From 0bc58acfcb7fc339fafca4a798fe3765db3337f5 Mon Sep 17 00:00:00 2001 From: Ivan Date: Tue, 2 Apr 2019 23:38:51 +0300 Subject: [PATCH] [fixed] empty value is^W was returned if cell is string formula --- col.go | 18 +++++++++++++++--- workbook.go | 8 ++++---- worksheet.go | 25 +++++++++++++++++++++---- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/col.go b/col.go index fa9e02f..a094de4 100644 --- a/col.go +++ b/col.go @@ -54,10 +54,10 @@ func (xf *XfRk) String(wb *WorkBook) string { fNo := wb.Xfs[idx].formatNo() if fNo >= 164 { // user defined format if formatter := wb.Formats[fNo]; formatter != nil { - if (strings.Contains(formatter.str, "#") || strings.Contains(formatter.str, ".00")){ + if strings.Contains(formatter.str, "#") || strings.Contains(formatter.str, ".00") { //If format contains # or .00 then this is a number - return xf.Rk.String() - }else{ + return xf.Rk.String() + } else { i, f, isFloat := xf.Rk.number() if !isFloat { f = float64(i) @@ -165,6 +165,18 @@ func (c *NumberCol) String(wb *WorkBook) []string { return []string{strconv.FormatFloat(c.Float, 'f', -1, 64)} } +type FormulaStringCol struct { + Col + RenderedValue string +} + +func (c *FormulaStringCol) String(wb *WorkBook) []string { + return []string{c.RenderedValue} +} + +//str, err = wb.get_string(buf_item, size) +//wb.sst[offset_pre] = wb.sst[offset_pre] + str + type FormulaCol struct { Header struct { Col diff --git a/workbook.go b/workbook.go index 2ffd0e8..ebaac26 100644 --- a/workbook.go +++ b/workbook.go @@ -3,10 +3,10 @@ package xls import ( "bytes" "encoding/binary" + "golang.org/x/text/encoding/charmap" "io" "os" "unicode/utf16" - "golang.org/x/text/encoding/charmap" ) //xls workbook type @@ -162,9 +162,9 @@ func (wb *WorkBook) parseBof(buf io.ReadSeeker, b *bof, pre *bof, offset_pre int return } func decodeWindows1251(enc []byte) string { - dec := charmap.Windows1251.NewDecoder() - out, _ := dec.Bytes(enc) - return string(out) + dec := charmap.Windows1251.NewDecoder() + out, _ := dec.Bytes(enc) + return string(out) } func (w *WorkBook) get_string(buf io.ReadSeeker, size uint16) (res string, err error) { if w.Is5ver { diff --git a/worksheet.go b/worksheet.go index 0299819..0f4ec8b 100644 --- a/worksheet.go +++ b/worksheet.go @@ -1,6 +1,7 @@ package xls import ( + "bytes" "encoding/binary" "fmt" "io" @@ -48,9 +49,10 @@ func (w *WorkSheet) parse(buf io.ReadSeeker) { w.rows = make(map[uint16]*Row) b := new(bof) var bof_pre *bof + var col_pre interface{} for { if err := binary.Read(buf, binary.LittleEndian, b); err == nil { - bof_pre = w.parseBof(buf, b, bof_pre) + bof_pre, col_pre = w.parseBof(buf, b, bof_pre, col_pre) if b.Id == 0xa { break } @@ -62,8 +64,11 @@ func (w *WorkSheet) parse(buf io.ReadSeeker) { w.parsed = true } -func (w *WorkSheet) parseBof(buf io.ReadSeeker, b *bof, pre *bof) *bof { +func (w *WorkSheet) parseBof(buf io.ReadSeeker, b *bof, pre *bof, col_pre interface{}) (*bof, interface{}) { var col interface{} + var bts = make([]byte, b.Size) + binary.Read(buf, binary.LittleEndian, bts) + buf = bytes.NewReader(bts) switch b.Id { // case 0x0E5: //MERGEDCELLS // ws.mergedCells(buf) @@ -72,7 +77,7 @@ func (w *WorkSheet) parseBof(buf io.ReadSeeker, b *bof, pre *bof) *bof { binary.Read(buf, binary.LittleEndian, &sheetOptions) binary.Read(buf, binary.LittleEndian, &firstVisibleRow) // not valuable binary.Read(buf, binary.LittleEndian, &firstVisibleColumn) // not valuable - buf.Seek(int64(b.Size)-2*3, 1) + //buf.Seek(int64(b.Size)-2*3, 1) w.rightToLeft = (sheetOptions & 0x40) != 0 w.Selected = (sheetOptions & 0x400) != 0 case 0x208: //ROW @@ -108,6 +113,18 @@ func (w *WorkSheet) parseBof(buf io.ReadSeeker, b *bof, pre *bof) *bof { c.Bts = make([]byte, b.Size-20) binary.Read(buf, binary.LittleEndian, &c.Bts) col = c + case 0x207: //STRING = FORMULA-VALUE is expected right after FORMULA + if ch, ok := col_pre.(*FormulaCol); ok { + c := new(FormulaStringCol) + c.Col = ch.Header.Col + var cStringLen uint16 + binary.Read(buf, binary.LittleEndian, &cStringLen) + str, err := w.wb.get_string(buf, cStringLen) + if nil == err { + c.RenderedValue = str + } + col = c + } case 0x27e: //RK col = new(RkCol) binary.Read(buf, binary.LittleEndian, col) @@ -182,7 +199,7 @@ func (w *WorkSheet) parseBof(buf io.ReadSeeker, b *bof, pre *bof) *bof { if col != nil { w.add(col) } - return b + return b, col } func (w *WorkSheet) add(content interface{}) {