summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2021-08-23 00:15:43 +0800
committerxuri <xuri.me@gmail.com>2021-08-23 00:15:43 +0800
commitcd030d4aa81582e8bc04d029c0be6e42eff9ea47 (patch)
tree3c757dd209fe7fd2349f433275255a9b975a7329
parenta2d449708cf72928394b4bc4aea41c0c6a606fa2 (diff)
Improve compatibility with row element with r="0" attribute
-rw-r--r--cell_test.go17
-rw-r--r--excelize.go32
2 files changed, 47 insertions, 2 deletions
diff --git a/cell_test.go b/cell_test.go
index 91dc4fd..7a08560 100644
--- a/cell_test.go
+++ b/cell_test.go
@@ -225,6 +225,23 @@ func TestGetCellValue(t *testing.T) {
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)
+
+ f.Sheet.Delete("xl/worksheets/sheet1.xml")
+ f.Pkg.Store("xl/worksheets/sheet1.xml", []byte(fmt.Sprintf(sheetData, `<row r="0"><c r="H6" t="str"><v>H6</v></c><c r="A1" t="str"><v>r0A6</v></c><c r="F4" t="str"><v>F4</v></c></row><row><c r="A1" t="str"><v>A6</v></c><c r="B1" t="str"><v>B6</v></c><c r="C1" t="str"><v>C6</v></c></row><row r="3"><c r="A3"><v>100</v></c><c r="B3" t="str"><v>B3</v></c></row>`)))
+ f.checked = nil
+ cell, err = f.GetCellValue("Sheet1", "H6")
+ assert.Equal(t, "H6", cell)
+ assert.NoError(t, err)
+ rows, err = f.GetRows("Sheet1")
+ assert.Equal(t, [][]string{
+ {"A6", "B6", "C6"},
+ nil,
+ {"100", "B3"},
+ {"", "", "", "", "", "F4"},
+ nil,
+ {"", "", "", "", "", "", "", "H6"},
+ }, rows)
+ assert.NoError(t, err)
}
func TestGetCellFormula(t *testing.T) {
diff --git a/excelize.go b/excelize.go
index 6e4e4d9..11ddf92 100644
--- a/excelize.go
+++ b/excelize.go
@@ -226,7 +226,13 @@ func (f *File) workSheetReader(sheet string) (ws *xlsxWorksheet, err error) {
// continuous in a worksheet of XML.
func checkSheet(ws *xlsxWorksheet) {
var row int
- for _, r := range ws.SheetData.Row {
+ var r0 xlsxRow
+ for i, r := range ws.SheetData.Row {
+ if i == 0 && r.R == 0 {
+ r0 = r
+ ws.SheetData.Row = ws.SheetData.Row[1:]
+ continue
+ }
if r.R != 0 && r.R > row {
row = r.R
continue
@@ -254,7 +260,29 @@ func checkSheet(ws *xlsxWorksheet) {
for i := 1; i <= row; i++ {
sheetData.Row[i-1].R = i
}
- ws.SheetData = sheetData
+ checkSheetR0(ws, &sheetData, &r0)
+}
+
+// checkSheetR0 handle the row element with r="0" attribute, cells in this row
+// could be disorderly, the cell in this row can be used as the value of
+// which cell is empty in the normal rows.
+func checkSheetR0(ws *xlsxWorksheet, sheetData *xlsxSheetData, r0 *xlsxRow) {
+ for _, cell := range r0.C {
+ if col, row, err := CellNameToCoordinates(cell.R); err == nil {
+ rows, rowIdx := len(sheetData.Row), row-1
+ for r := rows; r < row; r++ {
+ sheetData.Row = append(sheetData.Row, xlsxRow{R: r + 1})
+ }
+ columns, colIdx := len(sheetData.Row[rowIdx].C), col-1
+ for c := columns; c < col; c++ {
+ sheetData.Row[rowIdx].C = append(sheetData.Row[rowIdx].C, xlsxC{})
+ }
+ if !sheetData.Row[rowIdx].C[colIdx].hasValue() {
+ sheetData.Row[rowIdx].C[colIdx] = cell
+ }
+ }
+ }
+ ws.SheetData = *sheetData
}
// addRels provides a function to add relationships by given XML path,