diff options
author | xuri <xuri.me@gmail.com> | 2018-05-07 15:48:58 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-07 15:48:58 +0800 |
commit | 3746ba6a50be963673e0972596f37310ccaa9662 (patch) | |
tree | e1c8723b1e6c61b76379018b7843acc3c9610e36 /rows.go | |
parent | 934ecec1a96bfd5a1ecf3f1f373332504971c5fd (diff) | |
parent | bc451a78de32ccde2a4f6d0851ea6e41e45408f1 (diff) |
Merge pull request #218 from lunny/master
Add iterator method for rows
Diffstat (limited to 'rows.go')
-rw-r--r-- | rows.go | 96 |
1 files changed, 96 insertions, 0 deletions
@@ -3,6 +3,8 @@ package excelize import ( "bytes" "encoding/xml" + "fmt" + "io" "math" "strconv" "strings" @@ -67,6 +69,100 @@ func (f *File) GetRows(sheet string) [][]string { return rows } +// Rows defines an iterator to a sheet +type Rows struct { + decoder *xml.Decoder + token xml.Token + err error + f *File +} + +// 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 + } + } + } +} + +// Error will return the error when the find next row element +func (rows *Rows) Error() error { + return rows.err +} + +// Columns return the current row's column values +func (rows *Rows) Columns() []string { + if rows.token == nil { + return []string{} + } + + startElement := rows.token.(xml.StartElement) + r := xlsxRow{} + rows.decoder.DecodeElement(&r, &startElement) + + d := rows.f.sharedStringsReader() + row := make([]string, len(r.C), len(r.C)) + for _, colCell := range r.C { + c := TitleToNumber(strings.Map(letterOnlyMapF, colCell.R)) + val, _ := colCell.getValueFrom(rows.f, d) + row[c] = val + } + return row +} + +// ErrSheetNotExist defines an error of sheet is not exist +type ErrSheetNotExist struct { + SheetName string +} + +func (err ErrSheetNotExist) Error() string { + return fmt.Sprintf("Sheet %s is not exist", string(err.SheetName)) +} + +// Rows return a rows iterator. For example: +// +// rows, err := xlsx.GetRows("Sheet1") +// +// for rows.Next() { +// for _, colCell := range rows.Columns() { +// fmt.Print(colCell, "\t") +// } +// fmt.Println() +// } +// +func (f *File) Rows(sheet string) (*Rows, error) { + xlsx := f.workSheetReader(sheet) + name, ok := f.sheetMap[trimSheetName(sheet)] + if !ok { + return nil, ErrSheetNotExist{sheet} + } + if xlsx != nil { + output, err := xml.Marshal(f.Sheet[name]) + if err != nil { + return nil, err + } + f.saveFileList(name, replaceWorkSheetsRelationshipsNameSpace(string(output))) + } + + return &Rows{ + f: f, + decoder: xml.NewDecoder(strings.NewReader(f.readXML(name))), + }, nil +} + // getTotalRowsCols provides a function to get total columns and rows in a // worksheet. func (f *File) getTotalRowsCols(name string) (int, int) { |