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(`A3A4B4A7B7A8B8`) + 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() diff --git a/col.go b/col.go index d6f0690..0baa2e4 100644 --- a/col.go +++ b/col.go @@ -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 diff --git a/rows.go b/rows.go index 18d9957..38c1ecc 100644 --- a/rows.go +++ b/rows.go @@ -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: