forked from p30928647/excelize
add iterator method for rows
This commit is contained in:
parent
934ecec1a9
commit
bc451a78de
96
rows.go
96
rows.go
|
@ -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) {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package excelize
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func trimSliceSpace(s []string) []string {
|
||||
for {
|
||||
if len(s) > 0 && s[len(s)-1] == "" {
|
||||
s = s[:len(s)-1]
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func TestRows(t *testing.T) {
|
||||
xlsx, err := OpenFile("./test/Book1.xlsx")
|
||||
assert.NoError(t, err)
|
||||
|
||||
rows, err := xlsx.Rows("Sheet2")
|
||||
assert.NoError(t, err)
|
||||
|
||||
rowStrs := make([][]string, 0)
|
||||
var i = 0
|
||||
for rows.Next() {
|
||||
i++
|
||||
columns := rows.Columns()
|
||||
//fmt.Println(i, columns)
|
||||
rowStrs = append(rowStrs, columns)
|
||||
}
|
||||
assert.NoError(t, rows.Error())
|
||||
|
||||
dstRows := xlsx.GetRows("Sheet2")
|
||||
assert.EqualValues(t, len(dstRows), len(rowStrs))
|
||||
for i := 0; i < len(rowStrs); i++ {
|
||||
assert.EqualValues(t, trimSliceSpace(dstRows[i]), trimSliceSpace(rowStrs[i]))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue