summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2020-06-27 00:02:47 +0800
committerxuri <xuri.me@gmail.com>2020-06-27 00:02:47 +0800
commit48f19f60aa3e162146a9dc4edf7b4c8cf687ec26 (patch)
tree77fdff8dba0fbb26f8c534872f06a98258c1c273
parent15fd56853fe1b63217fb963c951cf4fef7b56a08 (diff)
support the row element without r attribute in the worksheet
-rw-r--r--cell_test.go17
-rw-r--r--col.go18
-rw-r--r--excelize.go21
-rw-r--r--rows.go40
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()
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: