support the row element without r attribute in the worksheet
This commit is contained in:
parent
15fd56853f
commit
48f19f60aa
17
cell_test.go
17
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"`)
|
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) {
|
func TestGetCellFormula(t *testing.T) {
|
||||||
// Test get cell formula on not exist worksheet.
|
// Test get cell formula on not exist worksheet.
|
||||||
f := NewFile()
|
f := NewFile()
|
||||||
|
|
18
col.go
18
col.go
|
@ -42,18 +42,14 @@ type Cols struct {
|
||||||
// GetCols return all the columns in a sheet by given worksheet name (case
|
// GetCols return all the columns in a sheet by given worksheet name (case
|
||||||
// sensitive). For example:
|
// sensitive). For example:
|
||||||
//
|
//
|
||||||
// cols, err := f.Cols("Sheet1")
|
// cols, err := f.GetCols("Sheet1")
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// fmt.Println(err)
|
// fmt.Println(err)
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
// for cols.Next() {
|
// for _, col := range cols {
|
||||||
// col, err := cols.Rows()
|
// for _, colCell := range col {
|
||||||
// if err != nil {
|
// fmt.Println(colCell, "\t")
|
||||||
// fmt.Println(err)
|
|
||||||
// }
|
|
||||||
// for _, rowCell := range col {
|
|
||||||
// fmt.Print(rowCell, "\t")
|
|
||||||
// }
|
// }
|
||||||
// fmt.Println()
|
// fmt.Println()
|
||||||
// }
|
// }
|
||||||
|
@ -71,13 +67,13 @@ func (f *File) GetCols(sheet string) ([][]string, error) {
|
||||||
return results, nil
|
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 {
|
func (cols *Cols) Next() bool {
|
||||||
cols.curCol++
|
cols.curCol++
|
||||||
return cols.curCol <= cols.totalCol
|
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 {
|
func (cols *Cols) Error() error {
|
||||||
return cols.err
|
return cols.err
|
||||||
}
|
}
|
||||||
|
@ -127,7 +123,7 @@ func (cols *Cols) Rows() ([]string, error) {
|
||||||
return rows, nil
|
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:
|
// worksheet with a large data. For example:
|
||||||
//
|
//
|
||||||
// cols, err := f.Cols("Sheet1")
|
// cols, err := f.Cols("Sheet1")
|
||||||
|
|
21
excelize.go
21
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
|
// checkSheet provides a function to fill each row element and make that is
|
||||||
// continuous in a worksheet of XML.
|
// continuous in a worksheet of XML.
|
||||||
func checkSheet(xlsx *xlsxWorksheet) {
|
func checkSheet(xlsx *xlsxWorksheet) {
|
||||||
row := len(xlsx.SheetData.Row)
|
var row int
|
||||||
if row >= 1 {
|
for _, r := range xlsx.SheetData.Row {
|
||||||
lastRow := xlsx.SheetData.Row[row-1].R
|
if r.R != 0 && r.R > row {
|
||||||
if lastRow >= row {
|
row = r.R
|
||||||
row = lastRow
|
continue
|
||||||
}
|
}
|
||||||
|
row++
|
||||||
}
|
}
|
||||||
sheetData := xlsxSheetData{Row: make([]xlsxRow, row)}
|
sheetData := xlsxSheetData{Row: make([]xlsxRow, row)}
|
||||||
|
row = 0
|
||||||
for _, r := range xlsx.SheetData.Row {
|
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++ {
|
for i := 1; i <= row; i++ {
|
||||||
sheetData.Row[i-1].R = i
|
sheetData.Row[i-1].R = i
|
||||||
|
|
40
rows.go
40
rows.go
|
@ -25,18 +25,14 @@ import (
|
||||||
// GetRows return all the rows in a sheet by given worksheet name (case
|
// GetRows return all the rows in a sheet by given worksheet name (case
|
||||||
// sensitive). For example:
|
// sensitive). For example:
|
||||||
//
|
//
|
||||||
// rows, err := f.Rows("Sheet1")
|
// rows, err := f.GetRows("Sheet1")
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// fmt.Println(err)
|
// fmt.Println(err)
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
// for rows.Next() {
|
// for _, row := range rows {
|
||||||
// row, err := rows.Columns()
|
|
||||||
// if err != nil {
|
|
||||||
// fmt.Println(err)
|
|
||||||
// }
|
|
||||||
// for _, colCell := range row {
|
// for _, colCell := range row {
|
||||||
// fmt.Print(colCell, "\t")
|
// fmt.Println(colCell, "\t")
|
||||||
// }
|
// }
|
||||||
// fmt.Println()
|
// fmt.Println()
|
||||||
// }
|
// }
|
||||||
|
@ -57,7 +53,7 @@ func (f *File) GetRows(sheet string) ([][]string, error) {
|
||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rows defines an iterator to a sheet
|
// Rows defines an iterator to a sheet.
|
||||||
type Rows struct {
|
type Rows struct {
|
||||||
err error
|
err error
|
||||||
curRow, totalRow, stashRow int
|
curRow, totalRow, stashRow int
|
||||||
|
@ -73,12 +69,12 @@ func (rows *Rows) Next() bool {
|
||||||
return rows.curRow <= rows.totalRow
|
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 {
|
func (rows *Rows) Error() error {
|
||||||
return rows.err
|
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) {
|
func (rows *Rows) Columns() ([]string, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
|
@ -117,9 +113,13 @@ func (rows *Rows) Columns() ([]string, error) {
|
||||||
if inElement == "c" {
|
if inElement == "c" {
|
||||||
colCell := xlsxC{}
|
colCell := xlsxC{}
|
||||||
_ = rows.decoder.DecodeElement(&colCell, &startElement)
|
_ = rows.decoder.DecodeElement(&colCell, &startElement)
|
||||||
cellCol, _, err = CellNameToCoordinates(colCell.R)
|
if colCell.R != "" {
|
||||||
if err != nil {
|
cellCol, _, err = CellNameToCoordinates(colCell.R)
|
||||||
return columns, err
|
if err != nil {
|
||||||
|
return columns, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cellCol++
|
||||||
}
|
}
|
||||||
blank := cellCol - len(columns)
|
blank := cellCol - len(columns)
|
||||||
for i := 1; i < blank; i++ {
|
for i := 1; i < blank; i++ {
|
||||||
|
@ -177,10 +177,10 @@ func (f *File) Rows(sheet string) (*Rows, error) {
|
||||||
f.saveFileList(name, replaceRelationshipsNameSpaceBytes(output))
|
f.saveFileList(name, replaceRelationshipsNameSpaceBytes(output))
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
inElement string
|
inElement string
|
||||||
row int
|
row, curRow int
|
||||||
rows Rows
|
rows Rows
|
||||||
)
|
)
|
||||||
decoder := f.xmlNewDecoder(bytes.NewReader(f.readXML(name)))
|
decoder := f.xmlNewDecoder(bytes.NewReader(f.readXML(name)))
|
||||||
for {
|
for {
|
||||||
|
@ -194,12 +194,16 @@ func (f *File) Rows(sheet string) (*Rows, error) {
|
||||||
if inElement == "row" {
|
if inElement == "row" {
|
||||||
for _, attr := range startElement.Attr {
|
for _, attr := range startElement.Attr {
|
||||||
if attr.Name.Local == "r" {
|
if attr.Name.Local == "r" {
|
||||||
row, err = strconv.Atoi(attr.Value)
|
curRow, err = strconv.Atoi(attr.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &rows, err
|
return &rows, err
|
||||||
}
|
}
|
||||||
|
row = curRow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(startElement.Attr) == 0 {
|
||||||
|
row++
|
||||||
|
}
|
||||||
rows.totalRow = row
|
rows.totalRow = row
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue