summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rows.go24
-rw-r--r--rows_test.go24
-rw-r--r--sheet.go28
-rw-r--r--sheet_test.go26
-rw-r--r--test/Book1.xlsxbin20738 -> 20451 bytes
-rw-r--r--xmlDrawing.go1
6 files changed, 103 insertions, 0 deletions
diff --git a/rows.go b/rows.go
index 853c8f7..457f59b 100644
--- a/rows.go
+++ b/rows.go
@@ -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 {
@@ -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:
@@ -111,6 +114,11 @@ func (rows *Rows) Next() bool {
}
}
+// GetRowOpts will return the RowOpts of the current row.
+func (rows *Rows) GetRowOpts() RowOpts {
+ return rows.curRowOpts
+}
+
// Error will return the error when the error occurs.
func (rows *Rows) Error() error {
return rows.err
@@ -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
@@ -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++ {
diff --git a/rows_test.go b/rows_test.go
index 4fe2851..4b57c34 100644
--- a/rows_test.go
+++ b/rows_test.go
@@ -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()
+ 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) {
diff --git a/sheet.go b/sheet.go
index 01dd167..1f2dcea 100644
--- a/sheet.go
+++ b/sheet.go
@@ -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
+// 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.
//
diff --git a/sheet_test.go b/sheet_test.go
index c68ad31..9b0caf4 100644
--- a/sheet_test.go
+++ b/sheet_test.go
@@ -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)
+}
diff --git a/test/Book1.xlsx b/test/Book1.xlsx
index 6a497e3..ed3e292 100644
--- a/test/Book1.xlsx
+++ b/test/Book1.xlsx
Binary files differ
diff --git a/xmlDrawing.go b/xmlDrawing.go
index 8c3d734..b4fdccc 100644
--- a/xmlDrawing.go
+++ b/xmlDrawing.go
@@ -107,6 +107,7 @@ const (
MaxFieldLength = 255
MaxColumnWidth = 255
MaxRowHeight = 409
+ MaxCellStyles = 64000
MinFontSize = 1
TotalRows = 1048576
MinColumns = 1