Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1296 add GetRowOpts to Rows #1297

Merged
merged 1 commit into from
Aug 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions rows.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,14 @@ type Rows struct {
sst *xlsxSST
decoder *xml.Decoder
token xml.Token
curRowOpts, seekRowOpts RowOpts
}

// Next will return true if find the next row element.
func (rows *Rows) Next() bool {
rows.seekRow++
if rows.curRow >= rows.seekRow {
rows.curRowOpts = rows.seekRowOpts
return true
}
for {
Expand All @@ -101,6 +103,7 @@ func (rows *Rows) Next() bool {
rows.curRow = rowNum
}
rows.token = token
rows.curRowOpts = extractRowOpts(xmlElement.Attr)
return true
}
case xml.EndElement:
Expand All @@ -111,6 +114,11 @@ func (rows *Rows) Next() bool {
}
}

// GetRowOpts will return the RowOpts of the current row.
func (rows *Rows) GetRowOpts() RowOpts {
thomascharbonnel marked this conversation as resolved.
Show resolved Hide resolved
return rows.curRowOpts
}

// Error will return the error when the error occurs.
func (rows *Rows) Error() error {
return rows.err
Expand Down Expand Up @@ -151,6 +159,8 @@ func (rows *Rows) Columns(opts ...Options) ([]string, error) {
} else if rows.token == nil {
rows.curRow++
}
rows.token = token
rows.seekRowOpts = extractRowOpts(xmlElement.Attr)
if rows.curRow > rows.seekRow {
rows.token = nil
return rowIterator.columns, rowIterator.err
Expand All @@ -170,6 +180,20 @@ func (rows *Rows) Columns(opts ...Options) ([]string, error) {
return rowIterator.columns, rowIterator.err
}

func extractRowOpts(attrs []xml.Attr) RowOpts {
rowOpts := RowOpts{Height: defaultRowHeight}
if styleID, err := attrValToInt("s", attrs); err == nil && styleID > 0 && styleID < MaxCellStyles {
rowOpts.StyleID = styleID
}
if hidden, err := attrValToBool("hidden", attrs); err == nil {
rowOpts.Hidden = hidden
}
if height, err := attrValToFloat("ht", attrs); err == nil {
rowOpts.Height = height
}
return rowOpts
}

// appendSpace append blank characters to slice by given length and source slice.
func appendSpace(l int, s []string) []string {
for i := 1; i < l; i++ {
Expand Down
24 changes: 24 additions & 0 deletions rows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,30 @@ func TestRowsIterator(t *testing.T) {
assert.Equal(t, expectedNumRow, rowCount)
}

func TestRowsGetRowOpts(t *testing.T) {
sheetName := "Sheet2"
expectedRowStyleID1 := RowOpts{Height: 17.0, Hidden: false, StyleID: 1}
expectedRowStyleID2 := RowOpts{Height: 17.0, Hidden: false, StyleID: 0}
expectedRowStyleID3 := RowOpts{Height: 17.0, Hidden: false, StyleID: 2}
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
require.NoError(t, err)

rows, err := f.Rows(sheetName)
require.NoError(t, err)

rows.Next()
thomascharbonnel marked this conversation as resolved.
Show resolved Hide resolved
rows.Columns() // Columns() may change the XML iterator, so better check with and without calling it
got := rows.GetRowOpts()
assert.Equal(t, expectedRowStyleID1, got)
rows.Next()
got = rows.GetRowOpts()
assert.Equal(t, expectedRowStyleID2, got)
rows.Next()
rows.Columns()
got = rows.GetRowOpts()
assert.Equal(t, expectedRowStyleID3, got)
}

func TestRowsError(t *testing.T) {
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
if !assert.NoError(t, err) {
Expand Down
28 changes: 28 additions & 0 deletions sheet.go
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,34 @@ func attrValToInt(name string, attrs []xml.Attr) (val int, err error) {
return
}

// attrValToFloat provides a function to convert the local names to a float64
thomascharbonnel marked this conversation as resolved.
Show resolved Hide resolved
// by given XML attributes and specified names.
func attrValToFloat(name string, attrs []xml.Attr) (val float64, err error) {
for _, attr := range attrs {
if attr.Name.Local == name {
val, err = strconv.ParseFloat(attr.Value, 64)
if err != nil {
return
}
}
}
return
}

// attrValToBool provides a function to convert the local names to a boolean
// by given XML attributes and specified names.
func attrValToBool(name string, attrs []xml.Attr) (val bool, err error) {
for _, attr := range attrs {
if attr.Name.Local == name {
val, err = strconv.ParseBool(attr.Value)
if err != nil {
return
}
}
}
return
}

// SetHeaderFooter provides a function to set headers and footers by given
// worksheet name and the control characters.
//
Expand Down
26 changes: 26 additions & 0 deletions sheet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -505,3 +505,29 @@ func newSheetWithSave() {
}
_ = file.Save()
}

func TestAttrValToBool(t *testing.T) {
_, err := attrValToBool("hidden", []xml.Attr{
{Name: xml.Name{Local: "hidden"}},
})
assert.EqualError(t, err, `strconv.ParseBool: parsing "": invalid syntax`)

got, err := attrValToBool("hidden", []xml.Attr{
{Name: xml.Name{Local: "hidden"}, Value: "1"},
})
assert.NoError(t, err)
assert.Equal(t, true, got)
}

func TestAttrValToFloat(t *testing.T) {
_, err := attrValToFloat("ht", []xml.Attr{
{Name: xml.Name{Local: "ht"}},
})
assert.EqualError(t, err, `strconv.ParseFloat: parsing "": invalid syntax`)

got, err := attrValToFloat("ht", []xml.Attr{
{Name: xml.Name{Local: "ht"}, Value: "42.1"},
})
assert.NoError(t, err)
assert.Equal(t, 42.1, got)
}
Binary file modified test/Book1.xlsx
Binary file not shown.
1 change: 1 addition & 0 deletions xmlDrawing.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ const (
MaxFieldLength = 255
MaxColumnWidth = 255
MaxRowHeight = 409
MaxCellStyles = 64000
MinFontSize = 1
TotalRows = 1048576
MinColumns = 1
Expand Down