summaryrefslogtreecommitdiff
path: root/rows.go
diff options
context:
space:
mode:
Diffstat (limited to 'rows.go')
-rw-r--r--rows.go142
1 files changed, 21 insertions, 121 deletions
diff --git a/rows.go b/rows.go
index 3079d5a..cb0e31f 100644
--- a/rows.go
+++ b/rows.go
@@ -10,10 +10,8 @@
package excelize
import (
- "bytes"
"encoding/xml"
"fmt"
- "io"
"math"
"strconv"
)
@@ -30,95 +28,35 @@ import (
// }
//
func (f *File) GetRows(sheet string) ([][]string, error) {
- name, ok := f.sheetMap[trimSheetName(sheet)]
- if !ok {
- return nil, nil
- }
-
- xlsx, err := f.workSheetReader(sheet)
+ rows, err := f.Rows(sheet)
if err != nil {
return nil, err
}
- if xlsx != nil {
- output, _ := xml.Marshal(f.Sheet[name])
- f.saveFileList(name, replaceWorkSheetsRelationshipsNameSpaceBytes(output))
- }
-
- xml.NewDecoder(bytes.NewReader(f.readXML(name)))
- d := f.sharedStringsReader()
- var (
- inElement string
- rowData xlsxRow
- )
-
- rowCount, colCount, err := f.getTotalRowsCols(name)
- if err != nil {
- return nil, nil
- }
- rows := make([][]string, rowCount)
- for i := range rows {
- rows[i] = make([]string, colCount)
- }
-
- var row int
- decoder := xml.NewDecoder(bytes.NewReader(f.readXML(name)))
- for {
- token, _ := decoder.Token()
- if token == nil {
+ results := make([][]string, 0, 64)
+ for rows.Next() {
+ if rows.Error() != nil {
break
}
- switch startElement := token.(type) {
- case xml.StartElement:
- inElement = startElement.Name.Local
- if inElement == "row" {
- rowData = xlsxRow{}
- _ = decoder.DecodeElement(&rowData, &startElement)
- cr := rowData.R - 1
- for _, colCell := range rowData.C {
- col, _, err := CellNameToCoordinates(colCell.R)
- if err != nil {
- return nil, err
- }
- val, _ := colCell.getValueFrom(f, d)
- rows[cr][col-1] = val
- if val != "" {
- row = rowData.R
- }
- }
- }
- default:
+ row, err := rows.Columns()
+ if err != nil {
+ break
}
+ results = append(results, row)
}
- return rows[:row], nil
+ return results, nil
}
// Rows defines an iterator to a sheet
type Rows struct {
- decoder *xml.Decoder
- token xml.Token
- err error
- f *File
+ err error
+ f *File
+ rows []xlsxRow
+ curRow int
}
// Next will return true if find the next row element.
func (rows *Rows) Next() bool {
- for {
- rows.token, rows.err = rows.decoder.Token()
- if rows.err == io.EOF {
- rows.err = nil
- }
- if rows.token == nil {
- return false
- }
-
- switch startElement := rows.token.(type) {
- case xml.StartElement:
- inElement := startElement.Name.Local
- if inElement == "row" {
- return true
- }
- }
- }
+ return rows.curRow < len(rows.rows)
}
// Error will return the error when the find next row element
@@ -128,15 +66,12 @@ func (rows *Rows) Error() error {
// Columns return the current row's column values
func (rows *Rows) Columns() ([]string, error) {
- if rows.token == nil {
- return []string{}, nil
- }
- startElement := rows.token.(xml.StartElement)
- r := xlsxRow{}
- _ = rows.decoder.DecodeElement(&r, &startElement)
+ curRow := rows.rows[rows.curRow]
+ rows.curRow++
+
+ columns := make([]string, len(curRow.C))
d := rows.f.sharedStringsReader()
- columns := make([]string, len(r.C))
- for _, colCell := range r.C {
+ for _, colCell := range curRow.C {
col, _, err := CellNameToCoordinates(colCell.R)
if err != nil {
return columns, err
@@ -181,46 +116,11 @@ func (f *File) Rows(sheet string) (*Rows, error) {
f.saveFileList(name, replaceWorkSheetsRelationshipsNameSpaceBytes(output))
}
return &Rows{
- f: f,
- decoder: xml.NewDecoder(bytes.NewReader(f.readXML(name))),
+ f: f,
+ rows: xlsx.SheetData.Row,
}, nil
}
-// getTotalRowsCols provides a function to get total columns and rows in a
-// worksheet.
-func (f *File) getTotalRowsCols(name string) (int, int, error) {
- decoder := xml.NewDecoder(bytes.NewReader(f.readXML(name)))
- var inElement string
- var r xlsxRow
- var tr, tc int
- for {
- token, _ := decoder.Token()
- if token == nil {
- break
- }
- switch startElement := token.(type) {
- case xml.StartElement:
- inElement = startElement.Name.Local
- if inElement == "row" {
- r = xlsxRow{}
- _ = decoder.DecodeElement(&r, &startElement)
- tr = r.R
- for _, colCell := range r.C {
- col, _, err := CellNameToCoordinates(colCell.R)
- if err != nil {
- return tr, tc, err
- }
- if col > tc {
- tc = col
- }
- }
- }
- default:
- }
- }
- return tr, tc, nil
-}
-
// SetRowHeight provides a function to set the height of a single row. For
// example, set the height of the first row in Sheet1:
//