From 75197d528857a98fcffcbd8263c79518e1ff733d Mon Sep 17 00:00:00 2001 From: akustikov Date: Thu, 10 Sep 2020 17:58:33 +0300 Subject: [PATCH 01/11] extend cell value load to support custom datetime format --- .gitignore | 1 + cell.go | 16 +++++++- excelize_test.go | 2 +- rows_test.go | 49 ++++++++++++++++++++++ styles.go | 93 +++++++++++++++++++++++++++++++----------- test/DateFormats.xlsx | Bin 0 -> 5604 bytes 6 files changed, 134 insertions(+), 27 deletions(-) create mode 100644 test/DateFormats.xlsx diff --git a/.gitignore b/.gitignore index a3fcff22aa..685d2bfdc5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ ~$*.xlsx test/Test*.xlsx +test/Test*.xlsm *.out *.test .idea diff --git a/cell.go b/cell.go index 5fe2157c43..58bcebf2cc 100644 --- a/cell.go +++ b/cell.go @@ -762,9 +762,21 @@ func (f *File) formattedValue(s int, v string) string { return v } styleSheet := f.stylesReader() - ok := builtInNumFmtFunc[*styleSheet.CellXfs.Xf[s].NumFmtID] + numFmtId := *styleSheet.CellXfs.Xf[s].NumFmtID + ok := builtInNumFmtFunc[numFmtId] if ok != nil { - return ok(*styleSheet.CellXfs.Xf[s].NumFmtID, v) + return ok(v, builtInNumFmt[numFmtId]) + } else { + for _, xlsxFmt := range styleSheet.NumFmts.NumFmt { + if xlsxFmt.NumFmtID == numFmtId { + format := strings.ToLower(xlsxFmt.FormatCode) + if strings.Contains(format, "y") || strings.Contains(format, "m") || strings.Contains(format, "d") || strings.Contains(format, "h") { + return parseTime(v, format) + } + + return v + } + } } return v } diff --git a/excelize_test.go b/excelize_test.go index f1cd65207e..a45b6b47ec 100644 --- a/excelize_test.go +++ b/excelize_test.go @@ -257,7 +257,7 @@ func TestBrokenFile(t *testing.T) { t.Run("SaveAsEmptyStruct", func(t *testing.T) { // Test write file with broken file struct with given path. - assert.NoError(t, f.SaveAs(filepath.Join("test", "BrokenFile.SaveAsEmptyStruct.xlsx"))) + assert.NoError(t, f.SaveAs(filepath.Join("test", "TestBrokenFile.SaveAsEmptyStruct.xlsx"))) }) t.Run("OpenBadWorkbook", func(t *testing.T) { diff --git a/rows_test.go b/rows_test.go index c469c01d47..f9accf1633 100644 --- a/rows_test.go +++ b/rows_test.go @@ -842,6 +842,39 @@ func TestCheckRow(t *testing.T) { assert.EqualError(t, f.SetCellValue("Sheet1", "A1", false), `cannot convert cell "-" to coordinates: invalid cell name "-"`) } +func TestDateFormats(t *testing.T) { + xlsx, err := OpenFile(filepath.Join("test", "DateFormats.xlsx")) + if !assert.NoError(t, err) { + t.FailNow() + } + + dt1, err := xlsx.GetCellValue("test", "C2") + assert.NoError(t, err) + assert.Equal(t, "08/05/2019", dt1) + + dt2, err := xlsx.GetCellValue("test", "D2") + assert.NoError(t, err) + assert.Equal(t, "2019-03-04", dt2) + + cells := make([][]string, 0) + + rows, err := xlsx.Rows("test") + assert.NoError(t, err) + for rows.Next() { + row, err := rows.Columns() + assert.NoError(t, err) + if err != nil { + break + } + + cells = append(cells, row) + } + + assert.Equal(t, []string{"1", "abc", "08/05/2019", "2019-03-04", "04/03/2019", "1", "4"}, cells[1]) + assert.Equal(t, []string{"2", "ddd hhh", "08/06/2019", "2019-03-05", "05/03/2019", "2", "5"}, cells[2]) + +} + func BenchmarkRows(b *testing.B) { f, _ := OpenFile(filepath.Join("test", "Book1.xlsx")) for i := 0; i < b.N; i++ { @@ -857,6 +890,22 @@ func BenchmarkRows(b *testing.B) { } } +func BenchmarkDateFormats(b *testing.B) { + f, _ := OpenFile(filepath.Join("test", "DateFormats.xlsx")) + for i := 0; i < b.N; i++ { + rows, err := f.Rows("test") + assert.NoError(b, err) + for rows.Next() { + row, _ := rows.Columns() + for i := range row { + if i >= 0 { + continue + } + } + } + } +} + func trimSliceSpace(s []string) []string { for { if len(s) > 0 && s[len(s)-1] == "" { diff --git a/styles.go b/styles.go index 14bcecc488..87eaeaad9b 100644 --- a/styles.go +++ b/styles.go @@ -21,6 +21,7 @@ import ( "log" "math" "reflect" + "regexp" "strconv" "strings" ) @@ -755,7 +756,7 @@ var currencyNumFmt = map[int]string{ // builtInNumFmtFunc defined the format conversion functions map. Partial format // code doesn't support currently and will return original string. -var builtInNumFmtFunc = map[int]func(i int, v string) string{ +var builtInNumFmtFunc = map[int]func(v string, format string) string{ 0: formatToString, 1: formatToInt, 2: formatToFloat, @@ -847,14 +848,14 @@ var criteriaType = map[string]string{ // formatToString provides a function to return original string by given // built-in number formats code and cell string. -func formatToString(i int, v string) string { +func formatToString(v string, format string) string { return v } // formatToInt provides a function to convert original string to integer // format as string type by given built-in number formats code and cell // string. -func formatToInt(i int, v string) string { +func formatToInt(v string, format string) string { f, err := strconv.ParseFloat(v, 64) if err != nil { return v @@ -865,7 +866,7 @@ func formatToInt(i int, v string) string { // formatToFloat provides a function to convert original string to float // format as string type by given built-in number formats code and cell // string. -func formatToFloat(i int, v string) string { +func formatToFloat(v string, format string) string { f, err := strconv.ParseFloat(v, 64) if err != nil { return v @@ -875,7 +876,7 @@ func formatToFloat(i int, v string) string { // formatToA provides a function to convert original string to special format // as string type by given built-in number formats code and cell string. -func formatToA(i int, v string) string { +func formatToA(v string, format string) string { f, err := strconv.ParseFloat(v, 64) if err != nil { return v @@ -890,7 +891,7 @@ func formatToA(i int, v string) string { // formatToB provides a function to convert original string to special format // as string type by given built-in number formats code and cell string. -func formatToB(i int, v string) string { +func formatToB(v string, format string) string { f, err := strconv.ParseFloat(v, 64) if err != nil { return v @@ -903,7 +904,7 @@ func formatToB(i int, v string) string { // formatToC provides a function to convert original string to special format // as string type by given built-in number formats code and cell string. -func formatToC(i int, v string) string { +func formatToC(v string, format string) string { f, err := strconv.ParseFloat(v, 64) if err != nil { return v @@ -914,7 +915,7 @@ func formatToC(i int, v string) string { // formatToD provides a function to convert original string to special format // as string type by given built-in number formats code and cell string. -func formatToD(i int, v string) string { +func formatToD(v string, format string) string { f, err := strconv.ParseFloat(v, 64) if err != nil { return v @@ -925,7 +926,7 @@ func formatToD(i int, v string) string { // formatToE provides a function to convert original string to special format // as string type by given built-in number formats code and cell string. -func formatToE(i int, v string) string { +func formatToE(v string, format string) string { f, err := strconv.ParseFloat(v, 64) if err != nil { return v @@ -933,6 +934,8 @@ func formatToE(i int, v string) string { return fmt.Sprintf("%.e", f) } +var dateTimeFormatsCache = map[string]string{} + // parseTime provides a function to returns a string parsed using time.Time. // Replace Excel placeholders with Go time placeholders. For example, replace // yyyy with 2006. These are in a specific order, due to the fact that m is @@ -944,15 +947,42 @@ func formatToE(i int, v string) string { // arbitrary characters unused in Excel Date formats, and then at the end, // turn them to what they should actually be. Based off: // http://www.ozgrid.com/Excel/CustomFormats.htm -func parseTime(i int, v string) string { - f, err := strconv.ParseFloat(v, 64) +func parseTime(v string, format string) string { + var ( + f float64 + err error + goFmt string + ) + f, err = strconv.ParseFloat(v, 64) if err != nil { return v } val := timeFromExcelTime(f, false) - format := builtInNumFmt[i] + + if format == "" { + return v + } + + goFmt, found := dateTimeFormatsCache[format] + + if found { + return val.Format(goFmt) + } + + goFmt = format + + if strings.Contains(goFmt, "[") { + var re = regexp.MustCompile(`\[.+\]`) + goFmt = re.ReplaceAllLiteralString(goFmt, "") + } replacements := []struct{ xltime, gotime string }{ + {"YYYY", "2006"}, + {"YY", "06"}, + {"MM", "01"}, + {"M", "1"}, + {"DD", "02"}, + {"D", "2"}, {"yyyy", "2006"}, {"yy", "06"}, {"mmmm", "%%%%"}, @@ -970,30 +1000,45 @@ func parseTime(i int, v string) string { {"%%%%", "January"}, {"&&&&", "Monday"}, } + + replacementsGlobal := []struct{ xltime, gotime string }{ + {"\\-", "-"}, + } // It is the presence of the "am/pm" indicator that determines if this is // a 12 hour or 24 hours time format, not the number of 'h' characters. if is12HourTime(format) { - format = strings.Replace(format, "hh", "03", 1) - format = strings.Replace(format, "h", "3", 1) + goFmt = strings.Replace(goFmt, "hh", "03", 1) + goFmt = strings.Replace(goFmt, "h", "3", 1) + goFmt = strings.Replace(goFmt, "HH", "03", 1) + goFmt = strings.Replace(goFmt, "H", "3", 1) } else { - format = strings.Replace(format, "hh", "15", 1) - format = strings.Replace(format, "h", "15", 1) + goFmt = strings.Replace(goFmt, "hh", "15", 1) + goFmt = strings.Replace(goFmt, "h", "15", 1) + goFmt = strings.Replace(goFmt, "HH", "15", 1) + goFmt = strings.Replace(goFmt, "H", "15", 1) + } for _, repl := range replacements { - format = strings.Replace(format, repl.xltime, repl.gotime, 1) + goFmt = strings.Replace(goFmt, repl.xltime, repl.gotime, 1) + } + for _, repl := range replacementsGlobal { + goFmt = strings.Replace(goFmt, repl.xltime, repl.gotime, -1) } // If the hour is optional, strip it out, along with the possible dangling // colon that would remain. if val.Hour() < 1 { - format = strings.Replace(format, "]:", "]", 1) - format = strings.Replace(format, "[03]", "", 1) - format = strings.Replace(format, "[3]", "", 1) - format = strings.Replace(format, "[15]", "", 1) + goFmt = strings.Replace(goFmt, "]:", "]", 1) + goFmt = strings.Replace(goFmt, "[03]", "", 1) + goFmt = strings.Replace(goFmt, "[3]", "", 1) + goFmt = strings.Replace(goFmt, "[15]", "", 1) } else { - format = strings.Replace(format, "[3]", "3", 1) - format = strings.Replace(format, "[15]", "15", 1) + goFmt = strings.Replace(goFmt, "[3]", "3", 1) + goFmt = strings.Replace(goFmt, "[15]", "15", 1) } - return val.Format(format) + + dateTimeFormatsCache[format] = goFmt + + return val.Format(goFmt) } // is12HourTime checks whether an Excel time format string is a 12 hours form. diff --git a/test/DateFormats.xlsx b/test/DateFormats.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..aac9678c62b3e70a5207747958397d045746e0bc GIT binary patch literal 5604 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 literal 0 HcmV?d00001 From 41b6a6c44fef9afd52ffe491af250933a90b864a Mon Sep 17 00:00:00 2001 From: akustikov Date: Thu, 10 Sep 2020 20:03:30 +0300 Subject: [PATCH 02/11] cleanup incorrect imports --- go.mod | 2 +- go.sum | 23 ++++- sheet_test.go | 86 ++++++++-------- sheetpr_test.go | 250 +++++++++++++++++++++++----------------------- sheetview_test.go | 92 +++++++++-------- 5 files changed, 231 insertions(+), 222 deletions(-) diff --git a/go.mod b/go.mod index fb2c1e8b99..91db593ea9 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/360EntSecGroup-Skylar/excelize/v2 +module github.com/artiz/excelize go 1.15 diff --git a/go.sum b/go.sum index e082e86359..00482b73c7 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,14 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/richardlehane/mscfb v1.0.3 h1:rD8TBkYWkObWO0oLDFCbwMeZ4KoalxQy+QgniCj3nKI= @@ -9,27 +16,35 @@ github.com/richardlehane/mscfb v1.0.3/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7 github.com/richardlehane/msoleps v1.0.1 h1:RfrALnSNXzmXLbGct/P2b4xkFz4e8Gmj/0Vj9M9xC1o= github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/xuri/efp v0.0.0-20191019043341-b7dc4fe9aa91/go.mod h1:uBiSUepVYMhGTfDeBKKasV4GpgBlzJ46gXUBAqV8qLk= github.com/xuri/efp v0.0.0-20200605144744-ba689101faaf h1:spotWVWg9DP470pPFQ7LaYtUqDpWEOS/BUrSmwFZE4k= github.com/xuri/efp v0.0.0-20200605144744-ba689101faaf/go.mod h1:uBiSUepVYMhGTfDeBKKasV4GpgBlzJ46gXUBAqV8qLk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/image v0.0.0-20200922025426-e59bae62ef32 h1:E+SEVulmY8U4+i6vSB88YSc2OKAFfvbHPU/uDTdQu7M= -golang.org/x/image v0.0.0-20200922025426-e59bae62ef32/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200801110659-972c09e46d76 h1:U7GPaoQyQmX+CBRWXKrvRzWTbd+slqeSh8uARsIyhAw= +golang.org/x/image v0.0.0-20200801110659-972c09e46d76/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA= -golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/sheet_test.go b/sheet_test.go index 0014220a26..890a4e5322 100644 --- a/sheet_test.go +++ b/sheet_test.go @@ -1,4 +1,4 @@ -package excelize_test +package excelize import ( "fmt" @@ -6,26 +6,24 @@ import ( "strings" "testing" - "github.com/360EntSecGroup-Skylar/excelize/v2" - "github.com/mohae/deepcopy" "github.com/stretchr/testify/assert" ) func ExampleFile_SetPageLayout() { - f := excelize.NewFile() + f := NewFile() if err := f.SetPageLayout( "Sheet1", - excelize.PageLayoutOrientation(excelize.OrientationLandscape), + PageLayoutOrientation(OrientationLandscape), ); err != nil { fmt.Println(err) } if err := f.SetPageLayout( "Sheet1", - excelize.PageLayoutPaperSize(10), - excelize.FitToHeight(2), - excelize.FitToWidth(2), + PageLayoutPaperSize(10), + FitToHeight(2), + FitToWidth(2), ); err != nil { fmt.Println(err) } @@ -33,12 +31,12 @@ func ExampleFile_SetPageLayout() { } func ExampleFile_GetPageLayout() { - f := excelize.NewFile() + f := NewFile() var ( - orientation excelize.PageLayoutOrientation - paperSize excelize.PageLayoutPaperSize - fitToHeight excelize.FitToHeight - fitToWidth excelize.FitToWidth + orientation PageLayoutOrientation + paperSize PageLayoutPaperSize + fitToHeight FitToHeight + fitToWidth FitToWidth ) if err := f.GetPageLayout("Sheet1", &orientation); err != nil { fmt.Println(err) @@ -67,7 +65,7 @@ func ExampleFile_GetPageLayout() { } func TestNewSheet(t *testing.T) { - f := excelize.NewFile() + f := NewFile() sheetID := f.NewSheet("Sheet2") f.SetActiveSheet(sheetID) // delete original sheet @@ -76,7 +74,7 @@ func TestNewSheet(t *testing.T) { } func TestSetPane(t *testing.T) { - f := excelize.NewFile() + f := NewFile() assert.NoError(t, f.SetPanes("Sheet1", `{"freeze":false,"split":false}`)) f.NewSheet("Panes 2") assert.NoError(t, f.SetPanes("Panes 2", `{"freeze":true,"split":false,"x_split":1,"y_split":0,"top_left_cell":"B1","active_pane":"topRight","panes":[{"sqref":"K16","active_cell":"K16","pane":"topRight"}]}`)) @@ -93,13 +91,13 @@ func TestPageLayoutOption(t *testing.T) { const sheet = "Sheet1" testData := []struct { - container excelize.PageLayoutOptionPtr - nonDefault excelize.PageLayoutOption + container PageLayoutOptionPtr + nonDefault PageLayoutOption }{ - {new(excelize.PageLayoutOrientation), excelize.PageLayoutOrientation(excelize.OrientationLandscape)}, - {new(excelize.PageLayoutPaperSize), excelize.PageLayoutPaperSize(10)}, - {new(excelize.FitToHeight), excelize.FitToHeight(2)}, - {new(excelize.FitToWidth), excelize.FitToWidth(2)}, + {new(PageLayoutOrientation), PageLayoutOrientation(OrientationLandscape)}, + {new(PageLayoutPaperSize), PageLayoutPaperSize(10)}, + {new(FitToHeight), FitToHeight(2)}, + {new(FitToWidth), FitToWidth(2)}, } for i, test := range testData { @@ -108,11 +106,11 @@ func TestPageLayoutOption(t *testing.T) { opt := test.nonDefault t.Logf("option %T", opt) - def := deepcopy.Copy(test.container).(excelize.PageLayoutOptionPtr) - val1 := deepcopy.Copy(def).(excelize.PageLayoutOptionPtr) - val2 := deepcopy.Copy(def).(excelize.PageLayoutOptionPtr) + def := deepcopy.Copy(test.container).(PageLayoutOptionPtr) + val1 := deepcopy.Copy(def).(PageLayoutOptionPtr) + val2 := deepcopy.Copy(def).(PageLayoutOptionPtr) - f := excelize.NewFile() + f := NewFile() // Get the default value assert.NoError(t, f.GetPageLayout(sheet, def), opt) // Get again and check @@ -150,7 +148,7 @@ func TestPageLayoutOption(t *testing.T) { } func TestSearchSheet(t *testing.T) { - f, err := excelize.OpenFile(filepath.Join("test", "SharedStrings.xlsx")) + f, err := OpenFile(filepath.Join("test", "SharedStrings.xlsx")) if !assert.NoError(t, err) { t.FailNow() } @@ -172,36 +170,36 @@ func TestSearchSheet(t *testing.T) { assert.EqualValues(t, expected, result) // Test search worksheet data after set cell value - f = excelize.NewFile() + f = NewFile() assert.NoError(t, f.SetCellValue("Sheet1", "A1", true)) _, err = f.SearchSheet("Sheet1", "") assert.NoError(t, err) } func TestSetPageLayout(t *testing.T) { - f := excelize.NewFile() + f := NewFile() // Test set page layout on not exists worksheet. assert.EqualError(t, f.SetPageLayout("SheetN"), "sheet SheetN is not exist") } func TestGetPageLayout(t *testing.T) { - f := excelize.NewFile() + f := NewFile() // Test get page layout on not exists worksheet. assert.EqualError(t, f.GetPageLayout("SheetN"), "sheet SheetN is not exist") } func TestSetHeaderFooter(t *testing.T) { - f := excelize.NewFile() + f := NewFile() assert.NoError(t, f.SetCellStr("Sheet1", "A1", "Test SetHeaderFooter")) // Test set header and footer on not exists worksheet. assert.EqualError(t, f.SetHeaderFooter("SheetN", nil), "sheet SheetN is not exist") // Test set header and footer with illegal setting. - assert.EqualError(t, f.SetHeaderFooter("Sheet1", &excelize.FormatHeaderFooter{ + assert.EqualError(t, f.SetHeaderFooter("Sheet1", &FormatHeaderFooter{ OddHeader: strings.Repeat("c", 256), }), "field OddHeader must be less than 255 characters") assert.NoError(t, f.SetHeaderFooter("Sheet1", nil)) - assert.NoError(t, f.SetHeaderFooter("Sheet1", &excelize.FormatHeaderFooter{ + assert.NoError(t, f.SetHeaderFooter("Sheet1", &FormatHeaderFooter{ DifferentFirst: true, DifferentOddEven: true, OddHeader: "&R&P", @@ -214,28 +212,28 @@ func TestSetHeaderFooter(t *testing.T) { } func TestDefinedName(t *testing.T) { - f := excelize.NewFile() - assert.NoError(t, f.SetDefinedName(&excelize.DefinedName{ + f := NewFile() + assert.NoError(t, f.SetDefinedName(&DefinedName{ Name: "Amount", RefersTo: "Sheet1!$A$2:$D$5", Comment: "defined name comment", Scope: "Sheet1", })) - assert.NoError(t, f.SetDefinedName(&excelize.DefinedName{ + assert.NoError(t, f.SetDefinedName(&DefinedName{ Name: "Amount", RefersTo: "Sheet1!$A$2:$D$5", Comment: "defined name comment", })) - assert.EqualError(t, f.SetDefinedName(&excelize.DefinedName{ + assert.EqualError(t, f.SetDefinedName(&DefinedName{ Name: "Amount", RefersTo: "Sheet1!$A$2:$D$5", Comment: "defined name comment", }), "the same name already exists on the scope") - assert.EqualError(t, f.DeleteDefinedName(&excelize.DefinedName{ + assert.EqualError(t, f.DeleteDefinedName(&DefinedName{ Name: "No Exist Defined Name", }), "no defined name on the scope") assert.Exactly(t, "Sheet1!$A$2:$D$5", f.GetDefinedName()[1].RefersTo) - assert.NoError(t, f.DeleteDefinedName(&excelize.DefinedName{ + assert.NoError(t, f.DeleteDefinedName(&DefinedName{ Name: "Amount", })) assert.Exactly(t, "Sheet1!$A$2:$D$5", f.GetDefinedName()[0].RefersTo) @@ -244,7 +242,7 @@ func TestDefinedName(t *testing.T) { } func TestGroupSheets(t *testing.T) { - f := excelize.NewFile() + f := NewFile() sheets := []string{"Sheet2", "Sheet3"} for _, sheet := range sheets { f.NewSheet(sheet) @@ -256,7 +254,7 @@ func TestGroupSheets(t *testing.T) { } func TestUngroupSheets(t *testing.T) { - f := excelize.NewFile() + f := NewFile() sheets := []string{"Sheet2", "Sheet3", "Sheet4", "Sheet5"} for _, sheet := range sheets { f.NewSheet(sheet) @@ -265,7 +263,7 @@ func TestUngroupSheets(t *testing.T) { } func TestInsertPageBreak(t *testing.T) { - f := excelize.NewFile() + f := NewFile() assert.NoError(t, f.InsertPageBreak("Sheet1", "A1")) assert.NoError(t, f.InsertPageBreak("Sheet1", "B2")) assert.NoError(t, f.InsertPageBreak("Sheet1", "C3")) @@ -276,7 +274,7 @@ func TestInsertPageBreak(t *testing.T) { } func TestRemovePageBreak(t *testing.T) { - f := excelize.NewFile() + f := NewFile() assert.NoError(t, f.RemovePageBreak("Sheet1", "A2")) assert.NoError(t, f.InsertPageBreak("Sheet1", "A2")) @@ -302,7 +300,7 @@ func TestRemovePageBreak(t *testing.T) { } func TestGetSheetName(t *testing.T) { - f, _ := excelize.OpenFile(filepath.Join("test", "Book1.xlsx")) + f, _ := OpenFile(filepath.Join("test", "Book1.xlsx")) assert.Equal(t, "Sheet1", f.GetSheetName(0)) assert.Equal(t, "Sheet2", f.GetSheetName(1)) assert.Equal(t, "", f.GetSheetName(-1)) @@ -314,7 +312,7 @@ func TestGetSheetMap(t *testing.T) { 1: "Sheet1", 2: "Sheet2", } - f, _ := excelize.OpenFile(filepath.Join("test", "Book1.xlsx")) + f, _ := OpenFile(filepath.Join("test", "Book1.xlsx")) sheetMap := f.GetSheetMap() for idx, name := range sheetMap { assert.Equal(t, expectedMap[idx], name) diff --git a/sheetpr_test.go b/sheetpr_test.go index 6e031518e1..29bd99efda 100644 --- a/sheetpr_test.go +++ b/sheetpr_test.go @@ -1,4 +1,4 @@ -package excelize_test +package excelize import ( "fmt" @@ -6,39 +6,37 @@ import ( "github.com/mohae/deepcopy" "github.com/stretchr/testify/assert" - - "github.com/360EntSecGroup-Skylar/excelize/v2" ) -var _ = []excelize.SheetPrOption{ - excelize.CodeName("hello"), - excelize.EnableFormatConditionsCalculation(false), - excelize.Published(false), - excelize.FitToPage(true), - excelize.AutoPageBreaks(true), - excelize.OutlineSummaryBelow(true), +var _ = []SheetPrOption{ + CodeName("hello"), + EnableFormatConditionsCalculation(false), + Published(false), + FitToPage(true), + AutoPageBreaks(true), + OutlineSummaryBelow(true), } -var _ = []excelize.SheetPrOptionPtr{ - (*excelize.CodeName)(nil), - (*excelize.EnableFormatConditionsCalculation)(nil), - (*excelize.Published)(nil), - (*excelize.FitToPage)(nil), - (*excelize.AutoPageBreaks)(nil), - (*excelize.OutlineSummaryBelow)(nil), +var _ = []SheetPrOptionPtr{ + (*CodeName)(nil), + (*EnableFormatConditionsCalculation)(nil), + (*Published)(nil), + (*FitToPage)(nil), + (*AutoPageBreaks)(nil), + (*OutlineSummaryBelow)(nil), } func ExampleFile_SetSheetPrOptions() { - f := excelize.NewFile() + f := NewFile() const sheet = "Sheet1" if err := f.SetSheetPrOptions(sheet, - excelize.CodeName("code"), - excelize.EnableFormatConditionsCalculation(false), - excelize.Published(false), - excelize.FitToPage(true), - excelize.AutoPageBreaks(true), - excelize.OutlineSummaryBelow(false), + CodeName("code"), + EnableFormatConditionsCalculation(false), + Published(false), + FitToPage(true), + AutoPageBreaks(true), + OutlineSummaryBelow(false), ); err != nil { fmt.Println(err) } @@ -46,16 +44,16 @@ func ExampleFile_SetSheetPrOptions() { } func ExampleFile_GetSheetPrOptions() { - f := excelize.NewFile() + f := NewFile() const sheet = "Sheet1" var ( - codeName excelize.CodeName - enableFormatConditionsCalculation excelize.EnableFormatConditionsCalculation - published excelize.Published - fitToPage excelize.FitToPage - autoPageBreaks excelize.AutoPageBreaks - outlineSummaryBelow excelize.OutlineSummaryBelow + codeName CodeName + enableFormatConditionsCalculation EnableFormatConditionsCalculation + published Published + fitToPage FitToPage + autoPageBreaks AutoPageBreaks + outlineSummaryBelow OutlineSummaryBelow ) if err := f.GetSheetPrOptions(sheet, @@ -89,15 +87,15 @@ func TestSheetPrOptions(t *testing.T) { const sheet = "Sheet1" testData := []struct { - container excelize.SheetPrOptionPtr - nonDefault excelize.SheetPrOption + container SheetPrOptionPtr + nonDefault SheetPrOption }{ - {new(excelize.CodeName), excelize.CodeName("xx")}, - {new(excelize.EnableFormatConditionsCalculation), excelize.EnableFormatConditionsCalculation(false)}, - {new(excelize.Published), excelize.Published(false)}, - {new(excelize.FitToPage), excelize.FitToPage(true)}, - {new(excelize.AutoPageBreaks), excelize.AutoPageBreaks(true)}, - {new(excelize.OutlineSummaryBelow), excelize.OutlineSummaryBelow(false)}, + {new(CodeName), CodeName("xx")}, + {new(EnableFormatConditionsCalculation), EnableFormatConditionsCalculation(false)}, + {new(Published), Published(false)}, + {new(FitToPage), FitToPage(true)}, + {new(AutoPageBreaks), AutoPageBreaks(true)}, + {new(OutlineSummaryBelow), OutlineSummaryBelow(false)}, } for i, test := range testData { @@ -106,11 +104,11 @@ func TestSheetPrOptions(t *testing.T) { opt := test.nonDefault t.Logf("option %T", opt) - def := deepcopy.Copy(test.container).(excelize.SheetPrOptionPtr) - val1 := deepcopy.Copy(def).(excelize.SheetPrOptionPtr) - val2 := deepcopy.Copy(def).(excelize.SheetPrOptionPtr) + def := deepcopy.Copy(test.container).(SheetPrOptionPtr) + val1 := deepcopy.Copy(def).(SheetPrOptionPtr) + val2 := deepcopy.Copy(def).(SheetPrOptionPtr) - f := excelize.NewFile() + f := NewFile() // Get the default value assert.NoError(t, f.GetSheetPrOptions(sheet, def), opt) // Get again and check @@ -148,46 +146,46 @@ func TestSheetPrOptions(t *testing.T) { } func TestSetSheetrOptions(t *testing.T) { - f := excelize.NewFile() + f := NewFile() // Test SetSheetrOptions on not exists worksheet. assert.EqualError(t, f.SetSheetPrOptions("SheetN"), "sheet SheetN is not exist") } func TestGetSheetPrOptions(t *testing.T) { - f := excelize.NewFile() + f := NewFile() // Test GetSheetPrOptions on not exists worksheet. assert.EqualError(t, f.GetSheetPrOptions("SheetN"), "sheet SheetN is not exist") } -var _ = []excelize.PageMarginsOptions{ - excelize.PageMarginBottom(1.0), - excelize.PageMarginFooter(1.0), - excelize.PageMarginHeader(1.0), - excelize.PageMarginLeft(1.0), - excelize.PageMarginRight(1.0), - excelize.PageMarginTop(1.0), +var _ = []PageMarginsOptions{ + PageMarginBottom(1.0), + PageMarginFooter(1.0), + PageMarginHeader(1.0), + PageMarginLeft(1.0), + PageMarginRight(1.0), + PageMarginTop(1.0), } -var _ = []excelize.PageMarginsOptionsPtr{ - (*excelize.PageMarginBottom)(nil), - (*excelize.PageMarginFooter)(nil), - (*excelize.PageMarginHeader)(nil), - (*excelize.PageMarginLeft)(nil), - (*excelize.PageMarginRight)(nil), - (*excelize.PageMarginTop)(nil), +var _ = []PageMarginsOptionsPtr{ + (*PageMarginBottom)(nil), + (*PageMarginFooter)(nil), + (*PageMarginHeader)(nil), + (*PageMarginLeft)(nil), + (*PageMarginRight)(nil), + (*PageMarginTop)(nil), } func ExampleFile_SetPageMargins() { - f := excelize.NewFile() + f := NewFile() const sheet = "Sheet1" if err := f.SetPageMargins(sheet, - excelize.PageMarginBottom(1.0), - excelize.PageMarginFooter(1.0), - excelize.PageMarginHeader(1.0), - excelize.PageMarginLeft(1.0), - excelize.PageMarginRight(1.0), - excelize.PageMarginTop(1.0), + PageMarginBottom(1.0), + PageMarginFooter(1.0), + PageMarginHeader(1.0), + PageMarginLeft(1.0), + PageMarginRight(1.0), + PageMarginTop(1.0), ); err != nil { fmt.Println(err) } @@ -195,16 +193,16 @@ func ExampleFile_SetPageMargins() { } func ExampleFile_GetPageMargins() { - f := excelize.NewFile() + f := NewFile() const sheet = "Sheet1" var ( - marginBottom excelize.PageMarginBottom - marginFooter excelize.PageMarginFooter - marginHeader excelize.PageMarginHeader - marginLeft excelize.PageMarginLeft - marginRight excelize.PageMarginRight - marginTop excelize.PageMarginTop + marginBottom PageMarginBottom + marginFooter PageMarginFooter + marginHeader PageMarginHeader + marginLeft PageMarginLeft + marginRight PageMarginRight + marginTop PageMarginTop ) if err := f.GetPageMargins(sheet, @@ -238,15 +236,15 @@ func TestPageMarginsOption(t *testing.T) { const sheet = "Sheet1" testData := []struct { - container excelize.PageMarginsOptionsPtr - nonDefault excelize.PageMarginsOptions + container PageMarginsOptionsPtr + nonDefault PageMarginsOptions }{ - {new(excelize.PageMarginTop), excelize.PageMarginTop(1.0)}, - {new(excelize.PageMarginBottom), excelize.PageMarginBottom(1.0)}, - {new(excelize.PageMarginLeft), excelize.PageMarginLeft(1.0)}, - {new(excelize.PageMarginRight), excelize.PageMarginRight(1.0)}, - {new(excelize.PageMarginHeader), excelize.PageMarginHeader(1.0)}, - {new(excelize.PageMarginFooter), excelize.PageMarginFooter(1.0)}, + {new(PageMarginTop), PageMarginTop(1.0)}, + {new(PageMarginBottom), PageMarginBottom(1.0)}, + {new(PageMarginLeft), PageMarginLeft(1.0)}, + {new(PageMarginRight), PageMarginRight(1.0)}, + {new(PageMarginHeader), PageMarginHeader(1.0)}, + {new(PageMarginFooter), PageMarginFooter(1.0)}, } for i, test := range testData { @@ -255,11 +253,11 @@ func TestPageMarginsOption(t *testing.T) { opt := test.nonDefault t.Logf("option %T", opt) - def := deepcopy.Copy(test.container).(excelize.PageMarginsOptionsPtr) - val1 := deepcopy.Copy(def).(excelize.PageMarginsOptionsPtr) - val2 := deepcopy.Copy(def).(excelize.PageMarginsOptionsPtr) + def := deepcopy.Copy(test.container).(PageMarginsOptionsPtr) + val1 := deepcopy.Copy(def).(PageMarginsOptionsPtr) + val2 := deepcopy.Copy(def).(PageMarginsOptionsPtr) - f := excelize.NewFile() + f := NewFile() // Get the default value assert.NoError(t, f.GetPageMargins(sheet, def), opt) // Get again and check @@ -297,29 +295,29 @@ func TestPageMarginsOption(t *testing.T) { } func TestSetPageMargins(t *testing.T) { - f := excelize.NewFile() + f := NewFile() // Test set page margins on not exists worksheet. assert.EqualError(t, f.SetPageMargins("SheetN"), "sheet SheetN is not exist") } func TestGetPageMargins(t *testing.T) { - f := excelize.NewFile() + f := NewFile() // Test get page margins on not exists worksheet. assert.EqualError(t, f.GetPageMargins("SheetN"), "sheet SheetN is not exist") } func ExampleFile_SetSheetFormatPr() { - f := excelize.NewFile() + f := NewFile() const sheet = "Sheet1" if err := f.SetSheetFormatPr(sheet, - excelize.BaseColWidth(1.0), - excelize.DefaultColWidth(1.0), - excelize.DefaultRowHeight(1.0), - excelize.CustomHeight(true), - excelize.ZeroHeight(true), - excelize.ThickTop(true), - excelize.ThickBottom(true), + BaseColWidth(1.0), + DefaultColWidth(1.0), + DefaultRowHeight(1.0), + CustomHeight(true), + ZeroHeight(true), + ThickTop(true), + ThickBottom(true), ); err != nil { fmt.Println(err) } @@ -327,17 +325,17 @@ func ExampleFile_SetSheetFormatPr() { } func ExampleFile_GetSheetFormatPr() { - f := excelize.NewFile() + f := NewFile() const sheet = "Sheet1" var ( - baseColWidth excelize.BaseColWidth - defaultColWidth excelize.DefaultColWidth - defaultRowHeight excelize.DefaultRowHeight - customHeight excelize.CustomHeight - zeroHeight excelize.ZeroHeight - thickTop excelize.ThickTop - thickBottom excelize.ThickBottom + baseColWidth BaseColWidth + defaultColWidth DefaultColWidth + defaultRowHeight DefaultRowHeight + customHeight CustomHeight + zeroHeight ZeroHeight + thickTop ThickTop + thickBottom ThickBottom ) if err := f.GetSheetFormatPr(sheet, @@ -374,16 +372,16 @@ func TestSheetFormatPrOptions(t *testing.T) { const sheet = "Sheet1" testData := []struct { - container excelize.SheetFormatPrOptionsPtr - nonDefault excelize.SheetFormatPrOptions + container SheetFormatPrOptionsPtr + nonDefault SheetFormatPrOptions }{ - {new(excelize.BaseColWidth), excelize.BaseColWidth(1.0)}, - {new(excelize.DefaultColWidth), excelize.DefaultColWidth(1.0)}, - {new(excelize.DefaultRowHeight), excelize.DefaultRowHeight(1.0)}, - {new(excelize.CustomHeight), excelize.CustomHeight(true)}, - {new(excelize.ZeroHeight), excelize.ZeroHeight(true)}, - {new(excelize.ThickTop), excelize.ThickTop(true)}, - {new(excelize.ThickBottom), excelize.ThickBottom(true)}, + {new(BaseColWidth), BaseColWidth(1.0)}, + {new(DefaultColWidth), DefaultColWidth(1.0)}, + {new(DefaultRowHeight), DefaultRowHeight(1.0)}, + {new(CustomHeight), CustomHeight(true)}, + {new(ZeroHeight), ZeroHeight(true)}, + {new(ThickTop), ThickTop(true)}, + {new(ThickBottom), ThickBottom(true)}, } for i, test := range testData { @@ -392,11 +390,11 @@ func TestSheetFormatPrOptions(t *testing.T) { opt := test.nonDefault t.Logf("option %T", opt) - def := deepcopy.Copy(test.container).(excelize.SheetFormatPrOptionsPtr) - val1 := deepcopy.Copy(def).(excelize.SheetFormatPrOptionsPtr) - val2 := deepcopy.Copy(def).(excelize.SheetFormatPrOptionsPtr) + def := deepcopy.Copy(test.container).(SheetFormatPrOptionsPtr) + val1 := deepcopy.Copy(def).(SheetFormatPrOptionsPtr) + val2 := deepcopy.Copy(def).(SheetFormatPrOptionsPtr) - f := excelize.NewFile() + f := NewFile() // Get the default value assert.NoError(t, f.GetSheetFormatPr(sheet, def), opt) // Get again and check @@ -434,26 +432,26 @@ func TestSheetFormatPrOptions(t *testing.T) { } func TestSetSheetFormatPr(t *testing.T) { - f := excelize.NewFile() + f := NewFile() assert.NoError(t, f.GetSheetFormatPr("Sheet1")) f.Sheet["xl/worksheets/sheet1.xml"].SheetFormatPr = nil - assert.NoError(t, f.SetSheetFormatPr("Sheet1", excelize.BaseColWidth(1.0))) + assert.NoError(t, f.SetSheetFormatPr("Sheet1", BaseColWidth(1.0))) // Test set formatting properties on not exists worksheet. assert.EqualError(t, f.SetSheetFormatPr("SheetN"), "sheet SheetN is not exist") } func TestGetSheetFormatPr(t *testing.T) { - f := excelize.NewFile() + f := NewFile() assert.NoError(t, f.GetSheetFormatPr("Sheet1")) f.Sheet["xl/worksheets/sheet1.xml"].SheetFormatPr = nil var ( - baseColWidth excelize.BaseColWidth - defaultColWidth excelize.DefaultColWidth - defaultRowHeight excelize.DefaultRowHeight - customHeight excelize.CustomHeight - zeroHeight excelize.ZeroHeight - thickTop excelize.ThickTop - thickBottom excelize.ThickBottom + baseColWidth BaseColWidth + defaultColWidth DefaultColWidth + defaultRowHeight DefaultRowHeight + customHeight CustomHeight + zeroHeight ZeroHeight + thickTop ThickTop + thickBottom ThickBottom ) assert.NoError(t, f.GetSheetFormatPr("Sheet1", &baseColWidth, diff --git a/sheetview_test.go b/sheetview_test.go index d999875030..e323e2380c 100644 --- a/sheetview_test.go +++ b/sheetview_test.go @@ -1,60 +1,58 @@ -package excelize_test +package excelize import ( "fmt" "testing" "github.com/stretchr/testify/assert" - - "github.com/360EntSecGroup-Skylar/excelize/v2" ) -var _ = []excelize.SheetViewOption{ - excelize.DefaultGridColor(true), - excelize.RightToLeft(false), - excelize.ShowFormulas(false), - excelize.ShowGridLines(true), - excelize.ShowRowColHeaders(true), - excelize.TopLeftCell("B2"), +var _ = []SheetViewOption{ + DefaultGridColor(true), + RightToLeft(false), + ShowFormulas(false), + ShowGridLines(true), + ShowRowColHeaders(true), + TopLeftCell("B2"), // SheetViewOptionPtr are also SheetViewOption - new(excelize.DefaultGridColor), - new(excelize.RightToLeft), - new(excelize.ShowFormulas), - new(excelize.ShowGridLines), - new(excelize.ShowRowColHeaders), - new(excelize.TopLeftCell), + new(DefaultGridColor), + new(RightToLeft), + new(ShowFormulas), + new(ShowGridLines), + new(ShowRowColHeaders), + new(TopLeftCell), } -var _ = []excelize.SheetViewOptionPtr{ - (*excelize.DefaultGridColor)(nil), - (*excelize.RightToLeft)(nil), - (*excelize.ShowFormulas)(nil), - (*excelize.ShowGridLines)(nil), - (*excelize.ShowRowColHeaders)(nil), - (*excelize.TopLeftCell)(nil), +var _ = []SheetViewOptionPtr{ + (*DefaultGridColor)(nil), + (*RightToLeft)(nil), + (*ShowFormulas)(nil), + (*ShowGridLines)(nil), + (*ShowRowColHeaders)(nil), + (*TopLeftCell)(nil), } func ExampleFile_SetSheetViewOptions() { - f := excelize.NewFile() + f := NewFile() const sheet = "Sheet1" if err := f.SetSheetViewOptions(sheet, 0, - excelize.DefaultGridColor(false), - excelize.RightToLeft(false), - excelize.ShowFormulas(true), - excelize.ShowGridLines(true), - excelize.ShowRowColHeaders(true), - excelize.ZoomScale(80), - excelize.TopLeftCell("C3"), + DefaultGridColor(false), + RightToLeft(false), + ShowFormulas(true), + ShowGridLines(true), + ShowRowColHeaders(true), + ZoomScale(80), + TopLeftCell("C3"), ); err != nil { fmt.Println(err) } - var zoomScale excelize.ZoomScale + var zoomScale ZoomScale fmt.Println("Default:") fmt.Println("- zoomScale: 80") - if err := f.SetSheetViewOptions(sheet, 0, excelize.ZoomScale(500)); err != nil { + if err := f.SetSheetViewOptions(sheet, 0, ZoomScale(500)); err != nil { fmt.Println(err) } @@ -65,7 +63,7 @@ func ExampleFile_SetSheetViewOptions() { fmt.Println("Used out of range value:") fmt.Println("- zoomScale:", zoomScale) - if err := f.SetSheetViewOptions(sheet, 0, excelize.ZoomScale(123)); err != nil { + if err := f.SetSheetViewOptions(sheet, 0, ZoomScale(123)); err != nil { fmt.Println(err) } @@ -87,18 +85,18 @@ func ExampleFile_SetSheetViewOptions() { } func ExampleFile_GetSheetViewOptions() { - f := excelize.NewFile() + f := NewFile() const sheet = "Sheet1" var ( - defaultGridColor excelize.DefaultGridColor - rightToLeft excelize.RightToLeft - showFormulas excelize.ShowFormulas - showGridLines excelize.ShowGridLines - showZeros excelize.ShowZeros - showRowColHeaders excelize.ShowRowColHeaders - zoomScale excelize.ZoomScale - topLeftCell excelize.TopLeftCell + defaultGridColor DefaultGridColor + rightToLeft RightToLeft + showFormulas ShowFormulas + showGridLines ShowGridLines + showZeros ShowZeros + showRowColHeaders ShowRowColHeaders + zoomScale ZoomScale + topLeftCell TopLeftCell ) if err := f.GetSheetViewOptions(sheet, 0, @@ -124,7 +122,7 @@ func ExampleFile_GetSheetViewOptions() { fmt.Println("- zoomScale:", zoomScale) fmt.Println("- topLeftCell:", `"`+topLeftCell+`"`) - if err := f.SetSheetViewOptions(sheet, 0, excelize.TopLeftCell("B2")); err != nil { + if err := f.SetSheetViewOptions(sheet, 0, TopLeftCell("B2")); err != nil { fmt.Println(err) } @@ -132,7 +130,7 @@ func ExampleFile_GetSheetViewOptions() { fmt.Println(err) } - if err := f.SetSheetViewOptions(sheet, 0, excelize.ShowGridLines(false)); err != nil { + if err := f.SetSheetViewOptions(sheet, 0, ShowGridLines(false)); err != nil { fmt.Println(err) } @@ -140,7 +138,7 @@ func ExampleFile_GetSheetViewOptions() { fmt.Println(err) } - if err := f.SetSheetViewOptions(sheet, 0, excelize.ShowZeros(false)); err != nil { + if err := f.SetSheetViewOptions(sheet, 0, ShowZeros(false)); err != nil { fmt.Println(err) } @@ -170,7 +168,7 @@ func ExampleFile_GetSheetViewOptions() { } func TestSheetViewOptionsErrors(t *testing.T) { - f := excelize.NewFile() + f := NewFile() const sheet = "Sheet1" assert.NoError(t, f.GetSheetViewOptions(sheet, 0)) From b959dfdacd0cfe35c94abcea34d66b3d2bb71bb9 Mon Sep 17 00:00:00 2001 From: akustikov Date: Fri, 11 Sep 2020 21:02:11 +0300 Subject: [PATCH 03/11] fix numeric values conversion as done in legacy Excel --- rows.go | 19 +++++++++++++++++++ rows_test.go | 22 +++++++--------------- styles.go | 14 ++++++++------ styles_test.go | 9 +++++++++ test/NumberFormats.xlsx | Bin 0 -> 8906 bytes 5 files changed, 43 insertions(+), 21 deletions(-) create mode 100644 test/NumberFormats.xlsx diff --git a/rows.go b/rows.go index eb4b1dfe62..50e7308570 100644 --- a/rows.go +++ b/rows.go @@ -345,6 +345,25 @@ func (xlsx *xlsxC) getValueFrom(f *File, d *xlsxSST) (string, error) { } return f.formattedValue(xlsx.S, xlsx.V), nil default: + // correct numeric values as legacy Excel app + // https://en.wikipedia.org/wiki/Numeric_precision_in_Microsoft_Excel + // In the top figure the fraction 1/9000 in Excel is displayed. + // Although this number has a decimal representation that is an infinite string of ones, + // Excel displays only the leading 15 figures. In the second line, the number one is added to the fraction, and again Excel displays only 15 figures. + const precision = 1000000000000000 + if len(xlsx.V) > 16 { + num, err := strconv.ParseFloat(xlsx.V, 64) + if err != nil { + return "", err + } + + num = math.Round(num*precision) / precision + val := fmt.Sprintf("%g", num) + if val != xlsx.V { + return f.formattedValue(xlsx.S, val), nil + } + } + return f.formattedValue(xlsx.S, xlsx.V), nil } } diff --git a/rows_test.go b/rows_test.go index f9accf1633..ee58339ffe 100644 --- a/rows_test.go +++ b/rows_test.go @@ -842,24 +842,18 @@ func TestCheckRow(t *testing.T) { assert.EqualError(t, f.SetCellValue("Sheet1", "A1", false), `cannot convert cell "-" to coordinates: invalid cell name "-"`) } -func TestDateFormats(t *testing.T) { - xlsx, err := OpenFile(filepath.Join("test", "DateFormats.xlsx")) +func TestNumberFormats(t *testing.T) { + xlsx, err := OpenFile(filepath.Join("test", "NumberFormats.xlsx")) if !assert.NoError(t, err) { t.FailNow() } - dt1, err := xlsx.GetCellValue("test", "C2") - assert.NoError(t, err) - assert.Equal(t, "08/05/2019", dt1) - - dt2, err := xlsx.GetCellValue("test", "D2") - assert.NoError(t, err) - assert.Equal(t, "2019-03-04", dt2) - cells := make([][]string, 0) + rows, err := xlsx.Rows("numbers") // nuprod20200726062152 + if !assert.NoError(t, err) { + t.FailNow() + } - rows, err := xlsx.Rows("test") - assert.NoError(t, err) for rows.Next() { row, err := rows.Columns() assert.NoError(t, err) @@ -870,9 +864,7 @@ func TestDateFormats(t *testing.T) { cells = append(cells, row) } - assert.Equal(t, []string{"1", "abc", "08/05/2019", "2019-03-04", "04/03/2019", "1", "4"}, cells[1]) - assert.Equal(t, []string{"2", "ddd hhh", "08/06/2019", "2019-03-05", "05/03/2019", "2", "5"}, cells[2]) - + assert.Equal(t, []string{"BKR", "4.69", "0", "0.01", "1.6", "19.2"}, cells[6]) } func BenchmarkRows(b *testing.B) { diff --git a/styles.go b/styles.go index 87eaeaad9b..cd29ed18c0 100644 --- a/styles.go +++ b/styles.go @@ -964,7 +964,6 @@ func parseTime(v string, format string) string { } goFmt, found := dateTimeFormatsCache[format] - if found { return val.Format(goFmt) } @@ -992,8 +991,11 @@ func parseTime(v string, format string) string { {"mmm", "Jan"}, {"mmss", "0405"}, {"ss", "05"}, + {"s", "5"}, {"mm:", "04:"}, {":mm", ":04"}, + {"m:", "4:"}, + {":m", ":4"}, {"mm", "01"}, {"am/pm", "pm"}, {"m/", "1/"}, @@ -1007,17 +1009,17 @@ func parseTime(v string, format string) string { // It is the presence of the "am/pm" indicator that determines if this is // a 12 hour or 24 hours time format, not the number of 'h' characters. if is12HourTime(format) { - goFmt = strings.Replace(goFmt, "hh", "03", 1) + goFmt = strings.Replace(goFmt, "hh", "3", 1) goFmt = strings.Replace(goFmt, "h", "3", 1) - goFmt = strings.Replace(goFmt, "HH", "03", 1) + goFmt = strings.Replace(goFmt, "HH", "3", 1) goFmt = strings.Replace(goFmt, "H", "3", 1) } else { goFmt = strings.Replace(goFmt, "hh", "15", 1) - goFmt = strings.Replace(goFmt, "h", "15", 1) + goFmt = strings.Replace(goFmt, "h", "3", 1) goFmt = strings.Replace(goFmt, "HH", "15", 1) - goFmt = strings.Replace(goFmt, "H", "15", 1) - + goFmt = strings.Replace(goFmt, "H", "3", 1) } + for _, repl := range replacements { goFmt = strings.Replace(goFmt, repl.xltime, repl.gotime, 1) } diff --git a/styles_test.go b/styles_test.go index b68365bc06..bc141f1c5f 100644 --- a/styles_test.go +++ b/styles_test.go @@ -250,3 +250,12 @@ func TestGetStyleID(t *testing.T) { func TestGetFillID(t *testing.T) { assert.Equal(t, -1, getFillID(NewFile().stylesReader(), &Style{Fill: Fill{Type: "unknown"}})) } + +func TestParseTime(t *testing.T) { + assert.Equal(t, "2019", parseTime("43528", "YYYY")) + assert.Equal(t, "2019-03-04 05:05:42", parseTime("43528.2123", "YYYY-MM-DD hh:mm:ss")) + assert.Equal(t, "3/4/2019 5:5:42", parseTime("43528.2123", "M/D/YYYY h:m:s")) + assert.Equal(t, "March", parseTime("43528", "mmmm")) + assert.Equal(t, "Monday", parseTime("43528", "dddd")) + +} diff --git a/test/NumberFormats.xlsx b/test/NumberFormats.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..e7719d8891a72b5c480a8f11d6cec60bb763e1e4 GIT binary patch literal 8906 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 literal 0 HcmV?d00001 From 3f9d3c5d7f7214883fd4e1a94e7c9299d5095527 Mon Sep 17 00:00:00 2001 From: akustikov Date: Fri, 11 Sep 2020 22:03:34 +0300 Subject: [PATCH 04/11] fix tests coverage --- cell.go | 3 +++ cell_test.go | 15 +++++++++++++++ rows_test.go | 16 +++++++++++++++- styles_test.go | 4 +++- templates.go | 2 +- 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/cell.go b/cell.go index 58bcebf2cc..f7ab5739a0 100644 --- a/cell.go +++ b/cell.go @@ -762,6 +762,9 @@ func (f *File) formattedValue(s int, v string) string { return v } styleSheet := f.stylesReader() + if s > len(styleSheet.CellXfs.Xf) { + return v + } numFmtId := *styleSheet.CellXfs.Xf[s].NumFmtID ok := builtInNumFmtFunc[numFmtId] if ok != nil { diff --git a/cell_test.go b/cell_test.go index 441a6946ed..72e4c8dd8f 100644 --- a/cell_test.go +++ b/cell_test.go @@ -264,3 +264,18 @@ func TestSetCellRichText(t *testing.T) { // Test set cell rich text with illegal cell coordinates assert.EqualError(t, f.SetCellRichText("Sheet1", "A", richTextRun), `cannot convert cell "A" to coordinates: invalid cell name "A"`) } + +func TestFormattedValue(t *testing.T) { + f := NewFile() + v := f.formattedValue(0, "43528") + assert.Equal(t, "43528", v) + + v = f.formattedValue(15, "43528") + assert.Equal(t, "43528", v) + + v = f.formattedValue(1, "43528") + assert.Equal(t, "43528", v) + + v = f.formattedValue(2, "43528") + assert.Equal(t, "03/04/2019", v) +} diff --git a/rows_test.go b/rows_test.go index ee58339ffe..9c2a2decf7 100644 --- a/rows_test.go +++ b/rows_test.go @@ -817,7 +817,7 @@ func TestDuplicateMergeCells(t *testing.T) { assert.EqualError(t, f.duplicateMergeCells("SheetN", xlsx, 1, 2), "sheet SheetN is not exist") } -func TestGetValueFrom(t *testing.T) { +func TestGetValueFromInlineStr(t *testing.T) { c := &xlsxC{T: "inlineStr"} f := NewFile() d := &xlsxSST{} @@ -826,6 +826,20 @@ func TestGetValueFrom(t *testing.T) { assert.Equal(t, "", val) } +func TestGetValueFromNumber(t *testing.T) { + c := &xlsxC{T: "n", V: "2.2200000000000002"} + f := NewFile() + d := &xlsxSST{} + val, err := c.getValueFrom(f, d) + assert.NoError(t, err) + assert.Equal(t, "2.22", val) + + c = &xlsxC{T: "n", V: "2.220000ddsf0000000002-r"} + val, err = c.getValueFrom(f, d) + assert.NotNil(t, err) + assert.Equal(t, "strconv.ParseFloat: parsing \"2.220000ddsf0000000002-r\": invalid syntax", err.Error()) +} + func TestErrSheetNotExistError(t *testing.T) { err := ErrSheetNotExist{SheetName: "Sheet1"} assert.EqualValues(t, err.Error(), "sheet Sheet1 is not exist") diff --git a/styles_test.go b/styles_test.go index bc141f1c5f..48123a2b6a 100644 --- a/styles_test.go +++ b/styles_test.go @@ -196,7 +196,7 @@ func TestNewStyle(t *testing.T) { fontID := styles.CellXfs.Xf[styleID].FontID font := styles.Fonts.Font[*fontID] assert.Contains(t, *font.Name.Val, "Times New Roman", "Stored font should contain font name") - assert.Equal(t, 2, styles.CellXfs.Count, "Should have 2 styles") + assert.Equal(t, 4, styles.CellXfs.Count, "Should have 4 styles") _, err = f.NewStyle(&Style{}) assert.NoError(t, err) _, err = f.NewStyle(Style{}) @@ -253,6 +253,8 @@ func TestGetFillID(t *testing.T) { func TestParseTime(t *testing.T) { assert.Equal(t, "2019", parseTime("43528", "YYYY")) + assert.Equal(t, "43528", parseTime("43528", "")) + assert.Equal(t, "2019-03-04 05:05:42", parseTime("43528.2123", "YYYY-MM-DD hh:mm:ss")) assert.Equal(t, "3/4/2019 5:5:42", parseTime("43528.2123", "M/D/YYYY h:m:s")) assert.Equal(t, "March", parseTime("43528", "mmmm")) diff --git a/templates.go b/templates.go index 5721150ce8..b4dd54fdb5 100644 --- a/templates.go +++ b/templates.go @@ -29,7 +29,7 @@ const templateContentTypes = `` -const templateStyles = `` +const templateStyles = `` const templateSheet = `` From bbf5bdc2fa4af394e843a5de53aafa79c987ade0 Mon Sep 17 00:00:00 2001 From: akustikov Date: Tue, 22 Sep 2020 12:57:11 +0300 Subject: [PATCH 05/11] revert temporary package name fix --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 91db593ea9..fb2c1e8b99 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/artiz/excelize +module github.com/360EntSecGroup-Skylar/excelize/v2 go 1.15 From fc546c60e5c1026d6dc6e3ea5fbaa4f1c802ae7c Mon Sep 17 00:00:00 2001 From: artiz Date: Wed, 23 Sep 2020 00:03:11 +0300 Subject: [PATCH 06/11] remove personal info from test XLSX files --- test/DateFormats.xlsx | Bin 5604 -> 5065 bytes test/NumberFormats.xlsx | Bin 8906 -> 8634 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/test/DateFormats.xlsx b/test/DateFormats.xlsx index aac9678c62b3e70a5207747958397d045746e0bc..8416e821161569363ae5b68ddc3698ff98c8787e 100644 GIT binary patch delta 565 zcmaE&eNtT_z?+#xgn@&DgCV+1E3kEz$*gw_3=HR(HcH4cPM$6-u-TPSgK6>=AfuMq zh?&d(!_TTqKn1Eyn|HDaFis8^5!if_-Is+cEi5kpB;n1p*?@+snA*W`+HjH>celHPWV>L|NLZ*^QoJDTVHU`neG;D;cwjIP^`S< zUP#5(IqKUbejeD8u=ZlW!+P5ao7MRNCv~45JJ@Y37Bk^Nph>3x&b1%RSiCtu)^Kn-eRttgdFlKh__t>8M%x3lR03wMu9OQ&qlj};;{0k{0Ge`7kxxn+R^yZ z_5C>v%l}+$va?j4%2Ul9elghMg0(*ThS$5cNPo?EW3Qgyz5IIJ6_;0s*ICp**cBge zx+daCteMb}zx(1m-u0OKI-K`awp=ikJ$#b4z|`Z08s!I=I7H?zw?8{?($^Oc3oVbA zPJCMKDdxZL%&`)iWkOo88{j2fw5NtiarJajrP;z delta 1103 zcmX@9{zO|Mz?+#xgn@&DgCV+1E06&WHcH4ca>02Fo9!9(n2`D9%ofai2zdquDTc{` zLNb$YvVA~Sc9}hx1(|Qa!^9|tX&VEBAj4!uVd47PAm98$20VM;hllK(uA(5}60n88 zQ0mf_Mzgomma=WynmJ`g|G(c$Tg!5sci()!*XH)dpzEzp{4a)K|gl8p|Z5FUSNe6H;BvlYHB1(&W@tQQo^tBXcKcaY;T&xDb5r z;g{&{2SxQC9na3uEbd*}+I^`l=PLX9=!bRt-@mEeYVzg$%h!J%?vyjVw(OS{tBT}& zDZx{XE*^^$6#AY@JzH8{zJJEVC8vLAq#d5|ReX>7F6M((`N_ZPU)QEq^l(qVlTy%N z6jh~@`h(#{=%;CGr)X9@-Ewrpl_hHR42tKMMCKo66WZQ8f7;e1t*h>)U3zR2bI{AV zDw?gIJK}Ou-JySTH=a&1>#~ggkbNs7gNTiDA#~Ce7P2S4&5J zyBps2;$q6>+n1;Rsee1!Y*ziXsl|)Dj1MM1;1wv)P*+O-BhY-e?5$tpV%}$#>sXc> zW~^ZQ{6w?9D%2?`RpM%&?*l8grG`ap3)NKDZj`%`nitNsFe~Rxfb0SdF1HM|6C0P^ zagbkVsN$aM^7fRs%!^NH>YuNlh?(%Mq-uZelC$26iYp$AY)!1>*|$mI>?Q`*b^E!3 zuRGtn#M}Pxh-+}mpQZEH9X|R>+G5k)H_YviZ{4d=e7f)TRf2;q+^FPOd$%VIjZUaob&rI~J|%tunCK*`ONscJ|)42Va|e*8$^zox^g=N@+)6 zoUCR>iW7dc47>R$zXbDST_Fx}nHU%Z85kH+@{{`2vG@{)TY6oniarUNY8Ju)qw zvOPamh|~n!^1uF#=^*Ep1rF@~pG?&E=P)e)bG6CNQh6#*HFx;MV2caZ`s^EC@7f~$ zHRFxFdVcrv>vdOLUL9U%5&K|Qe8B0Nh$FFPLP!4Yi}QHbWA5v4-dEXj!BqC}N!|ie zj~i-~A7J7TnZMlr?7T@|Upy?dJYG8SX}PDE|GqQFN^F)L{jyi3{?+-OS3l1DpDJvn zd2WijW67j$|A2bt%>}ZjS(HT>L>O=dGccqX7#S2M$0<26CCE%(q@={AA`cP-05);0 AnE(I) delta 412 zcmdnxe9CnLtMuf#%p9^;#5aGjVq{>jVPaqqWZ+;-$xjX_$}cF^PtGq&-P|R^!&u)k z@wDGz0|D3X9)Fyl)FxTCPK)x?Vtm!*<*|fmF_j5C? zjgRK6zV(E8PJWM`;8_kY2X1BQy?Pfn&0B7+@v$-cWc1>NF4iA1!eZk@4jCoN*jObW zY-Otv^1Nl7=)HyWpi$4>8x4=_y7^>}PA%-JZ~sw}owKvzarOaA#pE>#1t*!0S0`k# zD_JQmm6-7D?p9j|E*@Qt3kQ>D1^#);`(Vod%?rZM%~{21EuC(4%r@P-P=NjWHS^|; zuXnAH{%V+1*A*|u@Bep2=Hl0V zqt3lI6mOb&R?6MId%Za1sfxPh%q2f}ENgi>CDuQl`_JNiQVp+e{E2^LvUJO`@SZ0< zKIb~r9j-qASNHyv@Z^ciBAfGM_OeV~rNASO8q5qZFxgMhiK#$#@+3tiHWLMqC;-SU Bvo-(# From 646bb318d5700f3c3888e9cae819c5666e95e74f Mon Sep 17 00:00:00 2001 From: artiz Date: Wed, 23 Sep 2020 00:23:44 +0300 Subject: [PATCH 07/11] remove unused dependencies --- go.sum | 7 ------- 1 file changed, 7 deletions(-) diff --git a/go.sum b/go.sum index 00482b73c7..5b50aa1452 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -16,34 +15,28 @@ github.com/richardlehane/mscfb v1.0.3/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7 github.com/richardlehane/msoleps v1.0.1 h1:RfrALnSNXzmXLbGct/P2b4xkFz4e8Gmj/0Vj9M9xC1o= github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/xuri/efp v0.0.0-20191019043341-b7dc4fe9aa91/go.mod h1:uBiSUepVYMhGTfDeBKKasV4GpgBlzJ46gXUBAqV8qLk= github.com/xuri/efp v0.0.0-20200605144744-ba689101faaf h1:spotWVWg9DP470pPFQ7LaYtUqDpWEOS/BUrSmwFZE4k= github.com/xuri/efp v0.0.0-20200605144744-ba689101faaf/go.mod h1:uBiSUepVYMhGTfDeBKKasV4GpgBlzJ46gXUBAqV8qLk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200801110659-972c09e46d76 h1:U7GPaoQyQmX+CBRWXKrvRzWTbd+slqeSh8uARsIyhAw= golang.org/x/image v0.0.0-20200801110659-972c09e46d76/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= From b76a84db205bd44dc1882b7c4a5bc84e7e42ac5b Mon Sep 17 00:00:00 2001 From: artiz Date: Wed, 23 Sep 2020 01:43:27 +0300 Subject: [PATCH 08/11] update format conversion in parseTime --- rows_test.go | 2 +- styles.go | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/rows_test.go b/rows_test.go index 9c2a2decf7..a33b9c13dd 100644 --- a/rows_test.go +++ b/rows_test.go @@ -863,7 +863,7 @@ func TestNumberFormats(t *testing.T) { } cells := make([][]string, 0) - rows, err := xlsx.Rows("numbers") // nuprod20200726062152 + rows, err := xlsx.Rows("numbers") if !assert.NoError(t, err) { t.FailNow() } diff --git a/styles.go b/styles.go index cd29ed18c0..3051af78fa 100644 --- a/styles.go +++ b/styles.go @@ -975,6 +975,11 @@ func parseTime(v string, format string) string { goFmt = re.ReplaceAllLiteralString(goFmt, "") } + // use only first variant + if strings.Contains(goFmt, ";") { + goFmt = goFmt[:strings.IndexByte(goFmt, ';')] + } + replacements := []struct{ xltime, gotime string }{ {"YYYY", "2006"}, {"YY", "06"}, @@ -1005,6 +1010,9 @@ func parseTime(v string, format string) string { replacementsGlobal := []struct{ xltime, gotime string }{ {"\\-", "-"}, + {"\\ ", " "}, + {"\\.", "."}, + {"\\", ""}, } // It is the presence of the "am/pm" indicator that determines if this is // a 12 hour or 24 hours time format, not the number of 'h' characters. From 95661957e7f33722abf33001d6d3223c08432fb8 Mon Sep 17 00:00:00 2001 From: akustikov Date: Thu, 24 Sep 2020 15:44:48 +0300 Subject: [PATCH 09/11] new UT to increase code coverage --- cell.go | 3 +++ cell_test.go | 17 +++++++++++++++++ excelize.go | 2 +- excelize_test.go | 3 +++ file.go | 2 +- styles.go | 1 + styles_test.go | 34 ++++++++++++++++++++++++++++++++++ 7 files changed, 60 insertions(+), 2 deletions(-) diff --git a/cell.go b/cell.go index f7ab5739a0..05275f1b7a 100644 --- a/cell.go +++ b/cell.go @@ -161,7 +161,10 @@ func setCellTime(value time.Time) (t string, b string, isNum bool, err error) { if err != nil { return } + isNum = excelTime > 0 + fmt.Println("setCellTime", value, excelTime, isNum) + if isNum { t, b = setCellDefault(strconv.FormatFloat(excelTime, 'f', -1, 64)) } else { diff --git a/cell_test.go b/cell_test.go index 72e4c8dd8f..0e30b05662 100644 --- a/cell_test.go +++ b/cell_test.go @@ -111,6 +111,23 @@ func TestSetCellValue(t *testing.T) { assert.EqualError(t, f.SetCellValue("Sheet1", "A", time.Duration(1e13)), `cannot convert cell "A" to coordinates: invalid cell name "A"`) } +func TestSetCellValues(t *testing.T) { + f := NewFile() + err := f.SetCellValue("Sheet1", "A1", time.Date(2010, time.December, 31, 0, 0, 0, 0, time.UTC)) + assert.NoError(t, err) + + v, err := f.GetCellValue("Sheet1", "A1") + assert.NoError(t, err) + assert.Equal(t, v, "12/31/10 12:00") + + // test date value lower than min date supported by Excel + err = f.SetCellValue("Sheet1", "A1", time.Date(1600, time.December, 31, 0, 0, 0, 0, time.UTC)) + assert.NoError(t, err) + + _, err = f.GetCellValue("Sheet1", "A1") + assert.EqualError(t, err, `strconv.ParseFloat: parsing "1600-12-31T00:00:00Z": invalid syntax`) +} + func TestSetCellBool(t *testing.T) { f := NewFile() assert.EqualError(t, f.SetCellBool("Sheet1", "A", true), `cannot convert cell "A" to coordinates: invalid cell name "A"`) diff --git a/excelize.go b/excelize.go index a90b765115..cca6616825 100644 --- a/excelize.go +++ b/excelize.go @@ -158,7 +158,7 @@ func (f *File) setDefaultTimeStyle(sheet, axis string, format int) error { } if s == 0 { style, _ := f.NewStyle(&Style{NumFmt: format}) - _ = f.SetCellStyle(sheet, axis, axis, style) + err = f.SetCellStyle(sheet, axis, axis, style) } return err } diff --git a/excelize_test.go b/excelize_test.go index a45b6b47ec..47c87fc324 100644 --- a/excelize_test.go +++ b/excelize_test.go @@ -1175,6 +1175,9 @@ func TestSetDefaultTimeStyle(t *testing.T) { f := NewFile() // Test set default time style on not exists worksheet. assert.EqualError(t, f.setDefaultTimeStyle("SheetN", "", 0), "sheet SheetN is not exist") + + // Test set default time style on invalid cell + assert.EqualError(t, f.setDefaultTimeStyle("Sheet1", "", 42), "cannot convert cell \"\" to coordinates: invalid cell name \"\"") } func TestAddVBAProject(t *testing.T) { diff --git a/file.go b/file.go index 83ed2711ff..6a48c0c767 100644 --- a/file.go +++ b/file.go @@ -123,7 +123,7 @@ func (f *File) WriteToBuffer() (*bytes.Buffer, error) { } } - if f.options != nil { + if f.options != nil && f.options.Password != "" { if err := zw.Close(); err != nil { return buf, err } diff --git a/styles.go b/styles.go index 3051af78fa..d4d0468904 100644 --- a/styles.go +++ b/styles.go @@ -2281,6 +2281,7 @@ func newNumFmt(styleSheet *xlsxStyleSheet, style *Style) int { // setCustomNumFmt provides a function to set custom number format code. func setCustomNumFmt(styleSheet *xlsxStyleSheet, style *Style) int { nf := xlsxNumFmt{FormatCode: *style.CustomNumFmt} + if styleSheet.NumFmts != nil { nf.NumFmtID = styleSheet.NumFmts.NumFmt[len(styleSheet.NumFmts.NumFmt)-1].NumFmtID + 1 styleSheet.NumFmts.NumFmt = append(styleSheet.NumFmts.NumFmt, &nf) diff --git a/styles_test.go b/styles_test.go index 48123a2b6a..9994d91a30 100644 --- a/styles_test.go +++ b/styles_test.go @@ -201,10 +201,44 @@ func TestNewStyle(t *testing.T) { assert.NoError(t, err) _, err = f.NewStyle(Style{}) assert.EqualError(t, err, "invalid parameter type") + _, err = f.NewStyle(&Style{Font: &Font{Family: strings.Repeat("s", MaxFontFamilyLength+1)}}) assert.EqualError(t, err, "the length of the font family name must be smaller than or equal to 31") _, err = f.NewStyle(&Style{Font: &Font{Size: MaxFontSize + 1}}) assert.EqualError(t, err, "font size must be between 1 and 409 points") + + // new numeric custom style + fmt := "####;####" + f.Styles.NumFmts = nil + styleID, err = f.NewStyle(&Style{ + CustomNumFmt: &fmt, + }) + assert.NoError(t, err) + assert.Equal(t, 4, styleID) + + assert.NotNil(t, f.Styles) + assert.NotNil(t, f.Styles.CellXfs) + assert.NotNil(t, f.Styles.CellXfs.Xf) + + nf := f.Styles.CellXfs.Xf[styleID] + assert.Equal(t, 164, *nf.NumFmtID) + + // new currency custom style + f.Styles.NumFmts = nil + styleID, err = f.NewStyle(&Style{ + Lang: "ko-kr", + NumFmt: 32, // must not be in currencyNumFmt + + }) + assert.NoError(t, err) + assert.Equal(t, 5, styleID) + + assert.NotNil(t, f.Styles) + assert.NotNil(t, f.Styles.CellXfs) + assert.NotNil(t, f.Styles.CellXfs.Xf) + + nf = f.Styles.CellXfs.Xf[styleID] + assert.Equal(t, 32, *nf.NumFmtID) } func TestGetDefaultFont(t *testing.T) { From 41cef9edc56bb96df1b5190e6abbcf6d23d87e28 Mon Sep 17 00:00:00 2001 From: xuri Date: Sun, 4 Oct 2020 19:59:10 +0800 Subject: [PATCH 10/11] Resolve code review issue for PR #703 --- cell.go | 22 +++++++++------------- cell_test.go | 8 ++++++-- go.sum | 16 ++++------------ rows_test.go | 32 ++++++-------------------------- styles_test.go | 7 ++++--- templates.go | 2 +- test/DateFormats.xlsx | Bin 5065 -> 0 bytes test/NumberFormats.xlsx | Bin 8634 -> 0 bytes 8 files changed, 30 insertions(+), 57 deletions(-) delete mode 100644 test/DateFormats.xlsx delete mode 100644 test/NumberFormats.xlsx diff --git a/cell.go b/cell.go index 05275f1b7a..11c6836ee6 100644 --- a/cell.go +++ b/cell.go @@ -161,10 +161,7 @@ func setCellTime(value time.Time) (t string, b string, isNum bool, err error) { if err != nil { return } - isNum = excelTime > 0 - fmt.Println("setCellTime", value, excelTime, isNum) - if isNum { t, b = setCellDefault(strconv.FormatFloat(excelTime, 'f', -1, 64)) } else { @@ -765,23 +762,22 @@ func (f *File) formattedValue(s int, v string) string { return v } styleSheet := f.stylesReader() - if s > len(styleSheet.CellXfs.Xf) { + if s >= len(styleSheet.CellXfs.Xf) { return v } numFmtId := *styleSheet.CellXfs.Xf[s].NumFmtID ok := builtInNumFmtFunc[numFmtId] if ok != nil { return ok(v, builtInNumFmt[numFmtId]) - } else { - for _, xlsxFmt := range styleSheet.NumFmts.NumFmt { - if xlsxFmt.NumFmtID == numFmtId { - format := strings.ToLower(xlsxFmt.FormatCode) - if strings.Contains(format, "y") || strings.Contains(format, "m") || strings.Contains(format, "d") || strings.Contains(format, "h") { - return parseTime(v, format) - } - - return v + } + for _, xlsxFmt := range styleSheet.NumFmts.NumFmt { + if xlsxFmt.NumFmtID == numFmtId { + format := strings.ToLower(xlsxFmt.FormatCode) + if strings.Contains(format, "y") || strings.Contains(format, "m") || strings.Contains(format, "d") || strings.Contains(format, "h") { + return parseTime(v, format) } + + return v } } return v diff --git a/cell_test.go b/cell_test.go index 0e30b05662..a855344b76 100644 --- a/cell_test.go +++ b/cell_test.go @@ -292,7 +292,11 @@ func TestFormattedValue(t *testing.T) { v = f.formattedValue(1, "43528") assert.Equal(t, "43528", v) - - v = f.formattedValue(2, "43528") + customNumFmt := "[$-409]MM/DD/YYYY" + _, err := f.NewStyle(&Style{ + CustomNumFmt: &customNumFmt, + }) + assert.NoError(t, err) + v = f.formattedValue(1, "43528") assert.Equal(t, "03/04/2019", v) } diff --git a/go.sum b/go.sum index 5b50aa1452..e082e86359 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,7 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/richardlehane/mscfb v1.0.3 h1:rD8TBkYWkObWO0oLDFCbwMeZ4KoalxQy+QgniCj3nKI= @@ -23,11 +17,11 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/image v0.0.0-20200801110659-972c09e46d76 h1:U7GPaoQyQmX+CBRWXKrvRzWTbd+slqeSh8uARsIyhAw= -golang.org/x/image v0.0.0-20200801110659-972c09e46d76/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20200922025426-e59bae62ef32 h1:E+SEVulmY8U4+i6vSB88YSc2OKAFfvbHPU/uDTdQu7M= +golang.org/x/image v0.0.0-20200922025426-e59bae62ef32/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA= +golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -37,7 +31,5 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/rows_test.go b/rows_test.go index a33b9c13dd..246233ffd7 100644 --- a/rows_test.go +++ b/rows_test.go @@ -857,28 +857,24 @@ func TestCheckRow(t *testing.T) { } func TestNumberFormats(t *testing.T) { - xlsx, err := OpenFile(filepath.Join("test", "NumberFormats.xlsx")) + f, err := OpenFile(filepath.Join("test", "Book1.xlsx")) if !assert.NoError(t, err) { t.FailNow() } - cells := make([][]string, 0) - rows, err := xlsx.Rows("numbers") + cols, err := f.Cols("Sheet2") if !assert.NoError(t, err) { t.FailNow() } - - for rows.Next() { - row, err := rows.Columns() + for cols.Next() { + col, err := cols.Rows() assert.NoError(t, err) if err != nil { break } - - cells = append(cells, row) + cells = append(cells, col) } - - assert.Equal(t, []string{"BKR", "4.69", "0", "0.01", "1.6", "19.2"}, cells[6]) + assert.Equal(t, []string{"", "200", "450", "200", "510", "315", "127", "89", "348", "53", "37"}, cells[3]) } func BenchmarkRows(b *testing.B) { @@ -896,22 +892,6 @@ func BenchmarkRows(b *testing.B) { } } -func BenchmarkDateFormats(b *testing.B) { - f, _ := OpenFile(filepath.Join("test", "DateFormats.xlsx")) - for i := 0; i < b.N; i++ { - rows, err := f.Rows("test") - assert.NoError(b, err) - for rows.Next() { - row, _ := rows.Columns() - for i := range row { - if i >= 0 { - continue - } - } - } - } -} - func trimSliceSpace(s []string) []string { for { if len(s) > 0 && s[len(s)-1] == "" { diff --git a/styles_test.go b/styles_test.go index 9994d91a30..8ce26a4e7b 100644 --- a/styles_test.go +++ b/styles_test.go @@ -196,7 +196,7 @@ func TestNewStyle(t *testing.T) { fontID := styles.CellXfs.Xf[styleID].FontID font := styles.Fonts.Font[*fontID] assert.Contains(t, *font.Name.Val, "Times New Roman", "Stored font should contain font name") - assert.Equal(t, 4, styles.CellXfs.Count, "Should have 4 styles") + assert.Equal(t, 2, styles.CellXfs.Count, "Should have 2 styles") _, err = f.NewStyle(&Style{}) assert.NoError(t, err) _, err = f.NewStyle(Style{}) @@ -214,7 +214,7 @@ func TestNewStyle(t *testing.T) { CustomNumFmt: &fmt, }) assert.NoError(t, err) - assert.Equal(t, 4, styleID) + assert.Equal(t, 2, styleID) assert.NotNil(t, f.Styles) assert.NotNil(t, f.Styles.CellXfs) @@ -231,7 +231,7 @@ func TestNewStyle(t *testing.T) { }) assert.NoError(t, err) - assert.Equal(t, 5, styleID) + assert.Equal(t, 3, styleID) assert.NotNil(t, f.Styles) assert.NotNil(t, f.Styles.CellXfs) @@ -290,6 +290,7 @@ func TestParseTime(t *testing.T) { assert.Equal(t, "43528", parseTime("43528", "")) assert.Equal(t, "2019-03-04 05:05:42", parseTime("43528.2123", "YYYY-MM-DD hh:mm:ss")) + assert.Equal(t, "2019-03-04 05:05:42", parseTime("43528.2123", "YYYY-MM-DD hh:mm:ss;YYYY-MM-DD hh:mm:ss")) assert.Equal(t, "3/4/2019 5:5:42", parseTime("43528.2123", "M/D/YYYY h:m:s")) assert.Equal(t, "March", parseTime("43528", "mmmm")) assert.Equal(t, "Monday", parseTime("43528", "dddd")) diff --git a/templates.go b/templates.go index b4dd54fdb5..5721150ce8 100644 --- a/templates.go +++ b/templates.go @@ -29,7 +29,7 @@ const templateContentTypes = `` -const templateStyles = `` +const templateStyles = `` const templateSheet = `` diff --git a/test/DateFormats.xlsx b/test/DateFormats.xlsx deleted file mode 100644 index 8416e821161569363ae5b68ddc3698ff98c8787e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5065 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 OzU0v2<8h%rfd2p%vy9gO diff --git a/test/NumberFormats.xlsx b/test/NumberFormats.xlsx deleted file mode 100644 index ec1adb954bc0bf0711f4aec05662aa69b3629ffc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8634 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 From 48047a685e914377f2881a06a1a699b6b39967de Mon Sep 17 00:00:00 2001 From: xuri Date: Sun, 4 Oct 2020 20:08:50 +0800 Subject: [PATCH 11/11] Rename broken file name generated by unit test --- crypt_test.go | 2 +- excelize_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crypt_test.go b/crypt_test.go index c6acb38ba8..f9a3fb7a6f 100644 --- a/crypt_test.go +++ b/crypt_test.go @@ -19,5 +19,5 @@ import ( func TestEncrypt(t *testing.T) { f, err := OpenFile(filepath.Join("test", "encryptSHA1.xlsx"), Options{Password: "password"}) assert.NoError(t, err) - assert.EqualError(t, f.SaveAs(filepath.Join("test", "TestEncrypt.xlsx"), Options{Password: "password"}), "not support encryption currently") + assert.EqualError(t, f.SaveAs(filepath.Join("test", "BadEncrypt.xlsx"), Options{Password: "password"}), "not support encryption currently") } diff --git a/excelize_test.go b/excelize_test.go index 47c87fc324..890bcf61e6 100644 --- a/excelize_test.go +++ b/excelize_test.go @@ -257,7 +257,7 @@ func TestBrokenFile(t *testing.T) { t.Run("SaveAsEmptyStruct", func(t *testing.T) { // Test write file with broken file struct with given path. - assert.NoError(t, f.SaveAs(filepath.Join("test", "TestBrokenFile.SaveAsEmptyStruct.xlsx"))) + assert.NoError(t, f.SaveAs(filepath.Join("test", "BadWorkbook.SaveAsEmptyStruct.xlsx"))) }) t.Run("OpenBadWorkbook", func(t *testing.T) {