- This fix panic and incorrect cell read on some case

- Make unit test on Go 1.7
- API documentation updated
This commit is contained in:
xuri 2021-08-22 13:36:56 +08:00
parent 9b55f4f9f0
commit a2d449708c
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
6 changed files with 27 additions and 12 deletions

View File

@ -5,7 +5,7 @@ jobs:
test: test:
strategy: strategy:
matrix: matrix:
go-version: [1.15.x, 1.16.x] go-version: [1.15.x, 1.16.x, 1.17.x]
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
targetplatform: [x86, x64] targetplatform: [x86, x64]

View File

@ -181,6 +181,7 @@ func TestGetCellValue(t *testing.T) {
// Test get cell value without r attribute of the row. // Test get cell value without r attribute of the row.
f := NewFile() f := NewFile()
sheetData := `<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetData>%s</sheetData></worksheet>` sheetData := `<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetData>%s</sheetData></worksheet>`
f.Sheet.Delete("xl/worksheets/sheet1.xml") f.Sheet.Delete("xl/worksheets/sheet1.xml")
f.Pkg.Store("xl/worksheets/sheet1.xml", []byte(fmt.Sprintf(sheetData, `<row r="3"><c t="str"><v>A3</v></c></row><row><c t="str"><v>A4</v></c><c t="str"><v>B4</v></c></row><row r="7"><c t="str"><v>A7</v></c><c t="str"><v>B7</v></c></row><row><c t="str"><v>A8</v></c><c t="str"><v>B8</v></c></row>`))) f.Pkg.Store("xl/worksheets/sheet1.xml", []byte(fmt.Sprintf(sheetData, `<row r="3"><c t="str"><v>A3</v></c></row><row><c t="str"><v>A4</v></c><c t="str"><v>B4</v></c></row><row r="7"><c t="str"><v>A7</v></c><c t="str"><v>B7</v></c></row><row><c t="str"><v>A8</v></c><c t="str"><v>B8</v></c></row>`)))
f.checked = nil f.checked = nil
@ -196,24 +197,34 @@ func TestGetCellValue(t *testing.T) {
cols, err := f.GetCols("Sheet1") cols, err := f.GetCols("Sheet1")
assert.Equal(t, [][]string{{"", "", "A3", "A4", "", "", "A7", "A8"}, {"", "", "", "B4", "", "", "B7", "B8"}}, cols) assert.Equal(t, [][]string{{"", "", "A3", "A4", "", "", "A7", "A8"}, {"", "", "", "B4", "", "", "B7", "B8"}}, cols)
assert.NoError(t, err) assert.NoError(t, err)
f.Sheet.Delete("xl/worksheets/sheet1.xml") f.Sheet.Delete("xl/worksheets/sheet1.xml")
f.Pkg.Store("xl/worksheets/sheet1.xml", []byte(fmt.Sprintf(sheetData, `<row r="2"><c r="A2" t="str"><v>A2</v></c></row><row r="2"><c r="B2" t="str"><v>B2</v></c></row>`))) f.Pkg.Store("xl/worksheets/sheet1.xml", []byte(fmt.Sprintf(sheetData, `<row r="2"><c r="A2" t="str"><v>A2</v></c></row><row r="2"><c r="B2" t="str"><v>B2</v></c></row>`)))
f.checked = nil f.checked = nil
cell, err := f.GetCellValue("Sheet1", "A2") cell, err := f.GetCellValue("Sheet1", "A2")
assert.Equal(t, "A2", cell) assert.Equal(t, "A2", cell)
assert.NoError(t, err) assert.NoError(t, err)
f.Sheet.Delete("xl/worksheets/sheet1.xml") f.Sheet.Delete("xl/worksheets/sheet1.xml")
f.Pkg.Store("xl/worksheets/sheet1.xml", []byte(fmt.Sprintf(sheetData, `<row r="2"><c r="A2" t="str"><v>A2</v></c></row><row r="2"><c r="B2" t="str"><v>B2</v></c></row>`))) f.Pkg.Store("xl/worksheets/sheet1.xml", []byte(fmt.Sprintf(sheetData, `<row r="2"><c r="A2" t="str"><v>A2</v></c></row><row r="2"><c r="B2" t="str"><v>B2</v></c></row>`)))
f.checked = nil f.checked = nil
rows, err = f.GetRows("Sheet1") rows, err = f.GetRows("Sheet1")
assert.Equal(t, [][]string{nil, {"A2", "B2"}}, rows) assert.Equal(t, [][]string{nil, {"A2", "B2"}}, rows)
assert.NoError(t, err) assert.NoError(t, err)
f.Sheet.Delete("xl/worksheets/sheet1.xml") f.Sheet.Delete("xl/worksheets/sheet1.xml")
f.Pkg.Store("xl/worksheets/sheet1.xml", []byte(fmt.Sprintf(sheetData, `<row r="1"><c r="A1" t="str"><v>A1</v></c></row><row r="1"><c r="B1" t="str"><v>B1</v></c></row>`))) f.Pkg.Store("xl/worksheets/sheet1.xml", []byte(fmt.Sprintf(sheetData, `<row r="1"><c r="A1" t="str"><v>A1</v></c></row><row r="1"><c r="B1" t="str"><v>B1</v></c></row>`)))
f.checked = nil f.checked = nil
rows, err = f.GetRows("Sheet1") rows, err = f.GetRows("Sheet1")
assert.Equal(t, [][]string{{"A1", "B1"}}, rows) assert.Equal(t, [][]string{{"A1", "B1"}}, rows)
assert.NoError(t, err) assert.NoError(t, err)
f.Sheet.Delete("xl/worksheets/sheet1.xml")
f.Pkg.Store("xl/worksheets/sheet1.xml", []byte(fmt.Sprintf(sheetData, `<row><c t="str"><v>A3</v></c></row><row><c t="str"><v>A4</v></c><c t="str"><v>B4</v></c></row><row r="7"><c t="str"><v>A7</v></c><c t="str"><v>B7</v></c></row><row><c t="str"><v>A8</v></c><c t="str"><v>B8</v></c></row>`)))
f.checked = nil
rows, err = f.GetRows("Sheet1")
assert.Equal(t, [][]string{{"A3"}, {"A4", "B4"}, nil, nil, nil, nil, {"A7", "B7"}, {"A8", "B8"}}, rows)
assert.NoError(t, err)
} }
func TestGetCellFormula(t *testing.T) { func TestGetCellFormula(t *testing.T) {

4
col.go
View File

@ -399,8 +399,8 @@ func (f *File) SetColOutlineLevel(sheet, col string, level uint8) error {
// SetColStyle provides a function to set style of columns by given worksheet // SetColStyle provides a function to set style of columns by given worksheet
// name, columns range and style ID. Note that this will overwrite the // name, columns range and style ID. Note that this will overwrite the
// existing styles for the cell, it won't append or merge style with existing // existing styles for the columns, it won't append or merge style with
// styles. // existing styles.
// //
// For example set style of column H on Sheet1: // For example set style of column H on Sheet1:
// //

View File

@ -238,7 +238,7 @@ func checkSheet(ws *xlsxWorksheet) {
sheetData := xlsxSheetData{Row: make([]xlsxRow, row)} sheetData := xlsxSheetData{Row: make([]xlsxRow, row)}
row = 0 row = 0
for _, r := range ws.SheetData.Row { for _, r := range ws.SheetData.Row {
if r.R == row { if r.R == row && row > 0 {
sheetData.Row[r.R-1].C = append(sheetData.Row[r.R-1].C, r.C...) sheetData.Row[r.R-1].C = append(sheetData.Row[r.R-1].C, r.C...)
continue continue
} }

16
rows.go
View File

@ -24,8 +24,12 @@ import (
) )
// GetRows return all the rows in a sheet by given worksheet name // GetRows return all the rows in a sheet by given worksheet name
// (case sensitive). GetRows fetched the rows with value or formula cells, // (case sensitive), returned as a two-dimensional array, where the value of
// the tail continuously empty cell will be skipped. For example: // the cell is converted to the string type. If the cell format can be
// applied to the value of the cell, the applied value will be used,
// otherwise the original value will be used. GetRows fetched the rows with
// value or formula cells, the tail continuously empty cell will be skipped.
// For example:
// //
// rows, err := f.GetRows("Sheet1") // rows, err := f.GetRows("Sheet1")
// if err != nil { // if err != nil {
@ -111,7 +115,7 @@ func (rows *Rows) Columns() ([]string, error) {
} }
case xml.EndElement: case xml.EndElement:
rowIterator.inElement = xmlElement.Name.Local rowIterator.inElement = xmlElement.Name.Local
if rowIterator.row == 0 { if rowIterator.row == 0 && rowIterator.rows.curRow > 1 {
rowIterator.row = rowIterator.rows.curRow rowIterator.row = rowIterator.rows.curRow
} }
if rowIterator.inElement == "row" && rowIterator.row+1 < rowIterator.rows.curRow { if rowIterator.inElement == "row" && rowIterator.row+1 < rowIterator.rows.curRow {
@ -720,9 +724,9 @@ func checkRow(ws *xlsxWorksheet) error {
return nil return nil
} }
// SetRowStyle provides a function to set style of rows by given worksheet // SetRowStyle provides a function to set the style of rows by given worksheet
// name, row range and style ID. Note that this will overwrite the existing // name, row range, and style ID. Note that this will overwrite the existing
// styles for the cell, it won't append or merge style with existing styles. // styles for the rows, it won't append or merge style with existing styles.
// //
// For example set style of row 1 on Sheet1: // For example set style of row 1 on Sheet1:
// //

View File

@ -2603,8 +2603,8 @@ func (f *File) GetCellStyle(sheet, axis string) (int, error) {
// SetCellStyle provides a function to add style attribute for cells by given // SetCellStyle provides a function to add style attribute for cells by given
// worksheet name, coordinate area and style ID. Note that diagonalDown and // worksheet name, coordinate area and style ID. Note that diagonalDown and
// diagonalUp type border should be use same color in the same coordinate // diagonalUp type border should be use same color in the same coordinate
// area, this will overwrite the existing styles for the cell, it won't // area. SetCellStyle will overwrite the existing styles for the cell, it
// append or merge style with existing styles. // won't append or merge style with existing styles.
// //
// For example create a borders of cell H9 on Sheet1: // For example create a borders of cell H9 on Sheet1:
// //