Support get current row/col and total rows/cols in the stream reader (#1054)

This commit is contained in:
li 2021-11-05 00:01:34 +08:00 committed by GitHub
parent e64775fdcc
commit 60b13affbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 45 deletions

20
col.go
View File

@ -33,13 +33,23 @@ const (
// Cols defines an iterator to a sheet
type Cols struct {
err error
curCol, totalCol, stashCol, totalRow int
curCol, totalCols, totalRows, stashCol int
rawCellValue bool
sheet string
f *File
sheetXML []byte
}
// CurrentCol returns the column number that represents the current column.
func (cols *Cols) CurrentCol() int {
return cols.curCol
}
// TotalCols returns the total columns count in the worksheet.
func (cols *Cols) TotalCols() int {
return cols.totalCols
}
// GetCols return all the columns in a sheet by given worksheet name (case
// sensitive). For example:
//
@ -71,7 +81,7 @@ func (f *File) GetCols(sheet string, opts ...Options) ([][]string, error) {
// Next will return true if the next column is found.
func (cols *Cols) Next() bool {
cols.curCol++
return cols.curCol <= cols.totalCol
return cols.curCol <= cols.totalCols
}
// Error will return an error when the error occurs.
@ -159,7 +169,7 @@ func columnXMLHandler(colIterator *columnXMLIterator, xmlElement *xml.StartEleme
colIterator.row = colIterator.curRow
}
}
colIterator.cols.totalRow = colIterator.row
colIterator.cols.totalRows = colIterator.row
colIterator.cellCol = 0
}
if inElement == "c" {
@ -171,8 +181,8 @@ func columnXMLHandler(colIterator *columnXMLIterator, xmlElement *xml.StartEleme
}
}
}
if colIterator.cellCol > colIterator.cols.totalCol {
colIterator.cols.totalCol = colIterator.cellCol
if colIterator.cellCol > colIterator.cols.totalCols {
colIterator.cols.totalCols = colIterator.cellCol
}
}
}

View File

@ -59,39 +59,37 @@ func TestCols(t *testing.T) {
}
func TestColumnsIterator(t *testing.T) {
const (
sheet2 = "Sheet2"
expectedNumCol = 9
)
sheetName, colCount, expectedNumCol := "Sheet2", 0, 9
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
require.NoError(t, err)
cols, err := f.Cols(sheet2)
cols, err := f.Cols(sheetName)
require.NoError(t, err)
var colCount int
for cols.Next() {
colCount++
assert.Equal(t, colCount, cols.CurrentCol())
assert.Equal(t, expectedNumCol, cols.TotalCols())
require.True(t, colCount <= expectedNumCol, "colCount is greater than expected")
}
assert.Equal(t, expectedNumCol, colCount)
assert.NoError(t, f.Close())
f = NewFile()
f, sheetName, colCount, expectedNumCol = NewFile(), "Sheet1", 0, 4
cells := []string{"C2", "C3", "C4", "D2", "D3", "D4"}
for _, cell := range cells {
assert.NoError(t, f.SetCellValue("Sheet1", cell, 1))
assert.NoError(t, f.SetCellValue(sheetName, cell, 1))
}
cols, err = f.Cols("Sheet1")
cols, err = f.Cols(sheetName)
require.NoError(t, err)
colCount = 0
for cols.Next() {
colCount++
assert.Equal(t, colCount, cols.CurrentCol())
assert.Equal(t, expectedNumCol, cols.TotalCols())
require.True(t, colCount <= 4, "colCount is greater than expected")
}
assert.Equal(t, 4, colCount)
assert.Equal(t, expectedNumCol, colCount)
}
func TestColsError(t *testing.T) {
@ -130,8 +128,8 @@ func TestGetColsError(t *testing.T) {
f = NewFile()
cols, err := f.Cols("Sheet1")
assert.NoError(t, err)
cols.totalRow = 2
cols.totalCol = 2
cols.totalRows = 2
cols.totalCols = 2
cols.curCol = 1
cols.sheetXML = []byte(`<worksheet><sheetData><row r="1"><c r="A" t="str"><v>A</v></c></row></sheetData></worksheet>`)
_, err = cols.Rows()

16
rows.go
View File

@ -68,7 +68,7 @@ func (f *File) GetRows(sheet string, opts ...Options) ([][]string, error) {
// Rows defines an iterator to a sheet.
type Rows struct {
err error
curRow, totalRow, stashRow int
curRow, totalRows, stashRow int
rawCellValue bool
sheet string
f *File
@ -76,10 +76,20 @@ type Rows struct {
decoder *xml.Decoder
}
// CurrentRow returns the row number that represents the current row.
func (rows *Rows) CurrentRow() int {
return rows.curRow
}
// TotalRows returns the total rows count in the worksheet.
func (rows *Rows) TotalRows() int {
return rows.totalRows
}
// Next will return true if find the next row element.
func (rows *Rows) Next() bool {
rows.curRow++
return rows.curRow <= rows.totalRow
return rows.curRow <= rows.totalRows
}
// Error will return the error when the error occurs.
@ -255,7 +265,7 @@ func (f *File) Rows(sheet string) (*Rows, error) {
}
}
}
rows.totalRow = row
rows.totalRows = row
}
case xml.EndElement:
if xmlElement.Name.Local == "sheetData" {

View File

@ -65,18 +65,17 @@ func TestRows(t *testing.T) {
}
func TestRowsIterator(t *testing.T) {
const (
sheet2 = "Sheet2"
expectedNumRow = 11
)
sheetName, rowCount, expectedNumRow := "Sheet2", 0, 11
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
require.NoError(t, err)
rows, err := f.Rows(sheet2)
rows, err := f.Rows(sheetName)
require.NoError(t, err)
var rowCount int
for rows.Next() {
rowCount++
assert.Equal(t, rowCount, rows.CurrentRow())
assert.Equal(t, expectedNumRow, rows.TotalRows())
require.True(t, rowCount <= expectedNumRow, "rowCount is greater than expected")
}
assert.Equal(t, expectedNumRow, rowCount)
@ -84,19 +83,18 @@ func TestRowsIterator(t *testing.T) {
assert.NoError(t, f.Close())
// Valued cell sparse distribution test
f = NewFile()
f, sheetName, rowCount, expectedNumRow = NewFile(), "Sheet1", 0, 3
cells := []string{"C1", "E1", "A3", "B3", "C3", "D3", "E3"}
for _, cell := range cells {
assert.NoError(t, f.SetCellValue("Sheet1", cell, 1))
assert.NoError(t, f.SetCellValue(sheetName, cell, 1))
}
rows, err = f.Rows("Sheet1")
rows, err = f.Rows(sheetName)
require.NoError(t, err)
rowCount = 0
for rows.Next() {
rowCount++
require.True(t, rowCount <= 3, "rowCount is greater than expected")
require.True(t, rowCount <= expectedNumRow, "rowCount is greater than expected")
}
assert.Equal(t, 3, rowCount)
assert.Equal(t, expectedNumRow, rowCount)
}
func TestRowsError(t *testing.T) {