diff options
author | xuri <xuri.me@gmail.com> | 2021-08-23 00:15:43 +0800 |
---|---|---|
committer | xuri <xuri.me@gmail.com> | 2021-08-23 00:15:43 +0800 |
commit | cd030d4aa81582e8bc04d029c0be6e42eff9ea47 (patch) | |
tree | 3c757dd209fe7fd2349f433275255a9b975a7329 | |
parent | a2d449708cf72928394b4bc4aea41c0c6a606fa2 (diff) |
Improve compatibility with row element with r="0" attribute
-rw-r--r-- | cell_test.go | 17 | ||||
-rw-r--r-- | excelize.go | 32 |
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, |