Skip to content

Commit 5f5ec76

Browse files
committed
Fix qax-os#551, handle empty rows in streaming reading
1 parent 09485b3 commit 5f5ec76

8 files changed

+84
-81
lines changed

chart.go

+5-11
Original file line numberDiff line numberDiff line change
@@ -495,11 +495,7 @@ func parseFormatChartSet(formatSet string) (*formatChart, error) {
495495
//
496496
// package main
497497
//
498-
// import (
499-
// "fmt"
500-
//
501-
// "github.com/360EntSecGroup-Skylar/excelize"
502-
// )
498+
// import "github.com/360EntSecGroup-Skylar/excelize"
503499
//
504500
// func main() {
505501
// categories := map[string]string{"A2": "Small", "A3": "Normal", "A4": "Large", "B1": "Apple", "C1": "Orange", "D1": "Pear"}
@@ -511,15 +507,13 @@ func parseFormatChartSet(formatSet string) (*formatChart, error) {
511507
// for k, v := range values {
512508
// f.SetCellValue("Sheet1", k, v)
513509
// }
514-
// err := f.AddChart("Sheet1", "E1", `{"type":"col3DClustered","dimension":{"width":640,"height":480},"series":[{"name":"Sheet1!$A$2","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"},{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit 3D Clustered Column Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero","x_axis":{"reverse_order":true},"y_axis":{"maximum":7.5,"minimum":0.5}}`)
515-
// if err != nil {
516-
// fmt.Println(err)
510+
// if err := f.AddChart("Sheet1", "E1", `{"type":"col3DClustered","dimension":{"width":640,"height":480},"series":[{"name":"Sheet1!$A$2","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"},{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit 3D Clustered Column Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero","x_axis":{"reverse_order":true},"y_axis":{"maximum":7.5,"minimum":0.5}}`); err != nil {
511+
// println(err.Error())
517512
// return
518513
// }
519514
// // Save xlsx file by the given path.
520-
// err = xlsx.SaveAs("./Book1.xlsx")
521-
// if err != nil {
522-
// fmt.Println(err)
515+
// if err := xlsx.SaveAs("Book1.xlsx"); err != nil {
516+
// println(err.Error())
523517
// }
524518
// }
525519
//

excelize.go

+6-9
Original file line numberDiff line numberDiff line change
@@ -293,17 +293,14 @@ func (f *File) UpdateLinkedValue() error {
293293
// AddVBAProject provides the method to add vbaProject.bin file which contains
294294
// functions and/or macros. The file extension should be .xlsm. For example:
295295
//
296-
// err := f.SetSheetPrOptions("Sheet1", excelize.CodeName("Sheet1"))
297-
// if err != nil {
298-
// fmt.Println(err)
296+
// if err := f.SetSheetPrOptions("Sheet1", excelize.CodeName("Sheet1")); err != nil {
297+
// println(err.Error())
299298
// }
300-
// err = f.AddVBAProject("vbaProject.bin")
301-
// if err != nil {
302-
// fmt.Println(err)
299+
// if err := f.AddVBAProject("vbaProject.bin"); err != nil {
300+
// println(err.Error())
303301
// }
304-
// err = f.SaveAs("macros.xlsm")
305-
// if err != nil {
306-
// fmt.Println(err)
302+
// if err := f.SaveAs("macros.xlsm"); err != nil {
303+
// println(err.Error())
307304
// }
308305
//
309306
func (f *File) AddVBAProject(bin string) error {

picture.go

+19-28
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ func parseFormatPictureSet(formatSet string) (*formatPicture, error) {
4848
// package main
4949
//
5050
// import (
51-
// "fmt"
5251
// _ "image/gif"
5352
// _ "image/jpeg"
5453
// _ "image/png"
@@ -59,23 +58,19 @@ func parseFormatPictureSet(formatSet string) (*formatPicture, error) {
5958
// func main() {
6059
// f := excelize.NewFile()
6160
// // Insert a picture.
62-
// err := f.AddPicture("Sheet1", "A2", "./image1.jpg", "")
63-
// if err != nil {
64-
// fmt.Println(err)
61+
// if err := f.AddPicture("Sheet1", "A2", "image.jpg", ""); err != nil {
62+
// println(err.Error())
6563
// }
6664
// // Insert a picture scaling in the cell with location hyperlink.
67-
// err = f.AddPicture("Sheet1", "D2", "./image1.png", `{"x_scale": 0.5, "y_scale": 0.5, "hyperlink": "#Sheet2!D8", "hyperlink_type": "Location"}`)
68-
// if err != nil {
69-
// fmt.Println(err)
65+
// if err := f.AddPicture("Sheet1", "D2", "image.png", `{"x_scale": 0.5, "y_scale": 0.5, "hyperlink": "#Sheet2!D8", "hyperlink_type": "Location"}`); err != nil {
66+
// println(err.Error())
7067
// }
7168
// // Insert a picture offset in the cell with external hyperlink, printing and positioning support.
72-
// err = f.AddPicture("Sheet1", "H2", "./image3.gif", `{"x_offset": 15, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "print_obj": true, "lock_aspect_ratio": false, "locked": false, "positioning": "oneCell"}`)
73-
// if err != nil {
74-
// fmt.Println(err)
69+
// if err := f.AddPicture("Sheet1", "H2", "image.gif", `{"x_offset": 15, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "print_obj": true, "lock_aspect_ratio": false, "locked": false, "positioning": "oneCell"}`); err != nil {
70+
// println(err.Error())
7571
// }
76-
// err = f.SaveAs("./Book1.xlsx")
77-
// if err != nil {
78-
// fmt.Println(err)
72+
// if err := f.SaveAs("Book1.xlsx"); err != nil {
73+
// println(err.Error())
7974
// }
8075
// }
8176
//
@@ -109,7 +104,6 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error {
109104
// package main
110105
//
111106
// import (
112-
// "fmt"
113107
// _ "image/jpeg"
114108
// "io/ioutil"
115109
//
@@ -119,17 +113,15 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error {
119113
// func main() {
120114
// f := excelize.NewFile()
121115
//
122-
// file, err := ioutil.ReadFile("./image1.jpg")
116+
// file, err := ioutil.ReadFile("image.jpg")
123117
// if err != nil {
124-
// fmt.Println(err)
118+
// println(err.Error())
125119
// }
126-
// err = f.AddPictureFromBytes("Sheet1", "A2", "", "Excel Logo", ".jpg", file)
127-
// if err != nil {
128-
// fmt.Println(err)
120+
// if err := f.AddPictureFromBytes("Sheet1", "A2", "", "Excel Logo", ".jpg", file); err != nil {
121+
// println(err.Error())
129122
// }
130-
// err = f.SaveAs("./Book1.xlsx")
131-
// if err != nil {
132-
// fmt.Println(err)
123+
// if err := f.SaveAs("Book1.xlsx"); err != nil {
124+
// println(err.Error())
133125
// }
134126
// }
135127
//
@@ -430,19 +422,18 @@ func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string {
430422
// embed in XLSX by given worksheet and cell name. This function returns the
431423
// file name in XLSX and file contents as []byte data types. For example:
432424
//
433-
// f, err := excelize.OpenFile("./Book1.xlsx")
425+
// f, err := excelize.OpenFile("Book1.xlsx")
434426
// if err != nil {
435-
// fmt.Println(err)
427+
// println(err.Error())
436428
// return
437429
// }
438430
// file, raw, err := f.GetPicture("Sheet1", "A2")
439431
// if err != nil {
440-
// fmt.Println(err)
432+
// println(err.Error())
441433
// return
442434
// }
443-
// err = ioutil.WriteFile(file, raw, 0644)
444-
// if err != nil {
445-
// fmt.Println(err)
435+
// if err := ioutil.WriteFile(file, raw, 0644); err != nil {
436+
// println(err.Error())
446437
// }
447438
//
448439
func (f *File) GetPicture(sheet, cell string) (string, []byte, error) {

pivotTable.go

+5-7
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,17 @@ type PivotTableOption struct {
5656
// f.SetCellValue("Sheet1", fmt.Sprintf("D%d", i+2), rand.Intn(5000))
5757
// f.SetCellValue("Sheet1", fmt.Sprintf("E%d", i+2), region[rand.Intn(4)])
5858
// }
59-
// err := f.AddPivotTable(&excelize.PivotTableOption{
59+
// if err := f.AddPivotTable(&excelize.PivotTableOption{
6060
// DataRange: "Sheet1!$A$1:$E$31",
6161
// PivotTableRange: "Sheet1!$G$2:$M$34",
6262
// Rows: []string{"Month", "Year"},
6363
// Columns: []string{"Type"},
6464
// Data: []string{"Sales"},
65-
// })
66-
// if err != nil {
67-
// fmt.Println(err)
65+
// }); err != nil {
66+
// println(err.Error())
6867
// }
69-
// err = f.SaveAs("Book1.xlsx")
70-
// if err != nil {
71-
// fmt.Println(err)
68+
// if err := f.SaveAs("Book1.xlsx"); err != nil {
69+
// println(err.Error())
7270
// }
7371
// }
7472
//

rows.go

+26-12
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,20 @@ import (
2323
// GetRows return all the rows in a sheet by given worksheet name (case
2424
// sensitive). For example:
2525
//
26-
// rows, err := f.GetRows("Sheet1")
27-
// for _, row := range rows {
26+
// rows, err := f.Rows("Sheet1")
27+
// if err != nil {
28+
// println(err.Error())
29+
// return
30+
// }
31+
// for rows.Next() {
32+
// row, err := rows.Columns()
33+
// if err != nil {
34+
// println(err.Error())
35+
// }
2836
// for _, colCell := range row {
29-
// fmt.Print(colCell, "\t")
37+
// print(colCell, "\t")
3038
// }
31-
// fmt.Println()
39+
// println()
3240
// }
3341
//
3442
func (f *File) GetRows(sheet string) ([][]string, error) {
@@ -52,13 +60,13 @@ func (f *File) GetRows(sheet string) ([][]string, error) {
5260

5361
// Rows defines an iterator to a sheet
5462
type Rows struct {
55-
err error
56-
f *File
57-
rows []xlsxRow
58-
sheet string
59-
curRow int
60-
totalRow int
61-
decoder *xml.Decoder
63+
err error
64+
curRow, totalRow, stashRow int
65+
sheet string
66+
stashColumn []string
67+
rows []xlsxRow
68+
f *File
69+
decoder *xml.Decoder
6270
}
6371

6472
// Next will return true if find the next row element.
@@ -80,6 +88,11 @@ func (rows *Rows) Columns() ([]string, error) {
8088
row, cellCol int
8189
columns []string
8290
)
91+
92+
if rows.stashRow >= rows.curRow {
93+
return columns, err
94+
}
95+
8396
d := rows.f.sharedStringsReader()
8497
for {
8598
token, _ := rows.decoder.Token()
@@ -97,6 +110,8 @@ func (rows *Rows) Columns() ([]string, error) {
97110
return columns, err
98111
}
99112
if row > rows.curRow {
113+
rows.stashRow = row - 1
114+
rows.stashColumn = columns
100115
return columns, err
101116
}
102117
}
@@ -121,7 +136,6 @@ func (rows *Rows) Columns() ([]string, error) {
121136
if inElement == "row" {
122137
return columns, err
123138
}
124-
default:
125139
}
126140
}
127141
return columns, err

rows_test.go

+9
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,16 @@ func TestColumns(t *testing.T) {
136136
f := NewFile()
137137
rows, err := f.Rows("Sheet1")
138138
assert.NoError(t, err)
139+
140+
rows.decoder = f.xmlNewDecoder(bytes.NewReader([]byte(`<worksheet><sheetData><row r="2"><c r="A1" t="s"><v>1</v></c></row></sheetData></worksheet>`)))
141+
_, err = rows.Columns()
142+
assert.NoError(t, err)
143+
rows.decoder = f.xmlNewDecoder(bytes.NewReader([]byte(`<worksheet><sheetData><row r="2"><c r="A1" t="s"><v>1</v></c></row></sheetData></worksheet>`)))
144+
rows.curRow = 1
145+
_, err = rows.Columns()
146+
139147
rows.decoder = f.xmlNewDecoder(bytes.NewReader([]byte(`<worksheet><sheetData><row r="A"><c r="A1" t="s"><v>1</v></c></row><row r="A"><c r="2" t="str"><v>B</v></c></row></sheetData></worksheet>`)))
148+
rows.stashRow, rows.curRow = 0, 1
140149
_, err = rows.Columns()
141150
assert.EqualError(t, err, `strconv.Atoi: parsing "A": invalid syntax`)
142151

stream.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ type StreamWriter struct {
4141
// file := excelize.NewFile()
4242
// streamWriter, err := file.NewStreamWriter("Sheet1")
4343
// if err != nil {
44-
// panic(err)
44+
// println(err.Error())
4545
// }
4646
// styleID, err := file.NewStyle(`{"font":{"color":"#777777"}}`)
4747
// if err != nil {
48-
// panic(err)
48+
// println(err.Error())
4949
// }
5050
// if err := streamWriter.SetRow("A1", []interface{}{excelize.Cell{StyleID: styleID, Value: "Data"}}); err != nil {
51-
// panic(err)
51+
// println(err.Error())
5252
// }
5353
// for rowID := 2; rowID <= 102400; rowID++ {
5454
// row := make([]interface{}, 50)
@@ -57,14 +57,14 @@ type StreamWriter struct {
5757
// }
5858
// cell, _ := excelize.CoordinatesToCellName(1, rowID)
5959
// if err := streamWriter.SetRow(cell, row); err != nil {
60-
// panic(err)
60+
// println(err.Error())
6161
// }
6262
// }
6363
// if err := streamWriter.Flush(); err != nil {
64-
// panic(err)
64+
// println(err.Error())
6565
// }
6666
// if err := file.SaveAs("Book1.xlsx"); err != nil {
67-
// panic(err)
67+
// println(err.Error())
6868
// }
6969
//
7070
func (f *File) NewStreamWriter(sheet string) (*StreamWriter, error) {

styles.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -2321,7 +2321,7 @@ func (f *File) GetCellStyle(sheet, axis string) (int, error) {
23212321
//
23222322
// style, err := f.NewStyle(`{"border":[{"type":"left","color":"0000FF","style":3},{"type":"top","color":"00FF00","style":4},{"type":"bottom","color":"FFFF00","style":5},{"type":"right","color":"FF0000","style":6},{"type":"diagonalDown","color":"A020F0","style":7},{"type":"diagonalUp","color":"A020F0","style":8}]}`)
23232323
// if err != nil {
2324-
// fmt.Println(err)
2324+
// println(err.Error())
23252325
// }
23262326
// err = f.SetCellStyle("Sheet1", "H9", "H9", style)
23272327
//
@@ -2330,23 +2330,23 @@ func (f *File) GetCellStyle(sheet, axis string) (int, error) {
23302330
//
23312331
// style, err := f.NewStyle(`{"fill":{"type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":1}}`)
23322332
// if err != nil {
2333-
// fmt.Println(err)
2333+
// println(err.Error())
23342334
// }
23352335
// err = f.SetCellStyle("Sheet1", "H9", "H9", style)
23362336
//
23372337
// Set solid style pattern fill for cell H9 on Sheet1:
23382338
//
23392339
// style, err := f.NewStyle(`{"fill":{"type":"pattern","color":["#E0EBF5"],"pattern":1}}`)
23402340
// if err != nil {
2341-
// fmt.Println(err)
2341+
// println(err.Error())
23422342
// }
23432343
// err = f.SetCellStyle("Sheet1", "H9", "H9", style)
23442344
//
23452345
// Set alignment style for cell H9 on Sheet1:
23462346
//
23472347
// style, err := f.NewStyle(`{"alignment":{"horizontal":"center","ident":1,"justify_last_line":true,"reading_order":0,"relative_indent":1,"shrink_to_fit":true,"text_rotation":45,"vertical":"","wrap_text":true}}`)
23482348
// if err != nil {
2349-
// fmt.Println(err)
2349+
// println(err.Error())
23502350
// }
23512351
// err = f.SetCellStyle("Sheet1", "H9", "H9", style)
23522352
//
@@ -2357,23 +2357,23 @@ func (f *File) GetCellStyle(sheet, axis string) (int, error) {
23572357
// f.SetCellValue("Sheet1", "H9", 42920.5)
23582358
// style, err := f.NewStyle(`{"number_format": 22}`)
23592359
// if err != nil {
2360-
// fmt.Println(err)
2360+
// println(err.Error())
23612361
// }
23622362
// err = f.SetCellStyle("Sheet1", "H9", "H9", style)
23632363
//
23642364
// Set font style for cell H9 on Sheet1:
23652365
//
23662366
// style, err := f.NewStyle(`{"font":{"bold":true,"italic":true,"family":"Times New Roman","size":36,"color":"#777777"}}`)
23672367
// if err != nil {
2368-
// fmt.Println(err)
2368+
// println(err.Error())
23692369
// }
23702370
// err = f.SetCellStyle("Sheet1", "H9", "H9", style)
23712371
//
23722372
// Hide and lock for cell H9 on Sheet1:
23732373
//
23742374
// style, err := f.NewStyle(`{"protection":{"hidden":true, "locked":true}}`)
23752375
// if err != nil {
2376-
// fmt.Println(err)
2376+
// println(err.Error())
23772377
// }
23782378
// err = f.SetCellStyle("Sheet1", "H9", "H9", style)
23792379
//
@@ -2507,7 +2507,7 @@ func (f *File) SetCellStyle(sheet, hcell, vcell string, styleID int) error {
25072507
//
25082508
// format, err = f.NewConditionalStyle(`{"font":{"color":"#9A0511"},"fill":{"type":"pattern","color":["#FEC7CE"],"pattern":1}}`)
25092509
// if err != nil {
2510-
// fmt.Println(err)
2510+
// println(err.Error())
25112511
// }
25122512
// f.SetConditionalFormat("Sheet1", "A1:A10", fmt.Sprintf(`[{"type":"cell","criteria":">","format":%d,"value":"6"}]`, format))
25132513
//

0 commit comments

Comments
 (0)