Skip to content

Commit be12cc2

Browse files
committed
This closes qax-os#652, new SetColWidth API, support set column width in stream writing mode, and export error message
1 parent 423bc26 commit be12cc2

24 files changed

+141
-55
lines changed

adjust.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
package excelize
1313

1414
import (
15-
"errors"
1615
"strings"
1716
)
1817

@@ -219,7 +218,7 @@ func areaRangeToCoordinates(firstCell, lastCell string) ([]int, error) {
219218
// correct C1:B3 to B1:C3.
220219
func sortCoordinates(coordinates []int) error {
221220
if len(coordinates) != 4 {
222-
return errors.New("coordinates length must be 4")
221+
return ErrCoordinates
223222
}
224223
if coordinates[2] < coordinates[0] {
225224
coordinates[2], coordinates[0] = coordinates[0], coordinates[2]
@@ -234,7 +233,7 @@ func sortCoordinates(coordinates []int) error {
234233
// to area reference.
235234
func (f *File) coordinatesToAreaRef(coordinates []int) (string, error) {
236235
if len(coordinates) != 4 {
237-
return "", errors.New("coordinates length must be 4")
236+
return "", ErrCoordinates
238237
}
239238
firstCell, err := CoordinatesToCellName(coordinates[0], coordinates[1])
240239
if err != nil {

adjust_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ func TestAdjustCalcChain(t *testing.T) {
113113
func TestCoordinatesToAreaRef(t *testing.T) {
114114
f := NewFile()
115115
_, err := f.coordinatesToAreaRef([]int{})
116-
assert.EqualError(t, err, "coordinates length must be 4")
116+
assert.EqualError(t, err, ErrCoordinates.Error())
117117
_, err = f.coordinatesToAreaRef([]int{1, -1, 1, 1})
118118
assert.EqualError(t, err, "invalid cell coordinates [1, -1]")
119119
_, err = f.coordinatesToAreaRef([]int{1, 1, 1, -1})
@@ -124,5 +124,5 @@ func TestCoordinatesToAreaRef(t *testing.T) {
124124
}
125125

126126
func TestSortCoordinates(t *testing.T) {
127-
assert.EqualError(t, sortCoordinates(make([]int, 3)), "coordinates length must be 4")
127+
assert.EqualError(t, sortCoordinates(make([]int, 3)), ErrCoordinates.Error())
128128
}

calc.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ func (f *File) evalInfixExp(sheet, cell string, tokens []efp.Token) (efp.Token,
647647
optStack.Pop()
648648
}
649649
if opdStack.Len() == 0 {
650-
return efp.Token{}, errors.New("formula not valid")
650+
return efp.Token{}, ErrInvalidFormula
651651
}
652652
return opdStack.Peek().(efp.Token), err
653653
}
@@ -849,7 +849,7 @@ func calcDiv(rOpd, lOpd string, opdStack *Stack) error {
849849
func calculate(opdStack *Stack, opt efp.Token) error {
850850
if opt.TValue == "-" && opt.TType == efp.TokenTypeOperatorPrefix {
851851
if opdStack.Len() < 1 {
852-
return errors.New("formula not valid")
852+
return ErrInvalidFormula
853853
}
854854
opd := opdStack.Pop().(efp.Token)
855855
opdVal, err := strconv.ParseFloat(opd.TValue, 64)
@@ -874,7 +874,7 @@ func calculate(opdStack *Stack, opt efp.Token) error {
874874
}
875875
if opt.TValue == "-" && opt.TType == efp.TokenTypeOperatorInfix {
876876
if opdStack.Len() < 2 {
877-
return errors.New("formula not valid")
877+
return ErrInvalidFormula
878878
}
879879
rOpd := opdStack.Pop().(efp.Token)
880880
lOpd := opdStack.Pop().(efp.Token)
@@ -885,7 +885,7 @@ func calculate(opdStack *Stack, opt efp.Token) error {
885885
fn, ok := tokenCalcFunc[opt.TValue]
886886
if ok {
887887
if opdStack.Len() < 2 {
888-
return errors.New("formula not valid")
888+
return ErrInvalidFormula
889889
}
890890
rOpd := opdStack.Pop().(efp.Token)
891891
lOpd := opdStack.Pop().(efp.Token)

calc_test.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -1710,12 +1710,12 @@ func TestCalcCellValue(t *testing.T) {
17101710
"=POISSON(0,0,\"\")": "strconv.ParseBool: parsing \"\": invalid syntax",
17111711
"=POISSON(0,-1,TRUE)": "#N/A",
17121712
// SUM
1713-
"=SUM((": "formula not valid",
1714-
"=SUM(-)": "formula not valid",
1715-
"=SUM(1+)": "formula not valid",
1716-
"=SUM(1-)": "formula not valid",
1717-
"=SUM(1*)": "formula not valid",
1718-
"=SUM(1/)": "formula not valid",
1713+
"=SUM((": ErrInvalidFormula.Error(),
1714+
"=SUM(-)": ErrInvalidFormula.Error(),
1715+
"=SUM(1+)": ErrInvalidFormula.Error(),
1716+
"=SUM(1-)": ErrInvalidFormula.Error(),
1717+
"=SUM(1*)": ErrInvalidFormula.Error(),
1718+
"=SUM(1/)": ErrInvalidFormula.Error(),
17191719
// SUMIF
17201720
"=SUMIF()": "SUMIF requires at least 2 argument",
17211721
// SUMSQ

cell.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ func (f *File) SetCellHyperLink(sheet, axis, link, linkType string, opts ...Hype
475475
}
476476

477477
if len(ws.Hyperlinks.Hyperlink) > TotalSheetHyperlinks {
478-
return errors.New("over maximum limit hyperlinks in a worksheet")
478+
return ErrTotalSheetHyperlinks
479479
}
480480

481481
switch linkType {

chart.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -919,7 +919,7 @@ func (f *File) AddChart(sheet, cell, format string, combo ...string) error {
919919
func (f *File) AddChartSheet(sheet, format string, combo ...string) error {
920920
// Check if the worksheet already exists
921921
if f.GetSheetIndex(sheet) != -1 {
922-
return errors.New("the same name worksheet already exists")
922+
return ErrExistsWorksheet
923923
}
924924
formatSet, comboCharts, err := f.getFormatChart(format, combo)
925925
if err != nil {

chart_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ func TestAddChartSheet(t *testing.T) {
232232
// Test cell value on chartsheet
233233
assert.EqualError(t, f.SetCellValue("Chart1", "A1", true), "sheet Chart1 is chart sheet")
234234
// Test add chartsheet on already existing name sheet
235-
assert.EqualError(t, f.AddChartSheet("Sheet1", `{"type":"col3DClustered","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"}],"title":{"name":"Fruit 3D Clustered Column Chart"}}`), "the same name worksheet already exists")
235+
assert.EqualError(t, f.AddChartSheet("Sheet1", `{"type":"col3DClustered","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"}],"title":{"name":"Fruit 3D Clustered Column Chart"}}`), ErrExistsWorksheet.Error())
236236
// Test with unsupported chart type
237237
assert.EqualError(t, f.AddChartSheet("Chart2", `{"type":"unknown","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"}],"title":{"name":"Fruit 3D Clustered Column Chart"}}`), "unsupported chart type unknown")
238238

col.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ package excelize
1414
import (
1515
"bytes"
1616
"encoding/xml"
17-
"errors"
1817
"math"
1918
"strconv"
2019
"strings"
@@ -360,7 +359,7 @@ func (f *File) parseColRange(columns string) (start, end int, err error) {
360359
//
361360
func (f *File) SetColOutlineLevel(sheet, col string, level uint8) error {
362361
if level > 7 || level < 1 {
363-
return errors.New("invalid outline level")
362+
return ErrOutlineLevel
364363
}
365364
colNum, err := ColumnNameToNumber(col)
366365
if err != nil {
@@ -452,7 +451,7 @@ func (f *File) SetColWidth(sheet, startcol, endcol string, width float64) error
452451
return err
453452
}
454453
if width > MaxColumnWidth {
455-
return errors.New("the width of the column must be smaller than or equal to 255 characters")
454+
return ErrColumnWidth
456455
}
457456
if min > max {
458457
min, max = max, min

col_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -246,12 +246,12 @@ func TestOutlineLevel(t *testing.T) {
246246
assert.EqualError(t, err, "sheet Shee2 is not exist")
247247

248248
assert.NoError(t, f.SetColWidth("Sheet2", "A", "D", 13))
249-
assert.EqualError(t, f.SetColWidth("Sheet2", "A", "D", MaxColumnWidth+1), "the width of the column must be smaller than or equal to 255 characters")
249+
assert.EqualError(t, f.SetColWidth("Sheet2", "A", "D", MaxColumnWidth+1), ErrColumnWidth.Error())
250250

251251
assert.NoError(t, f.SetColOutlineLevel("Sheet2", "B", 2))
252252
assert.NoError(t, f.SetRowOutlineLevel("Sheet1", 2, 7))
253-
assert.EqualError(t, f.SetColOutlineLevel("Sheet1", "D", 8), "invalid outline level")
254-
assert.EqualError(t, f.SetRowOutlineLevel("Sheet1", 2, 8), "invalid outline level")
253+
assert.EqualError(t, f.SetColOutlineLevel("Sheet1", "D", 8), ErrOutlineLevel.Error())
254+
assert.EqualError(t, f.SetRowOutlineLevel("Sheet1", 2, 8), ErrOutlineLevel.Error())
255255
// Test set row outline level on not exists worksheet.
256256
assert.EqualError(t, f.SetRowOutlineLevel("SheetN", 1, 4), "sheet SheetN is not exist")
257257
// Test get row outline level on not exists worksheet.

date.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
package excelize
1313

1414
import (
15-
"errors"
1615
"math"
1716
"time"
1817
)
@@ -35,7 +34,7 @@ func timeToExcelTime(t time.Time) (float64, error) {
3534
// Because for example 1900-01-01 00:00:00 +0300 MSK converts to 1900-01-01 00:00:00 +0230 LMT
3635
// probably due to daylight saving.
3736
if t.Location() != time.UTC {
38-
return 0.0, errors.New("only UTC time expected")
37+
return 0.0, ErrToExcelTime
3938
}
4039

4140
if t.Before(excelMinTime1900) {

date_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func TestTimeToExcelTime_Timezone(t *testing.T) {
5555
for i, test := range trueExpectedDateList {
5656
t.Run(fmt.Sprintf("TestData%d", i+1), func(t *testing.T) {
5757
_, err := timeToExcelTime(test.GoValue.In(location))
58-
assert.EqualError(t, err, "only UTC time expected")
58+
assert.EqualError(t, err, ErrToExcelTime.Error())
5959
})
6060
}
6161
}

errors.go

+45-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111

1212
package excelize
1313

14-
import "fmt"
14+
import (
15+
"errors"
16+
"fmt"
17+
)
1518

1619
func newInvalidColumnNameError(col string) error {
1720
return fmt.Errorf("invalid column name %q", col)
@@ -28,3 +31,44 @@ func newInvalidCellNameError(cell string) error {
2831
func newInvalidExcelDateError(dateValue float64) error {
2932
return fmt.Errorf("invalid date value %f, negative values are not supported supported", dateValue)
3033
}
34+
35+
var (
36+
// ErrStreamSetColWidth defined the error message on set column width in
37+
// stream writing mode.
38+
ErrStreamSetColWidth = errors.New("must call the SetColWidth function before the SetRow function")
39+
// ErrColumnNumber defined the error message on receive an invalid column
40+
// number.
41+
ErrColumnNumber = errors.New("column number exceeds maximum limit")
42+
// ErrColumnWidth defined the error message on receive an invalid column
43+
// width.
44+
ErrColumnWidth = errors.New("the width of the column must be smaller than or equal to 255 characters")
45+
// ErrOutlineLevel defined the error message on receive an invalid outline
46+
// level number.
47+
ErrOutlineLevel = errors.New("invalid outline level")
48+
// ErrCoordinates defined the error message on invalid coordinates tuples
49+
// length.
50+
ErrCoordinates = errors.New("coordinates length must be 4")
51+
// ErrExistsWorksheet defined the error message on given worksheet already
52+
// exists.
53+
ErrExistsWorksheet = errors.New("the same name worksheet already exists")
54+
// ErrTotalSheetHyperlinks defined the error message on hyperlinks count
55+
// overflow.
56+
ErrTotalSheetHyperlinks = errors.New("over maximum limit hyperlinks in a worksheet")
57+
// ErrInvalidFormula defined the error message on receive an invalid
58+
// formula.
59+
ErrInvalidFormula = errors.New("formula not valid")
60+
// ErrAddVBAProject defined the error message on add the VBA project in
61+
// the workbook.
62+
ErrAddVBAProject = errors.New("unsupported VBA project extension")
63+
// ErrToExcelTime defined the error message on receive a not UTC time.
64+
ErrToExcelTime = errors.New("only UTC time expected")
65+
// ErrMaxRowHeight defined the error message on receive an invalid row
66+
// height.
67+
ErrMaxRowHeight = errors.New("the height of the row must be smaller than or equal to 409 points")
68+
// ErrImgExt defined the error message on receive an unsupported image
69+
// extension.
70+
ErrImgExt = errors.New("unsupported image extension")
71+
// ErrMaxFileNameLength defined the error message on receive the file name
72+
// length overflow.
73+
ErrMaxFileNameLength = errors.New("file name length exceeds maximum limit")
74+
)

excelize.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
"archive/zip"
1717
"bytes"
1818
"encoding/xml"
19-
"errors"
2019
"fmt"
2120
"io"
2221
"io/ioutil"
@@ -351,7 +350,7 @@ func (f *File) AddVBAProject(bin string) error {
351350
return fmt.Errorf("stat %s: no such file or directory", bin)
352351
}
353352
if path.Ext(bin) != ".bin" {
354-
return errors.New("unsupported VBA project extension")
353+
return ErrAddVBAProject
355354
}
356355
f.setContentTypePartVBAProjectExtensions()
357356
wb := f.relsReader(f.getWorkbookRelsPath())

excelize_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ func TestOpenFile(t *testing.T) {
144144

145145
assert.NoError(t, f.SetCellValue("Sheet2", "G2", nil))
146146

147-
assert.EqualError(t, f.SetCellValue("Sheet2", "G4", time.Now()), "only UTC time expected")
147+
assert.EqualError(t, f.SetCellValue("Sheet2", "G4", time.Now()), ErrToExcelTime.Error())
148148

149149
assert.NoError(t, f.SetCellValue("Sheet2", "G4", time.Now().UTC()))
150150
// 02:46:40
@@ -166,7 +166,7 @@ func TestOpenFile(t *testing.T) {
166166
assert.NoError(t, f.SetCellStr("Sheet2", "c"+strconv.Itoa(i), strconv.Itoa(i)))
167167
}
168168
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestOpenFile.xlsx")))
169-
assert.EqualError(t, f.SaveAs(filepath.Join("test", strings.Repeat("c", 199), ".xlsx")), "file name length exceeds maximum limit")
169+
assert.EqualError(t, f.SaveAs(filepath.Join("test", strings.Repeat("c", 199), ".xlsx")), ErrMaxFileNameLength.Error())
170170
}
171171

172172
func TestSaveFile(t *testing.T) {
@@ -344,7 +344,7 @@ func TestSetCellHyperLink(t *testing.T) {
344344
_, err = f.workSheetReader("Sheet1")
345345
assert.NoError(t, err)
346346
f.Sheet["xl/worksheets/sheet1.xml"].Hyperlinks = &xlsxHyperlinks{Hyperlink: make([]xlsxHyperlink, 65530)}
347-
assert.EqualError(t, f.SetCellHyperLink("Sheet1", "A65531", "https://github.com/360EntSecGroup-Skylar/excelize", "External"), "over maximum limit hyperlinks in a worksheet")
347+
assert.EqualError(t, f.SetCellHyperLink("Sheet1", "A65531", "https://github.com/360EntSecGroup-Skylar/excelize", "External"), ErrTotalSheetHyperlinks.Error())
348348

349349
f = NewFile()
350350
_, err = f.workSheetReader("Sheet1")
@@ -449,7 +449,7 @@ func TestSetSheetBackgroundErrors(t *testing.T) {
449449
}
450450

451451
err = f.SetSheetBackground("Sheet2", filepath.Join("test", "Book1.xlsx"))
452-
assert.EqualError(t, err, "unsupported image extension")
452+
assert.EqualError(t, err, ErrImgExt.Error())
453453
}
454454

455455
// TestWriteArrayFormula tests the extended options of SetCellFormula by writing an array function
@@ -1187,7 +1187,7 @@ func TestAddVBAProject(t *testing.T) {
11871187
f := NewFile()
11881188
assert.NoError(t, f.SetSheetPrOptions("Sheet1", CodeName("Sheet1")))
11891189
assert.EqualError(t, f.AddVBAProject("macros.bin"), "stat macros.bin: no such file or directory")
1190-
assert.EqualError(t, f.AddVBAProject(filepath.Join("test", "Book1.xlsx")), "unsupported VBA project extension")
1190+
assert.EqualError(t, f.AddVBAProject(filepath.Join("test", "Book1.xlsx")), ErrAddVBAProject.Error())
11911191
assert.NoError(t, f.AddVBAProject(filepath.Join("test", "vbaProject.bin")))
11921192
// Test add VBA project twice.
11931193
assert.NoError(t, f.AddVBAProject(filepath.Join("test", "vbaProject.bin")))

file.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ package excelize
1414
import (
1515
"archive/zip"
1616
"bytes"
17-
"errors"
1817
"fmt"
1918
"io"
2019
"os"
@@ -66,7 +65,7 @@ func (f *File) Save() error {
6665
// provided path.
6766
func (f *File) SaveAs(name string, opt ...Options) error {
6867
if len(name) > MaxFileNameLength {
69-
return errors.New("file name length exceeds maximum limit")
68+
return ErrMaxFileNameLength
7069
}
7170
file, err := os.OpenFile(name, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666)
7271
if err != nil {

lib.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ func ColumnNameToNumber(name string) (int, error) {
149149
multi *= 26
150150
}
151151
if col > TotalColumns {
152-
return -1, fmt.Errorf("column number exceeds maximum limit")
152+
return -1, ErrColumnNumber
153153
}
154154
return col, nil
155155
}
@@ -166,7 +166,7 @@ func ColumnNumberToName(num int) (string, error) {
166166
return "", fmt.Errorf("incorrect column number %d", num)
167167
}
168168
if num > TotalColumns {
169-
return "", fmt.Errorf("column number exceeds maximum limit")
169+
return "", ErrColumnNumber
170170
}
171171
var col string
172172
for num > 0 {

lib_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func TestColumnNameToNumber_Error(t *testing.T) {
7373
}
7474
}
7575
_, err := ColumnNameToNumber("XFE")
76-
assert.EqualError(t, err, "column number exceeds maximum limit")
76+
assert.EqualError(t, err, ErrColumnNumber.Error())
7777
}
7878

7979
func TestColumnNumberToName_OK(t *testing.T) {
@@ -98,7 +98,7 @@ func TestColumnNumberToName_Error(t *testing.T) {
9898
}
9999

100100
_, err = ColumnNumberToName(TotalColumns + 1)
101-
assert.EqualError(t, err, "column number exceeds maximum limit")
101+
assert.EqualError(t, err, ErrColumnNumber.Error())
102102
}
103103

104104
func TestSplitCellName_OK(t *testing.T) {

picture.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"bytes"
1616
"encoding/json"
1717
"encoding/xml"
18-
"errors"
1918
"fmt"
2019
"image"
2120
"io"
@@ -93,7 +92,7 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error {
9392
}
9493
ext, ok := supportImageTypes[path.Ext(picture)]
9594
if !ok {
96-
return errors.New("unsupported image extension")
95+
return ErrImgExt
9796
}
9897
file, _ := ioutil.ReadFile(picture)
9998
_, name := filepath.Split(picture)
@@ -134,7 +133,7 @@ func (f *File) AddPictureFromBytes(sheet, cell, format, name, extension string,
134133
var hyperlinkType string
135134
ext, ok := supportImageTypes[extension]
136135
if !ok {
137-
return errors.New("unsupported image extension")
136+
return ErrImgExt
138137
}
139138
formatSet, err := parseFormatPictureSet(format)
140139
if err != nil {

0 commit comments

Comments
 (0)