diff options
author | xuri <xuri.me@gmail.com> | 2020-06-27 00:02:47 +0800 |
---|---|---|
committer | xuri <xuri.me@gmail.com> | 2020-06-27 00:02:47 +0800 |
commit | 48f19f60aa3e162146a9dc4edf7b4c8cf687ec26 (patch) | |
tree | 77fdff8dba0fbb26f8c534872f06a98258c1c273 | |
parent | 15fd56853fe1b63217fb963c951cf4fef7b56a08 (diff) |
support the row element without r attribute in the worksheet
-rw-r--r-- | cell_test.go | 17 | ||||
-rw-r--r-- | col.go | 18 | ||||
-rw-r--r-- | excelize.go | 21 | ||||
-rw-r--r-- | rows.go | 40 |
4 files changed, 61 insertions, 35 deletions
diff --git a/cell_test.go b/cell_test.go index 45e2f24..b2b1d54 100644 --- a/cell_test.go +++ b/cell_test.go @@ -95,6 +95,23 @@ func TestSetCellBool(t *testing.T) { assert.EqualError(t, f.SetCellBool("Sheet1", "A", true), `cannot convert cell "A" to coordinates: invalid cell name "A"`) } +func TestGetCellValue(t *testing.T) { + // Test get cell value without r attribute of the row. + f := NewFile() + delete(f.Sheet, "xl/worksheets/sheet1.xml") + f.XLSX["xl/worksheets/sheet1.xml"] = []byte(`<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><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></sheetData></worksheet>`) + f.checked = nil + cells := []string{"A3", "A4", "B4", "A7", "B7"} + rows, err := f.GetRows("Sheet1") + assert.Equal(t, [][]string{nil, nil, {"A3"}, {"A4", "B4"}, nil, nil, {"A7", "B7"}, {"A8", "B8"}}, rows) + assert.NoError(t, err) + for _, cell := range cells { + value, err := f.GetCellValue("Sheet1", cell) + assert.Equal(t, cell, value) + assert.NoError(t, err) + } +} + func TestGetCellFormula(t *testing.T) { // Test get cell formula on not exist worksheet. f := NewFile() @@ -42,18 +42,14 @@ type Cols struct { // GetCols return all the columns in a sheet by given worksheet name (case // sensitive). For example: // -// cols, err := f.Cols("Sheet1") +// cols, err := f.GetCols("Sheet1") // if err != nil { // fmt.Println(err) // return // } -// for cols.Next() { -// col, err := cols.Rows() -// if err != nil { -// fmt.Println(err) -// } -// for _, rowCell := range col { -// fmt.Print(rowCell, "\t") +// for _, col := range cols { +// for _, colCell := range col { +// fmt.Println(colCell, "\t") // } // fmt.Println() // } @@ -71,13 +67,13 @@ func (f *File) GetCols(sheet string) ([][]string, error) { return results, nil } -// Next will return true if the next col element is found. +// Next will return true if the next column is found. func (cols *Cols) Next() bool { cols.curCol++ return cols.curCol <= cols.totalCol } -// Error will return an error when the next col element is found. +// Error will return an error when the error occurs. func (cols *Cols) Error() error { return cols.err } @@ -127,7 +123,7 @@ func (cols *Cols) Rows() ([]string, error) { return rows, nil } -// Cols returns a columns iterator, used for streaming/reading data for a +// Cols returns a columns iterator, used for streaming reading data for a // worksheet with a large data. For example: // // cols, err := f.Cols("Sheet1") diff --git a/excelize.go b/excelize.go index 3e0255a..970759c 100644 --- a/excelize.go +++ b/excelize.go @@ -191,16 +191,25 @@ func (f *File) workSheetReader(sheet string) (xlsx *xlsxWorksheet, err error) { // checkSheet provides a function to fill each row element and make that is // continuous in a worksheet of XML. func checkSheet(xlsx *xlsxWorksheet) { - row := len(xlsx.SheetData.Row) - if row >= 1 { - lastRow := xlsx.SheetData.Row[row-1].R - if lastRow >= row { - row = lastRow + var row int + for _, r := range xlsx.SheetData.Row { + if r.R != 0 && r.R > row { + row = r.R + continue } + row++ } sheetData := xlsxSheetData{Row: make([]xlsxRow, row)} + row = 0 for _, r := range xlsx.SheetData.Row { - sheetData.Row[r.R-1] = r + if r.R != 0 { + sheetData.Row[r.R-1] = r + row = r.R + continue + } + row++ + r.R = row + sheetData.Row[row-1] = r } for i := 1; i <= row; i++ { sheetData.Row[i-1].R = i @@ -25,18 +25,14 @@ import ( // GetRows return all the rows in a sheet by given worksheet name (case // sensitive). For example: // -// rows, err := f.Rows("Sheet1") +// rows, err := f.GetRows("Sheet1") // if err != nil { // fmt.Println(err) // return // } -// for rows.Next() { -// row, err := rows.Columns() -// if err != nil { -// fmt.Println(err) -// } +// for _, row := range rows { // for _, colCell := range row { -// fmt.Print(colCell, "\t") +// fmt.Println(colCell, "\t") // } // fmt.Println() // } @@ -57,7 +53,7 @@ func (f *File) GetRows(sheet string) ([][]string, error) { return results, nil } -// Rows defines an iterator to a sheet +// Rows defines an iterator to a sheet. type Rows struct { err error curRow, totalRow, stashRow int @@ -73,12 +69,12 @@ func (rows *Rows) Next() bool { return rows.curRow <= rows.totalRow } -// Error will return the error when the find next row element +// Error will return the error when the error occurs. func (rows *Rows) Error() error { return rows.err } -// Columns return the current row's column values +// Columns return the current row's column values. func (rows *Rows) Columns() ([]string, error) { var ( err error @@ -117,9 +113,13 @@ func (rows *Rows) Columns() ([]string, error) { if inElement == "c" { colCell := xlsxC{} _ = rows.decoder.DecodeElement(&colCell, &startElement) - cellCol, _, err = CellNameToCoordinates(colCell.R) - if err != nil { - return columns, err + if colCell.R != "" { + cellCol, _, err = CellNameToCoordinates(colCell.R) + if err != nil { + return columns, err + } + } else { + cellCol++ } blank := cellCol - len(columns) for i := 1; i < blank; i++ { @@ -177,10 +177,10 @@ func (f *File) Rows(sheet string) (*Rows, error) { f.saveFileList(name, replaceRelationshipsNameSpaceBytes(output)) } var ( - err error - inElement string - row int - rows Rows + err error + inElement string + row, curRow int + rows Rows ) decoder := f.xmlNewDecoder(bytes.NewReader(f.readXML(name))) for { @@ -194,12 +194,16 @@ func (f *File) Rows(sheet string) (*Rows, error) { if inElement == "row" { for _, attr := range startElement.Attr { if attr.Name.Local == "r" { - row, err = strconv.Atoi(attr.Value) + curRow, err = strconv.Atoi(attr.Value) if err != nil { return &rows, err } + row = curRow } } + if len(startElement.Attr) == 0 { + row++ + } rows.totalRow = row } default: |