diff options
Diffstat (limited to 'col.go')
-rw-r--r-- | col.go | 78 |
1 files changed, 43 insertions, 35 deletions
@@ -38,6 +38,7 @@ type Cols struct { sheet string f *File sheetXML []byte + sst *xlsxSST } // GetCols gets the value of all cells by columns on the worksheet based on the @@ -87,17 +88,14 @@ func (cols *Cols) Error() error { // Rows return the current column's row values. func (cols *Cols) Rows(opts ...Options) ([]string, error) { - var ( - err error - inElement string - cellCol, cellRow int - rows []string - ) + var rowIterator rowXMLIterator if cols.stashCol >= cols.curCol { - return rows, err + return rowIterator.cells, rowIterator.err } cols.rawCellValue = parseOptions(opts...).RawCellValue - d := cols.f.sharedStringsReader() + if cols.sst, rowIterator.err = cols.f.sharedStringsReader(); rowIterator.err != nil { + return rowIterator.cells, rowIterator.err + } decoder := cols.f.xmlNewDecoder(bytes.NewReader(cols.sheetXML)) for { token, _ := decoder.Token() @@ -106,42 +104,25 @@ func (cols *Cols) Rows(opts ...Options) ([]string, error) { } switch xmlElement := token.(type) { case xml.StartElement: - inElement = xmlElement.Name.Local - if inElement == "row" { - cellCol = 0 - cellRow++ + rowIterator.inElement = xmlElement.Name.Local + if rowIterator.inElement == "row" { + rowIterator.cellCol = 0 + rowIterator.cellRow++ attrR, _ := attrValToInt("r", xmlElement.Attr) if attrR != 0 { - cellRow = attrR + rowIterator.cellRow = attrR } } - if inElement == "c" { - cellCol++ - for _, attr := range xmlElement.Attr { - if attr.Name.Local == "r" { - if cellCol, cellRow, err = CellNameToCoordinates(attr.Value); err != nil { - return rows, err - } - } - } - blank := cellRow - len(rows) - for i := 1; i < blank; i++ { - rows = append(rows, "") - } - if cellCol == cols.curCol { - colCell := xlsxC{} - _ = decoder.DecodeElement(&colCell, &xmlElement) - val, _ := colCell.getValueFrom(cols.f, d, cols.rawCellValue) - rows = append(rows, val) - } + if cols.rowXMLHandler(&rowIterator, &xmlElement, decoder); rowIterator.err != nil { + return rowIterator.cells, rowIterator.err } case xml.EndElement: if xmlElement.Name.Local == "sheetData" { - return rows, err + return rowIterator.cells, rowIterator.err } } } - return rows, err + return rowIterator.cells, rowIterator.err } // columnXMLIterator defined runtime use field for the worksheet column SAX parser. @@ -183,6 +164,30 @@ func columnXMLHandler(colIterator *columnXMLIterator, xmlElement *xml.StartEleme } } +// rowXMLHandler parse the row XML element of the worksheet. +func (cols *Cols) rowXMLHandler(rowIterator *rowXMLIterator, xmlElement *xml.StartElement, decoder *xml.Decoder) { + if rowIterator.inElement == "c" { + rowIterator.cellCol++ + for _, attr := range xmlElement.Attr { + if attr.Name.Local == "r" { + if rowIterator.cellCol, rowIterator.cellRow, rowIterator.err = CellNameToCoordinates(attr.Value); rowIterator.err != nil { + return + } + } + } + blank := rowIterator.cellRow - len(rowIterator.cells) + for i := 1; i < blank; i++ { + rowIterator.cells = append(rowIterator.cells, "") + } + if rowIterator.cellCol == cols.curCol { + colCell := xlsxC{} + _ = decoder.DecodeElement(&colCell, xmlElement) + val, _ := colCell.getValueFrom(cols.f, cols.sst, cols.rawCellValue) + rowIterator.cells = append(rowIterator.cells, val) + } + } +} + // Cols returns a columns iterator, used for streaming reading data for a // worksheet with a large data. This function is concurrency safe. For // example: @@ -420,7 +425,10 @@ func (f *File) SetColStyle(sheet, columns string, styleID int) error { if err != nil { return err } - s := f.stylesReader() + s, err := f.stylesReader() + if err != nil { + return err + } s.Lock() if styleID < 0 || s.CellXfs == nil || len(s.CellXfs.Xf) <= styleID { s.Unlock() |