Преглед на файлове

support the row element without r attribute in the worksheet

xuri преди 5 години
родител
ревизия
48f19f60aa
променени са 4 файла, в които са добавени 61 реда и са изтрити 35 реда
  1. 17 0
      cell_test.go
  2. 7 11
      col.go
  3. 15 6
      excelize.go
  4. 22 18
      rows.go

+ 17 - 0
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()

+ 7 - 11
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")

+ 15 - 6
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

+ 22 - 18
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: