forked from p30928647/excelize
extend cell value load to support custom datetime format (#703)
* extend cell value load to support custom datetime format * cleanup incorrect imports * fix numeric values conversion as done in legacy Excel * fix tests coverage * revert temporary package name fix * remove personal info from test XLSX files * remove unused dependencies * update format conversion in parseTime * new UT to increase code coverage * Resolve code review issue for PR #703 * Rename broken file name generated by unit test Co-authored-by: xuri <xuri.me@gmail.com>
This commit is contained in:
parent
9055a835a8
commit
f2b8798a34
|
@ -1,5 +1,6 @@
|
||||||
~$*.xlsx
|
~$*.xlsx
|
||||||
test/Test*.xlsx
|
test/Test*.xlsx
|
||||||
|
test/Test*.xlsm
|
||||||
*.out
|
*.out
|
||||||
*.test
|
*.test
|
||||||
.idea
|
.idea
|
||||||
|
|
18
cell.go
18
cell.go
|
@ -762,9 +762,23 @@ func (f *File) formattedValue(s int, v string) string {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
styleSheet := f.stylesReader()
|
styleSheet := f.stylesReader()
|
||||||
ok := builtInNumFmtFunc[*styleSheet.CellXfs.Xf[s].NumFmtID]
|
if s >= len(styleSheet.CellXfs.Xf) {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
numFmtId := *styleSheet.CellXfs.Xf[s].NumFmtID
|
||||||
|
ok := builtInNumFmtFunc[numFmtId]
|
||||||
if ok != nil {
|
if ok != nil {
|
||||||
return ok(*styleSheet.CellXfs.Xf[s].NumFmtID, v)
|
return ok(v, builtInNumFmt[numFmtId])
|
||||||
|
}
|
||||||
|
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
|
return v
|
||||||
}
|
}
|
||||||
|
|
36
cell_test.go
36
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"`)
|
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) {
|
func TestSetCellBool(t *testing.T) {
|
||||||
f := NewFile()
|
f := NewFile()
|
||||||
assert.EqualError(t, f.SetCellBool("Sheet1", "A", true), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
assert.EqualError(t, f.SetCellBool("Sheet1", "A", true), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
|
||||||
|
@ -264,3 +281,22 @@ func TestSetCellRichText(t *testing.T) {
|
||||||
// Test set cell rich text with illegal cell coordinates
|
// 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"`)
|
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)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
|
@ -19,5 +19,5 @@ import (
|
||||||
func TestEncrypt(t *testing.T) {
|
func TestEncrypt(t *testing.T) {
|
||||||
f, err := OpenFile(filepath.Join("test", "encryptSHA1.xlsx"), Options{Password: "password"})
|
f, err := OpenFile(filepath.Join("test", "encryptSHA1.xlsx"), Options{Password: "password"})
|
||||||
assert.NoError(t, err)
|
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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ func (f *File) setDefaultTimeStyle(sheet, axis string, format int) error {
|
||||||
}
|
}
|
||||||
if s == 0 {
|
if s == 0 {
|
||||||
style, _ := f.NewStyle(&Style{NumFmt: format})
|
style, _ := f.NewStyle(&Style{NumFmt: format})
|
||||||
_ = f.SetCellStyle(sheet, axis, axis, style)
|
err = f.SetCellStyle(sheet, axis, axis, style)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,7 +257,7 @@ func TestBrokenFile(t *testing.T) {
|
||||||
|
|
||||||
t.Run("SaveAsEmptyStruct", func(t *testing.T) {
|
t.Run("SaveAsEmptyStruct", func(t *testing.T) {
|
||||||
// Test write file with broken file struct with given path.
|
// 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", "BadWorkbook.SaveAsEmptyStruct.xlsx")))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("OpenBadWorkbook", func(t *testing.T) {
|
t.Run("OpenBadWorkbook", func(t *testing.T) {
|
||||||
|
@ -1175,6 +1175,9 @@ func TestSetDefaultTimeStyle(t *testing.T) {
|
||||||
f := NewFile()
|
f := NewFile()
|
||||||
// Test set default time style on not exists worksheet.
|
// Test set default time style on not exists worksheet.
|
||||||
assert.EqualError(t, f.setDefaultTimeStyle("SheetN", "", 0), "sheet SheetN is not exist")
|
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) {
|
func TestAddVBAProject(t *testing.T) {
|
||||||
|
|
2
file.go
2
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 {
|
if err := zw.Close(); err != nil {
|
||||||
return buf, err
|
return buf, err
|
||||||
}
|
}
|
||||||
|
|
19
rows.go
19
rows.go
|
@ -345,6 +345,25 @@ func (xlsx *xlsxC) getValueFrom(f *File, d *xlsxSST) (string, error) {
|
||||||
}
|
}
|
||||||
return f.formattedValue(xlsx.S, xlsx.V), nil
|
return f.formattedValue(xlsx.S, xlsx.V), nil
|
||||||
default:
|
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
|
return f.formattedValue(xlsx.S, xlsx.V), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
37
rows_test.go
37
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")
|
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"}
|
c := &xlsxC{T: "inlineStr"}
|
||||||
f := NewFile()
|
f := NewFile()
|
||||||
d := &xlsxSST{}
|
d := &xlsxSST{}
|
||||||
|
@ -826,6 +826,20 @@ func TestGetValueFrom(t *testing.T) {
|
||||||
assert.Equal(t, "", val)
|
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) {
|
func TestErrSheetNotExistError(t *testing.T) {
|
||||||
err := ErrSheetNotExist{SheetName: "Sheet1"}
|
err := ErrSheetNotExist{SheetName: "Sheet1"}
|
||||||
assert.EqualValues(t, err.Error(), "sheet Sheet1 is not exist")
|
assert.EqualValues(t, err.Error(), "sheet Sheet1 is not exist")
|
||||||
|
@ -842,6 +856,27 @@ func TestCheckRow(t *testing.T) {
|
||||||
assert.EqualError(t, f.SetCellValue("Sheet1", "A1", false), `cannot convert cell "-" to coordinates: invalid cell name "-"`)
|
assert.EqualError(t, f.SetCellValue("Sheet1", "A1", false), `cannot convert cell "-" to coordinates: invalid cell name "-"`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNumberFormats(t *testing.T) {
|
||||||
|
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
cells := make([][]string, 0)
|
||||||
|
cols, err := f.Cols("Sheet2")
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
for cols.Next() {
|
||||||
|
col, err := cols.Rows()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
cells = append(cells, col)
|
||||||
|
}
|
||||||
|
assert.Equal(t, []string{"", "200", "450", "200", "510", "315", "127", "89", "348", "53", "37"}, cells[3])
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkRows(b *testing.B) {
|
func BenchmarkRows(b *testing.B) {
|
||||||
f, _ := OpenFile(filepath.Join("test", "Book1.xlsx"))
|
f, _ := OpenFile(filepath.Join("test", "Book1.xlsx"))
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package excelize_test
|
package excelize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -6,26 +6,24 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/360EntSecGroup-Skylar/excelize/v2"
|
|
||||||
|
|
||||||
"github.com/mohae/deepcopy"
|
"github.com/mohae/deepcopy"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExampleFile_SetPageLayout() {
|
func ExampleFile_SetPageLayout() {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
|
|
||||||
if err := f.SetPageLayout(
|
if err := f.SetPageLayout(
|
||||||
"Sheet1",
|
"Sheet1",
|
||||||
excelize.PageLayoutOrientation(excelize.OrientationLandscape),
|
PageLayoutOrientation(OrientationLandscape),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
if err := f.SetPageLayout(
|
if err := f.SetPageLayout(
|
||||||
"Sheet1",
|
"Sheet1",
|
||||||
excelize.PageLayoutPaperSize(10),
|
PageLayoutPaperSize(10),
|
||||||
excelize.FitToHeight(2),
|
FitToHeight(2),
|
||||||
excelize.FitToWidth(2),
|
FitToWidth(2),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
@ -33,12 +31,12 @@ func ExampleFile_SetPageLayout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleFile_GetPageLayout() {
|
func ExampleFile_GetPageLayout() {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
var (
|
var (
|
||||||
orientation excelize.PageLayoutOrientation
|
orientation PageLayoutOrientation
|
||||||
paperSize excelize.PageLayoutPaperSize
|
paperSize PageLayoutPaperSize
|
||||||
fitToHeight excelize.FitToHeight
|
fitToHeight FitToHeight
|
||||||
fitToWidth excelize.FitToWidth
|
fitToWidth FitToWidth
|
||||||
)
|
)
|
||||||
if err := f.GetPageLayout("Sheet1", &orientation); err != nil {
|
if err := f.GetPageLayout("Sheet1", &orientation); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
@ -67,7 +65,7 @@ func ExampleFile_GetPageLayout() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewSheet(t *testing.T) {
|
func TestNewSheet(t *testing.T) {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
sheetID := f.NewSheet("Sheet2")
|
sheetID := f.NewSheet("Sheet2")
|
||||||
f.SetActiveSheet(sheetID)
|
f.SetActiveSheet(sheetID)
|
||||||
// delete original sheet
|
// delete original sheet
|
||||||
|
@ -76,7 +74,7 @@ func TestNewSheet(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetPane(t *testing.T) {
|
func TestSetPane(t *testing.T) {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
assert.NoError(t, f.SetPanes("Sheet1", `{"freeze":false,"split":false}`))
|
assert.NoError(t, f.SetPanes("Sheet1", `{"freeze":false,"split":false}`))
|
||||||
f.NewSheet("Panes 2")
|
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"}]}`))
|
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"
|
const sheet = "Sheet1"
|
||||||
|
|
||||||
testData := []struct {
|
testData := []struct {
|
||||||
container excelize.PageLayoutOptionPtr
|
container PageLayoutOptionPtr
|
||||||
nonDefault excelize.PageLayoutOption
|
nonDefault PageLayoutOption
|
||||||
}{
|
}{
|
||||||
{new(excelize.PageLayoutOrientation), excelize.PageLayoutOrientation(excelize.OrientationLandscape)},
|
{new(PageLayoutOrientation), PageLayoutOrientation(OrientationLandscape)},
|
||||||
{new(excelize.PageLayoutPaperSize), excelize.PageLayoutPaperSize(10)},
|
{new(PageLayoutPaperSize), PageLayoutPaperSize(10)},
|
||||||
{new(excelize.FitToHeight), excelize.FitToHeight(2)},
|
{new(FitToHeight), FitToHeight(2)},
|
||||||
{new(excelize.FitToWidth), excelize.FitToWidth(2)},
|
{new(FitToWidth), FitToWidth(2)},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range testData {
|
for i, test := range testData {
|
||||||
|
@ -108,11 +106,11 @@ func TestPageLayoutOption(t *testing.T) {
|
||||||
opt := test.nonDefault
|
opt := test.nonDefault
|
||||||
t.Logf("option %T", opt)
|
t.Logf("option %T", opt)
|
||||||
|
|
||||||
def := deepcopy.Copy(test.container).(excelize.PageLayoutOptionPtr)
|
def := deepcopy.Copy(test.container).(PageLayoutOptionPtr)
|
||||||
val1 := deepcopy.Copy(def).(excelize.PageLayoutOptionPtr)
|
val1 := deepcopy.Copy(def).(PageLayoutOptionPtr)
|
||||||
val2 := deepcopy.Copy(def).(excelize.PageLayoutOptionPtr)
|
val2 := deepcopy.Copy(def).(PageLayoutOptionPtr)
|
||||||
|
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
// Get the default value
|
// Get the default value
|
||||||
assert.NoError(t, f.GetPageLayout(sheet, def), opt)
|
assert.NoError(t, f.GetPageLayout(sheet, def), opt)
|
||||||
// Get again and check
|
// Get again and check
|
||||||
|
@ -150,7 +148,7 @@ func TestPageLayoutOption(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSearchSheet(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) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
@ -172,36 +170,36 @@ func TestSearchSheet(t *testing.T) {
|
||||||
assert.EqualValues(t, expected, result)
|
assert.EqualValues(t, expected, result)
|
||||||
|
|
||||||
// Test search worksheet data after set cell value
|
// Test search worksheet data after set cell value
|
||||||
f = excelize.NewFile()
|
f = NewFile()
|
||||||
assert.NoError(t, f.SetCellValue("Sheet1", "A1", true))
|
assert.NoError(t, f.SetCellValue("Sheet1", "A1", true))
|
||||||
_, err = f.SearchSheet("Sheet1", "")
|
_, err = f.SearchSheet("Sheet1", "")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetPageLayout(t *testing.T) {
|
func TestSetPageLayout(t *testing.T) {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
// Test set page layout on not exists worksheet.
|
// Test set page layout on not exists worksheet.
|
||||||
assert.EqualError(t, f.SetPageLayout("SheetN"), "sheet SheetN is not exist")
|
assert.EqualError(t, f.SetPageLayout("SheetN"), "sheet SheetN is not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetPageLayout(t *testing.T) {
|
func TestGetPageLayout(t *testing.T) {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
// Test get page layout on not exists worksheet.
|
// Test get page layout on not exists worksheet.
|
||||||
assert.EqualError(t, f.GetPageLayout("SheetN"), "sheet SheetN is not exist")
|
assert.EqualError(t, f.GetPageLayout("SheetN"), "sheet SheetN is not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetHeaderFooter(t *testing.T) {
|
func TestSetHeaderFooter(t *testing.T) {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
assert.NoError(t, f.SetCellStr("Sheet1", "A1", "Test SetHeaderFooter"))
|
assert.NoError(t, f.SetCellStr("Sheet1", "A1", "Test SetHeaderFooter"))
|
||||||
// Test set header and footer on not exists worksheet.
|
// Test set header and footer on not exists worksheet.
|
||||||
assert.EqualError(t, f.SetHeaderFooter("SheetN", nil), "sheet SheetN is not exist")
|
assert.EqualError(t, f.SetHeaderFooter("SheetN", nil), "sheet SheetN is not exist")
|
||||||
// Test set header and footer with illegal setting.
|
// 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),
|
OddHeader: strings.Repeat("c", 256),
|
||||||
}), "field OddHeader must be less than 255 characters")
|
}), "field OddHeader must be less than 255 characters")
|
||||||
|
|
||||||
assert.NoError(t, f.SetHeaderFooter("Sheet1", nil))
|
assert.NoError(t, f.SetHeaderFooter("Sheet1", nil))
|
||||||
assert.NoError(t, f.SetHeaderFooter("Sheet1", &excelize.FormatHeaderFooter{
|
assert.NoError(t, f.SetHeaderFooter("Sheet1", &FormatHeaderFooter{
|
||||||
DifferentFirst: true,
|
DifferentFirst: true,
|
||||||
DifferentOddEven: true,
|
DifferentOddEven: true,
|
||||||
OddHeader: "&R&P",
|
OddHeader: "&R&P",
|
||||||
|
@ -214,28 +212,28 @@ func TestSetHeaderFooter(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDefinedName(t *testing.T) {
|
func TestDefinedName(t *testing.T) {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
assert.NoError(t, f.SetDefinedName(&excelize.DefinedName{
|
assert.NoError(t, f.SetDefinedName(&DefinedName{
|
||||||
Name: "Amount",
|
Name: "Amount",
|
||||||
RefersTo: "Sheet1!$A$2:$D$5",
|
RefersTo: "Sheet1!$A$2:$D$5",
|
||||||
Comment: "defined name comment",
|
Comment: "defined name comment",
|
||||||
Scope: "Sheet1",
|
Scope: "Sheet1",
|
||||||
}))
|
}))
|
||||||
assert.NoError(t, f.SetDefinedName(&excelize.DefinedName{
|
assert.NoError(t, f.SetDefinedName(&DefinedName{
|
||||||
Name: "Amount",
|
Name: "Amount",
|
||||||
RefersTo: "Sheet1!$A$2:$D$5",
|
RefersTo: "Sheet1!$A$2:$D$5",
|
||||||
Comment: "defined name comment",
|
Comment: "defined name comment",
|
||||||
}))
|
}))
|
||||||
assert.EqualError(t, f.SetDefinedName(&excelize.DefinedName{
|
assert.EqualError(t, f.SetDefinedName(&DefinedName{
|
||||||
Name: "Amount",
|
Name: "Amount",
|
||||||
RefersTo: "Sheet1!$A$2:$D$5",
|
RefersTo: "Sheet1!$A$2:$D$5",
|
||||||
Comment: "defined name comment",
|
Comment: "defined name comment",
|
||||||
}), "the same name already exists on the scope")
|
}), "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",
|
Name: "No Exist Defined Name",
|
||||||
}), "no defined name on the scope")
|
}), "no defined name on the scope")
|
||||||
assert.Exactly(t, "Sheet1!$A$2:$D$5", f.GetDefinedName()[1].RefersTo)
|
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",
|
Name: "Amount",
|
||||||
}))
|
}))
|
||||||
assert.Exactly(t, "Sheet1!$A$2:$D$5", f.GetDefinedName()[0].RefersTo)
|
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) {
|
func TestGroupSheets(t *testing.T) {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
sheets := []string{"Sheet2", "Sheet3"}
|
sheets := []string{"Sheet2", "Sheet3"}
|
||||||
for _, sheet := range sheets {
|
for _, sheet := range sheets {
|
||||||
f.NewSheet(sheet)
|
f.NewSheet(sheet)
|
||||||
|
@ -256,7 +254,7 @@ func TestGroupSheets(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUngroupSheets(t *testing.T) {
|
func TestUngroupSheets(t *testing.T) {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
sheets := []string{"Sheet2", "Sheet3", "Sheet4", "Sheet5"}
|
sheets := []string{"Sheet2", "Sheet3", "Sheet4", "Sheet5"}
|
||||||
for _, sheet := range sheets {
|
for _, sheet := range sheets {
|
||||||
f.NewSheet(sheet)
|
f.NewSheet(sheet)
|
||||||
|
@ -265,7 +263,7 @@ func TestUngroupSheets(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInsertPageBreak(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", "A1"))
|
||||||
assert.NoError(t, f.InsertPageBreak("Sheet1", "B2"))
|
assert.NoError(t, f.InsertPageBreak("Sheet1", "B2"))
|
||||||
assert.NoError(t, f.InsertPageBreak("Sheet1", "C3"))
|
assert.NoError(t, f.InsertPageBreak("Sheet1", "C3"))
|
||||||
|
@ -276,7 +274,7 @@ func TestInsertPageBreak(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRemovePageBreak(t *testing.T) {
|
func TestRemovePageBreak(t *testing.T) {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
assert.NoError(t, f.RemovePageBreak("Sheet1", "A2"))
|
assert.NoError(t, f.RemovePageBreak("Sheet1", "A2"))
|
||||||
|
|
||||||
assert.NoError(t, f.InsertPageBreak("Sheet1", "A2"))
|
assert.NoError(t, f.InsertPageBreak("Sheet1", "A2"))
|
||||||
|
@ -302,7 +300,7 @@ func TestRemovePageBreak(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetSheetName(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, "Sheet1", f.GetSheetName(0))
|
||||||
assert.Equal(t, "Sheet2", f.GetSheetName(1))
|
assert.Equal(t, "Sheet2", f.GetSheetName(1))
|
||||||
assert.Equal(t, "", f.GetSheetName(-1))
|
assert.Equal(t, "", f.GetSheetName(-1))
|
||||||
|
@ -314,7 +312,7 @@ func TestGetSheetMap(t *testing.T) {
|
||||||
1: "Sheet1",
|
1: "Sheet1",
|
||||||
2: "Sheet2",
|
2: "Sheet2",
|
||||||
}
|
}
|
||||||
f, _ := excelize.OpenFile(filepath.Join("test", "Book1.xlsx"))
|
f, _ := OpenFile(filepath.Join("test", "Book1.xlsx"))
|
||||||
sheetMap := f.GetSheetMap()
|
sheetMap := f.GetSheetMap()
|
||||||
for idx, name := range sheetMap {
|
for idx, name := range sheetMap {
|
||||||
assert.Equal(t, expectedMap[idx], name)
|
assert.Equal(t, expectedMap[idx], name)
|
||||||
|
|
250
sheetpr_test.go
250
sheetpr_test.go
|
@ -1,4 +1,4 @@
|
||||||
package excelize_test
|
package excelize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -6,39 +6,37 @@ import (
|
||||||
|
|
||||||
"github.com/mohae/deepcopy"
|
"github.com/mohae/deepcopy"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/360EntSecGroup-Skylar/excelize/v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = []excelize.SheetPrOption{
|
var _ = []SheetPrOption{
|
||||||
excelize.CodeName("hello"),
|
CodeName("hello"),
|
||||||
excelize.EnableFormatConditionsCalculation(false),
|
EnableFormatConditionsCalculation(false),
|
||||||
excelize.Published(false),
|
Published(false),
|
||||||
excelize.FitToPage(true),
|
FitToPage(true),
|
||||||
excelize.AutoPageBreaks(true),
|
AutoPageBreaks(true),
|
||||||
excelize.OutlineSummaryBelow(true),
|
OutlineSummaryBelow(true),
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = []excelize.SheetPrOptionPtr{
|
var _ = []SheetPrOptionPtr{
|
||||||
(*excelize.CodeName)(nil),
|
(*CodeName)(nil),
|
||||||
(*excelize.EnableFormatConditionsCalculation)(nil),
|
(*EnableFormatConditionsCalculation)(nil),
|
||||||
(*excelize.Published)(nil),
|
(*Published)(nil),
|
||||||
(*excelize.FitToPage)(nil),
|
(*FitToPage)(nil),
|
||||||
(*excelize.AutoPageBreaks)(nil),
|
(*AutoPageBreaks)(nil),
|
||||||
(*excelize.OutlineSummaryBelow)(nil),
|
(*OutlineSummaryBelow)(nil),
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleFile_SetSheetPrOptions() {
|
func ExampleFile_SetSheetPrOptions() {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
const sheet = "Sheet1"
|
const sheet = "Sheet1"
|
||||||
|
|
||||||
if err := f.SetSheetPrOptions(sheet,
|
if err := f.SetSheetPrOptions(sheet,
|
||||||
excelize.CodeName("code"),
|
CodeName("code"),
|
||||||
excelize.EnableFormatConditionsCalculation(false),
|
EnableFormatConditionsCalculation(false),
|
||||||
excelize.Published(false),
|
Published(false),
|
||||||
excelize.FitToPage(true),
|
FitToPage(true),
|
||||||
excelize.AutoPageBreaks(true),
|
AutoPageBreaks(true),
|
||||||
excelize.OutlineSummaryBelow(false),
|
OutlineSummaryBelow(false),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
@ -46,16 +44,16 @@ func ExampleFile_SetSheetPrOptions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleFile_GetSheetPrOptions() {
|
func ExampleFile_GetSheetPrOptions() {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
const sheet = "Sheet1"
|
const sheet = "Sheet1"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
codeName excelize.CodeName
|
codeName CodeName
|
||||||
enableFormatConditionsCalculation excelize.EnableFormatConditionsCalculation
|
enableFormatConditionsCalculation EnableFormatConditionsCalculation
|
||||||
published excelize.Published
|
published Published
|
||||||
fitToPage excelize.FitToPage
|
fitToPage FitToPage
|
||||||
autoPageBreaks excelize.AutoPageBreaks
|
autoPageBreaks AutoPageBreaks
|
||||||
outlineSummaryBelow excelize.OutlineSummaryBelow
|
outlineSummaryBelow OutlineSummaryBelow
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := f.GetSheetPrOptions(sheet,
|
if err := f.GetSheetPrOptions(sheet,
|
||||||
|
@ -89,15 +87,15 @@ func TestSheetPrOptions(t *testing.T) {
|
||||||
const sheet = "Sheet1"
|
const sheet = "Sheet1"
|
||||||
|
|
||||||
testData := []struct {
|
testData := []struct {
|
||||||
container excelize.SheetPrOptionPtr
|
container SheetPrOptionPtr
|
||||||
nonDefault excelize.SheetPrOption
|
nonDefault SheetPrOption
|
||||||
}{
|
}{
|
||||||
{new(excelize.CodeName), excelize.CodeName("xx")},
|
{new(CodeName), CodeName("xx")},
|
||||||
{new(excelize.EnableFormatConditionsCalculation), excelize.EnableFormatConditionsCalculation(false)},
|
{new(EnableFormatConditionsCalculation), EnableFormatConditionsCalculation(false)},
|
||||||
{new(excelize.Published), excelize.Published(false)},
|
{new(Published), Published(false)},
|
||||||
{new(excelize.FitToPage), excelize.FitToPage(true)},
|
{new(FitToPage), FitToPage(true)},
|
||||||
{new(excelize.AutoPageBreaks), excelize.AutoPageBreaks(true)},
|
{new(AutoPageBreaks), AutoPageBreaks(true)},
|
||||||
{new(excelize.OutlineSummaryBelow), excelize.OutlineSummaryBelow(false)},
|
{new(OutlineSummaryBelow), OutlineSummaryBelow(false)},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range testData {
|
for i, test := range testData {
|
||||||
|
@ -106,11 +104,11 @@ func TestSheetPrOptions(t *testing.T) {
|
||||||
opt := test.nonDefault
|
opt := test.nonDefault
|
||||||
t.Logf("option %T", opt)
|
t.Logf("option %T", opt)
|
||||||
|
|
||||||
def := deepcopy.Copy(test.container).(excelize.SheetPrOptionPtr)
|
def := deepcopy.Copy(test.container).(SheetPrOptionPtr)
|
||||||
val1 := deepcopy.Copy(def).(excelize.SheetPrOptionPtr)
|
val1 := deepcopy.Copy(def).(SheetPrOptionPtr)
|
||||||
val2 := deepcopy.Copy(def).(excelize.SheetPrOptionPtr)
|
val2 := deepcopy.Copy(def).(SheetPrOptionPtr)
|
||||||
|
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
// Get the default value
|
// Get the default value
|
||||||
assert.NoError(t, f.GetSheetPrOptions(sheet, def), opt)
|
assert.NoError(t, f.GetSheetPrOptions(sheet, def), opt)
|
||||||
// Get again and check
|
// Get again and check
|
||||||
|
@ -148,46 +146,46 @@ func TestSheetPrOptions(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetSheetrOptions(t *testing.T) {
|
func TestSetSheetrOptions(t *testing.T) {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
// Test SetSheetrOptions on not exists worksheet.
|
// Test SetSheetrOptions on not exists worksheet.
|
||||||
assert.EqualError(t, f.SetSheetPrOptions("SheetN"), "sheet SheetN is not exist")
|
assert.EqualError(t, f.SetSheetPrOptions("SheetN"), "sheet SheetN is not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetSheetPrOptions(t *testing.T) {
|
func TestGetSheetPrOptions(t *testing.T) {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
// Test GetSheetPrOptions on not exists worksheet.
|
// Test GetSheetPrOptions on not exists worksheet.
|
||||||
assert.EqualError(t, f.GetSheetPrOptions("SheetN"), "sheet SheetN is not exist")
|
assert.EqualError(t, f.GetSheetPrOptions("SheetN"), "sheet SheetN is not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = []excelize.PageMarginsOptions{
|
var _ = []PageMarginsOptions{
|
||||||
excelize.PageMarginBottom(1.0),
|
PageMarginBottom(1.0),
|
||||||
excelize.PageMarginFooter(1.0),
|
PageMarginFooter(1.0),
|
||||||
excelize.PageMarginHeader(1.0),
|
PageMarginHeader(1.0),
|
||||||
excelize.PageMarginLeft(1.0),
|
PageMarginLeft(1.0),
|
||||||
excelize.PageMarginRight(1.0),
|
PageMarginRight(1.0),
|
||||||
excelize.PageMarginTop(1.0),
|
PageMarginTop(1.0),
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = []excelize.PageMarginsOptionsPtr{
|
var _ = []PageMarginsOptionsPtr{
|
||||||
(*excelize.PageMarginBottom)(nil),
|
(*PageMarginBottom)(nil),
|
||||||
(*excelize.PageMarginFooter)(nil),
|
(*PageMarginFooter)(nil),
|
||||||
(*excelize.PageMarginHeader)(nil),
|
(*PageMarginHeader)(nil),
|
||||||
(*excelize.PageMarginLeft)(nil),
|
(*PageMarginLeft)(nil),
|
||||||
(*excelize.PageMarginRight)(nil),
|
(*PageMarginRight)(nil),
|
||||||
(*excelize.PageMarginTop)(nil),
|
(*PageMarginTop)(nil),
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleFile_SetPageMargins() {
|
func ExampleFile_SetPageMargins() {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
const sheet = "Sheet1"
|
const sheet = "Sheet1"
|
||||||
|
|
||||||
if err := f.SetPageMargins(sheet,
|
if err := f.SetPageMargins(sheet,
|
||||||
excelize.PageMarginBottom(1.0),
|
PageMarginBottom(1.0),
|
||||||
excelize.PageMarginFooter(1.0),
|
PageMarginFooter(1.0),
|
||||||
excelize.PageMarginHeader(1.0),
|
PageMarginHeader(1.0),
|
||||||
excelize.PageMarginLeft(1.0),
|
PageMarginLeft(1.0),
|
||||||
excelize.PageMarginRight(1.0),
|
PageMarginRight(1.0),
|
||||||
excelize.PageMarginTop(1.0),
|
PageMarginTop(1.0),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
@ -195,16 +193,16 @@ func ExampleFile_SetPageMargins() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleFile_GetPageMargins() {
|
func ExampleFile_GetPageMargins() {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
const sheet = "Sheet1"
|
const sheet = "Sheet1"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
marginBottom excelize.PageMarginBottom
|
marginBottom PageMarginBottom
|
||||||
marginFooter excelize.PageMarginFooter
|
marginFooter PageMarginFooter
|
||||||
marginHeader excelize.PageMarginHeader
|
marginHeader PageMarginHeader
|
||||||
marginLeft excelize.PageMarginLeft
|
marginLeft PageMarginLeft
|
||||||
marginRight excelize.PageMarginRight
|
marginRight PageMarginRight
|
||||||
marginTop excelize.PageMarginTop
|
marginTop PageMarginTop
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := f.GetPageMargins(sheet,
|
if err := f.GetPageMargins(sheet,
|
||||||
|
@ -238,15 +236,15 @@ func TestPageMarginsOption(t *testing.T) {
|
||||||
const sheet = "Sheet1"
|
const sheet = "Sheet1"
|
||||||
|
|
||||||
testData := []struct {
|
testData := []struct {
|
||||||
container excelize.PageMarginsOptionsPtr
|
container PageMarginsOptionsPtr
|
||||||
nonDefault excelize.PageMarginsOptions
|
nonDefault PageMarginsOptions
|
||||||
}{
|
}{
|
||||||
{new(excelize.PageMarginTop), excelize.PageMarginTop(1.0)},
|
{new(PageMarginTop), PageMarginTop(1.0)},
|
||||||
{new(excelize.PageMarginBottom), excelize.PageMarginBottom(1.0)},
|
{new(PageMarginBottom), PageMarginBottom(1.0)},
|
||||||
{new(excelize.PageMarginLeft), excelize.PageMarginLeft(1.0)},
|
{new(PageMarginLeft), PageMarginLeft(1.0)},
|
||||||
{new(excelize.PageMarginRight), excelize.PageMarginRight(1.0)},
|
{new(PageMarginRight), PageMarginRight(1.0)},
|
||||||
{new(excelize.PageMarginHeader), excelize.PageMarginHeader(1.0)},
|
{new(PageMarginHeader), PageMarginHeader(1.0)},
|
||||||
{new(excelize.PageMarginFooter), excelize.PageMarginFooter(1.0)},
|
{new(PageMarginFooter), PageMarginFooter(1.0)},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range testData {
|
for i, test := range testData {
|
||||||
|
@ -255,11 +253,11 @@ func TestPageMarginsOption(t *testing.T) {
|
||||||
opt := test.nonDefault
|
opt := test.nonDefault
|
||||||
t.Logf("option %T", opt)
|
t.Logf("option %T", opt)
|
||||||
|
|
||||||
def := deepcopy.Copy(test.container).(excelize.PageMarginsOptionsPtr)
|
def := deepcopy.Copy(test.container).(PageMarginsOptionsPtr)
|
||||||
val1 := deepcopy.Copy(def).(excelize.PageMarginsOptionsPtr)
|
val1 := deepcopy.Copy(def).(PageMarginsOptionsPtr)
|
||||||
val2 := deepcopy.Copy(def).(excelize.PageMarginsOptionsPtr)
|
val2 := deepcopy.Copy(def).(PageMarginsOptionsPtr)
|
||||||
|
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
// Get the default value
|
// Get the default value
|
||||||
assert.NoError(t, f.GetPageMargins(sheet, def), opt)
|
assert.NoError(t, f.GetPageMargins(sheet, def), opt)
|
||||||
// Get again and check
|
// Get again and check
|
||||||
|
@ -297,29 +295,29 @@ func TestPageMarginsOption(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetPageMargins(t *testing.T) {
|
func TestSetPageMargins(t *testing.T) {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
// Test set page margins on not exists worksheet.
|
// Test set page margins on not exists worksheet.
|
||||||
assert.EqualError(t, f.SetPageMargins("SheetN"), "sheet SheetN is not exist")
|
assert.EqualError(t, f.SetPageMargins("SheetN"), "sheet SheetN is not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetPageMargins(t *testing.T) {
|
func TestGetPageMargins(t *testing.T) {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
// Test get page margins on not exists worksheet.
|
// Test get page margins on not exists worksheet.
|
||||||
assert.EqualError(t, f.GetPageMargins("SheetN"), "sheet SheetN is not exist")
|
assert.EqualError(t, f.GetPageMargins("SheetN"), "sheet SheetN is not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleFile_SetSheetFormatPr() {
|
func ExampleFile_SetSheetFormatPr() {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
const sheet = "Sheet1"
|
const sheet = "Sheet1"
|
||||||
|
|
||||||
if err := f.SetSheetFormatPr(sheet,
|
if err := f.SetSheetFormatPr(sheet,
|
||||||
excelize.BaseColWidth(1.0),
|
BaseColWidth(1.0),
|
||||||
excelize.DefaultColWidth(1.0),
|
DefaultColWidth(1.0),
|
||||||
excelize.DefaultRowHeight(1.0),
|
DefaultRowHeight(1.0),
|
||||||
excelize.CustomHeight(true),
|
CustomHeight(true),
|
||||||
excelize.ZeroHeight(true),
|
ZeroHeight(true),
|
||||||
excelize.ThickTop(true),
|
ThickTop(true),
|
||||||
excelize.ThickBottom(true),
|
ThickBottom(true),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
@ -327,17 +325,17 @@ func ExampleFile_SetSheetFormatPr() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleFile_GetSheetFormatPr() {
|
func ExampleFile_GetSheetFormatPr() {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
const sheet = "Sheet1"
|
const sheet = "Sheet1"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
baseColWidth excelize.BaseColWidth
|
baseColWidth BaseColWidth
|
||||||
defaultColWidth excelize.DefaultColWidth
|
defaultColWidth DefaultColWidth
|
||||||
defaultRowHeight excelize.DefaultRowHeight
|
defaultRowHeight DefaultRowHeight
|
||||||
customHeight excelize.CustomHeight
|
customHeight CustomHeight
|
||||||
zeroHeight excelize.ZeroHeight
|
zeroHeight ZeroHeight
|
||||||
thickTop excelize.ThickTop
|
thickTop ThickTop
|
||||||
thickBottom excelize.ThickBottom
|
thickBottom ThickBottom
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := f.GetSheetFormatPr(sheet,
|
if err := f.GetSheetFormatPr(sheet,
|
||||||
|
@ -374,16 +372,16 @@ func TestSheetFormatPrOptions(t *testing.T) {
|
||||||
const sheet = "Sheet1"
|
const sheet = "Sheet1"
|
||||||
|
|
||||||
testData := []struct {
|
testData := []struct {
|
||||||
container excelize.SheetFormatPrOptionsPtr
|
container SheetFormatPrOptionsPtr
|
||||||
nonDefault excelize.SheetFormatPrOptions
|
nonDefault SheetFormatPrOptions
|
||||||
}{
|
}{
|
||||||
{new(excelize.BaseColWidth), excelize.BaseColWidth(1.0)},
|
{new(BaseColWidth), BaseColWidth(1.0)},
|
||||||
{new(excelize.DefaultColWidth), excelize.DefaultColWidth(1.0)},
|
{new(DefaultColWidth), DefaultColWidth(1.0)},
|
||||||
{new(excelize.DefaultRowHeight), excelize.DefaultRowHeight(1.0)},
|
{new(DefaultRowHeight), DefaultRowHeight(1.0)},
|
||||||
{new(excelize.CustomHeight), excelize.CustomHeight(true)},
|
{new(CustomHeight), CustomHeight(true)},
|
||||||
{new(excelize.ZeroHeight), excelize.ZeroHeight(true)},
|
{new(ZeroHeight), ZeroHeight(true)},
|
||||||
{new(excelize.ThickTop), excelize.ThickTop(true)},
|
{new(ThickTop), ThickTop(true)},
|
||||||
{new(excelize.ThickBottom), excelize.ThickBottom(true)},
|
{new(ThickBottom), ThickBottom(true)},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range testData {
|
for i, test := range testData {
|
||||||
|
@ -392,11 +390,11 @@ func TestSheetFormatPrOptions(t *testing.T) {
|
||||||
opt := test.nonDefault
|
opt := test.nonDefault
|
||||||
t.Logf("option %T", opt)
|
t.Logf("option %T", opt)
|
||||||
|
|
||||||
def := deepcopy.Copy(test.container).(excelize.SheetFormatPrOptionsPtr)
|
def := deepcopy.Copy(test.container).(SheetFormatPrOptionsPtr)
|
||||||
val1 := deepcopy.Copy(def).(excelize.SheetFormatPrOptionsPtr)
|
val1 := deepcopy.Copy(def).(SheetFormatPrOptionsPtr)
|
||||||
val2 := deepcopy.Copy(def).(excelize.SheetFormatPrOptionsPtr)
|
val2 := deepcopy.Copy(def).(SheetFormatPrOptionsPtr)
|
||||||
|
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
// Get the default value
|
// Get the default value
|
||||||
assert.NoError(t, f.GetSheetFormatPr(sheet, def), opt)
|
assert.NoError(t, f.GetSheetFormatPr(sheet, def), opt)
|
||||||
// Get again and check
|
// Get again and check
|
||||||
|
@ -434,26 +432,26 @@ func TestSheetFormatPrOptions(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetSheetFormatPr(t *testing.T) {
|
func TestSetSheetFormatPr(t *testing.T) {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
assert.NoError(t, f.GetSheetFormatPr("Sheet1"))
|
assert.NoError(t, f.GetSheetFormatPr("Sheet1"))
|
||||||
f.Sheet["xl/worksheets/sheet1.xml"].SheetFormatPr = nil
|
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.
|
// Test set formatting properties on not exists worksheet.
|
||||||
assert.EqualError(t, f.SetSheetFormatPr("SheetN"), "sheet SheetN is not exist")
|
assert.EqualError(t, f.SetSheetFormatPr("SheetN"), "sheet SheetN is not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetSheetFormatPr(t *testing.T) {
|
func TestGetSheetFormatPr(t *testing.T) {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
assert.NoError(t, f.GetSheetFormatPr("Sheet1"))
|
assert.NoError(t, f.GetSheetFormatPr("Sheet1"))
|
||||||
f.Sheet["xl/worksheets/sheet1.xml"].SheetFormatPr = nil
|
f.Sheet["xl/worksheets/sheet1.xml"].SheetFormatPr = nil
|
||||||
var (
|
var (
|
||||||
baseColWidth excelize.BaseColWidth
|
baseColWidth BaseColWidth
|
||||||
defaultColWidth excelize.DefaultColWidth
|
defaultColWidth DefaultColWidth
|
||||||
defaultRowHeight excelize.DefaultRowHeight
|
defaultRowHeight DefaultRowHeight
|
||||||
customHeight excelize.CustomHeight
|
customHeight CustomHeight
|
||||||
zeroHeight excelize.ZeroHeight
|
zeroHeight ZeroHeight
|
||||||
thickTop excelize.ThickTop
|
thickTop ThickTop
|
||||||
thickBottom excelize.ThickBottom
|
thickBottom ThickBottom
|
||||||
)
|
)
|
||||||
assert.NoError(t, f.GetSheetFormatPr("Sheet1",
|
assert.NoError(t, f.GetSheetFormatPr("Sheet1",
|
||||||
&baseColWidth,
|
&baseColWidth,
|
||||||
|
|
|
@ -1,60 +1,58 @@
|
||||||
package excelize_test
|
package excelize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/360EntSecGroup-Skylar/excelize/v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = []excelize.SheetViewOption{
|
var _ = []SheetViewOption{
|
||||||
excelize.DefaultGridColor(true),
|
DefaultGridColor(true),
|
||||||
excelize.RightToLeft(false),
|
RightToLeft(false),
|
||||||
excelize.ShowFormulas(false),
|
ShowFormulas(false),
|
||||||
excelize.ShowGridLines(true),
|
ShowGridLines(true),
|
||||||
excelize.ShowRowColHeaders(true),
|
ShowRowColHeaders(true),
|
||||||
excelize.TopLeftCell("B2"),
|
TopLeftCell("B2"),
|
||||||
// SheetViewOptionPtr are also SheetViewOption
|
// SheetViewOptionPtr are also SheetViewOption
|
||||||
new(excelize.DefaultGridColor),
|
new(DefaultGridColor),
|
||||||
new(excelize.RightToLeft),
|
new(RightToLeft),
|
||||||
new(excelize.ShowFormulas),
|
new(ShowFormulas),
|
||||||
new(excelize.ShowGridLines),
|
new(ShowGridLines),
|
||||||
new(excelize.ShowRowColHeaders),
|
new(ShowRowColHeaders),
|
||||||
new(excelize.TopLeftCell),
|
new(TopLeftCell),
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = []excelize.SheetViewOptionPtr{
|
var _ = []SheetViewOptionPtr{
|
||||||
(*excelize.DefaultGridColor)(nil),
|
(*DefaultGridColor)(nil),
|
||||||
(*excelize.RightToLeft)(nil),
|
(*RightToLeft)(nil),
|
||||||
(*excelize.ShowFormulas)(nil),
|
(*ShowFormulas)(nil),
|
||||||
(*excelize.ShowGridLines)(nil),
|
(*ShowGridLines)(nil),
|
||||||
(*excelize.ShowRowColHeaders)(nil),
|
(*ShowRowColHeaders)(nil),
|
||||||
(*excelize.TopLeftCell)(nil),
|
(*TopLeftCell)(nil),
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleFile_SetSheetViewOptions() {
|
func ExampleFile_SetSheetViewOptions() {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
const sheet = "Sheet1"
|
const sheet = "Sheet1"
|
||||||
|
|
||||||
if err := f.SetSheetViewOptions(sheet, 0,
|
if err := f.SetSheetViewOptions(sheet, 0,
|
||||||
excelize.DefaultGridColor(false),
|
DefaultGridColor(false),
|
||||||
excelize.RightToLeft(false),
|
RightToLeft(false),
|
||||||
excelize.ShowFormulas(true),
|
ShowFormulas(true),
|
||||||
excelize.ShowGridLines(true),
|
ShowGridLines(true),
|
||||||
excelize.ShowRowColHeaders(true),
|
ShowRowColHeaders(true),
|
||||||
excelize.ZoomScale(80),
|
ZoomScale(80),
|
||||||
excelize.TopLeftCell("C3"),
|
TopLeftCell("C3"),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var zoomScale excelize.ZoomScale
|
var zoomScale ZoomScale
|
||||||
fmt.Println("Default:")
|
fmt.Println("Default:")
|
||||||
fmt.Println("- zoomScale: 80")
|
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)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +63,7 @@ func ExampleFile_SetSheetViewOptions() {
|
||||||
fmt.Println("Used out of range value:")
|
fmt.Println("Used out of range value:")
|
||||||
fmt.Println("- zoomScale:", zoomScale)
|
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)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,18 +85,18 @@ func ExampleFile_SetSheetViewOptions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleFile_GetSheetViewOptions() {
|
func ExampleFile_GetSheetViewOptions() {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
const sheet = "Sheet1"
|
const sheet = "Sheet1"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
defaultGridColor excelize.DefaultGridColor
|
defaultGridColor DefaultGridColor
|
||||||
rightToLeft excelize.RightToLeft
|
rightToLeft RightToLeft
|
||||||
showFormulas excelize.ShowFormulas
|
showFormulas ShowFormulas
|
||||||
showGridLines excelize.ShowGridLines
|
showGridLines ShowGridLines
|
||||||
showZeros excelize.ShowZeros
|
showZeros ShowZeros
|
||||||
showRowColHeaders excelize.ShowRowColHeaders
|
showRowColHeaders ShowRowColHeaders
|
||||||
zoomScale excelize.ZoomScale
|
zoomScale ZoomScale
|
||||||
topLeftCell excelize.TopLeftCell
|
topLeftCell TopLeftCell
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := f.GetSheetViewOptions(sheet, 0,
|
if err := f.GetSheetViewOptions(sheet, 0,
|
||||||
|
@ -124,7 +122,7 @@ func ExampleFile_GetSheetViewOptions() {
|
||||||
fmt.Println("- zoomScale:", zoomScale)
|
fmt.Println("- zoomScale:", zoomScale)
|
||||||
fmt.Println("- topLeftCell:", `"`+topLeftCell+`"`)
|
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)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +130,7 @@ func ExampleFile_GetSheetViewOptions() {
|
||||||
fmt.Println(err)
|
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)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +138,7 @@ func ExampleFile_GetSheetViewOptions() {
|
||||||
fmt.Println(err)
|
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)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +168,7 @@ func ExampleFile_GetSheetViewOptions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSheetViewOptionsErrors(t *testing.T) {
|
func TestSheetViewOptionsErrors(t *testing.T) {
|
||||||
f := excelize.NewFile()
|
f := NewFile()
|
||||||
const sheet = "Sheet1"
|
const sheet = "Sheet1"
|
||||||
|
|
||||||
assert.NoError(t, f.GetSheetViewOptions(sheet, 0))
|
assert.NoError(t, f.GetSheetViewOptions(sheet, 0))
|
||||||
|
|
104
styles.go
104
styles.go
|
@ -21,6 +21,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
@ -755,7 +756,7 @@ var currencyNumFmt = map[int]string{
|
||||||
|
|
||||||
// builtInNumFmtFunc defined the format conversion functions map. Partial format
|
// builtInNumFmtFunc defined the format conversion functions map. Partial format
|
||||||
// code doesn't support currently and will return original string.
|
// 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,
|
0: formatToString,
|
||||||
1: formatToInt,
|
1: formatToInt,
|
||||||
2: formatToFloat,
|
2: formatToFloat,
|
||||||
|
@ -847,14 +848,14 @@ var criteriaType = map[string]string{
|
||||||
|
|
||||||
// formatToString provides a function to return original string by given
|
// formatToString provides a function to return original string by given
|
||||||
// built-in number formats code and cell string.
|
// built-in number formats code and cell string.
|
||||||
func formatToString(i int, v string) string {
|
func formatToString(v string, format string) string {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
// formatToInt provides a function to convert original string to integer
|
// formatToInt provides a function to convert original string to integer
|
||||||
// format as string type by given built-in number formats code and cell
|
// format as string type by given built-in number formats code and cell
|
||||||
// string.
|
// string.
|
||||||
func formatToInt(i int, v string) string {
|
func formatToInt(v string, format string) string {
|
||||||
f, err := strconv.ParseFloat(v, 64)
|
f, err := strconv.ParseFloat(v, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return v
|
return v
|
||||||
|
@ -865,7 +866,7 @@ func formatToInt(i int, v string) string {
|
||||||
// formatToFloat provides a function to convert original string to float
|
// formatToFloat provides a function to convert original string to float
|
||||||
// format as string type by given built-in number formats code and cell
|
// format as string type by given built-in number formats code and cell
|
||||||
// string.
|
// string.
|
||||||
func formatToFloat(i int, v string) string {
|
func formatToFloat(v string, format string) string {
|
||||||
f, err := strconv.ParseFloat(v, 64)
|
f, err := strconv.ParseFloat(v, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return v
|
return v
|
||||||
|
@ -875,7 +876,7 @@ func formatToFloat(i int, v string) string {
|
||||||
|
|
||||||
// formatToA provides a function to convert original string to special format
|
// formatToA provides a function to convert original string to special format
|
||||||
// as string type by given built-in number formats code and cell string.
|
// 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)
|
f, err := strconv.ParseFloat(v, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return v
|
return v
|
||||||
|
@ -890,7 +891,7 @@ func formatToA(i int, v string) string {
|
||||||
|
|
||||||
// formatToB provides a function to convert original string to special format
|
// formatToB provides a function to convert original string to special format
|
||||||
// as string type by given built-in number formats code and cell string.
|
// 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)
|
f, err := strconv.ParseFloat(v, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return v
|
return v
|
||||||
|
@ -903,7 +904,7 @@ func formatToB(i int, v string) string {
|
||||||
|
|
||||||
// formatToC provides a function to convert original string to special format
|
// formatToC provides a function to convert original string to special format
|
||||||
// as string type by given built-in number formats code and cell string.
|
// 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)
|
f, err := strconv.ParseFloat(v, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return v
|
return v
|
||||||
|
@ -914,7 +915,7 @@ func formatToC(i int, v string) string {
|
||||||
|
|
||||||
// formatToD provides a function to convert original string to special format
|
// formatToD provides a function to convert original string to special format
|
||||||
// as string type by given built-in number formats code and cell string.
|
// 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)
|
f, err := strconv.ParseFloat(v, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return v
|
return v
|
||||||
|
@ -925,7 +926,7 @@ func formatToD(i int, v string) string {
|
||||||
|
|
||||||
// formatToE provides a function to convert original string to special format
|
// formatToE provides a function to convert original string to special format
|
||||||
// as string type by given built-in number formats code and cell string.
|
// 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)
|
f, err := strconv.ParseFloat(v, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return v
|
return v
|
||||||
|
@ -933,6 +934,8 @@ func formatToE(i int, v string) string {
|
||||||
return fmt.Sprintf("%.e", f)
|
return fmt.Sprintf("%.e", f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var dateTimeFormatsCache = map[string]string{}
|
||||||
|
|
||||||
// parseTime provides a function to returns a string parsed using time.Time.
|
// parseTime provides a function to returns a string parsed using time.Time.
|
||||||
// Replace Excel placeholders with Go time placeholders. For example, replace
|
// 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
|
// yyyy with 2006. These are in a specific order, due to the fact that m is
|
||||||
|
@ -944,15 +947,46 @@ func formatToE(i int, v string) string {
|
||||||
// arbitrary characters unused in Excel Date formats, and then at the end,
|
// arbitrary characters unused in Excel Date formats, and then at the end,
|
||||||
// turn them to what they should actually be. Based off:
|
// turn them to what they should actually be. Based off:
|
||||||
// http://www.ozgrid.com/Excel/CustomFormats.htm
|
// http://www.ozgrid.com/Excel/CustomFormats.htm
|
||||||
func parseTime(i int, v string) string {
|
func parseTime(v string, format string) string {
|
||||||
f, err := strconv.ParseFloat(v, 64)
|
var (
|
||||||
|
f float64
|
||||||
|
err error
|
||||||
|
goFmt string
|
||||||
|
)
|
||||||
|
f, err = strconv.ParseFloat(v, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
val := timeFromExcelTime(f, false)
|
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, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// use only first variant
|
||||||
|
if strings.Contains(goFmt, ";") {
|
||||||
|
goFmt = goFmt[:strings.IndexByte(goFmt, ';')]
|
||||||
|
}
|
||||||
|
|
||||||
replacements := []struct{ xltime, gotime string }{
|
replacements := []struct{ xltime, gotime string }{
|
||||||
|
{"YYYY", "2006"},
|
||||||
|
{"YY", "06"},
|
||||||
|
{"MM", "01"},
|
||||||
|
{"M", "1"},
|
||||||
|
{"DD", "02"},
|
||||||
|
{"D", "2"},
|
||||||
{"yyyy", "2006"},
|
{"yyyy", "2006"},
|
||||||
{"yy", "06"},
|
{"yy", "06"},
|
||||||
{"mmmm", "%%%%"},
|
{"mmmm", "%%%%"},
|
||||||
|
@ -962,38 +996,59 @@ func parseTime(i int, v string) string {
|
||||||
{"mmm", "Jan"},
|
{"mmm", "Jan"},
|
||||||
{"mmss", "0405"},
|
{"mmss", "0405"},
|
||||||
{"ss", "05"},
|
{"ss", "05"},
|
||||||
|
{"s", "5"},
|
||||||
{"mm:", "04:"},
|
{"mm:", "04:"},
|
||||||
{":mm", ":04"},
|
{":mm", ":04"},
|
||||||
|
{"m:", "4:"},
|
||||||
|
{":m", ":4"},
|
||||||
{"mm", "01"},
|
{"mm", "01"},
|
||||||
{"am/pm", "pm"},
|
{"am/pm", "pm"},
|
||||||
{"m/", "1/"},
|
{"m/", "1/"},
|
||||||
{"%%%%", "January"},
|
{"%%%%", "January"},
|
||||||
{"&&&&", "Monday"},
|
{"&&&&", "Monday"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
replacementsGlobal := []struct{ xltime, gotime string }{
|
||||||
|
{"\\-", "-"},
|
||||||
|
{"\\ ", " "},
|
||||||
|
{"\\.", "."},
|
||||||
|
{"\\", ""},
|
||||||
|
}
|
||||||
// It is the presence of the "am/pm" indicator that determines if this is
|
// 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.
|
// a 12 hour or 24 hours time format, not the number of 'h' characters.
|
||||||
if is12HourTime(format) {
|
if is12HourTime(format) {
|
||||||
format = strings.Replace(format, "hh", "03", 1)
|
goFmt = strings.Replace(goFmt, "hh", "3", 1)
|
||||||
format = strings.Replace(format, "h", "3", 1)
|
goFmt = strings.Replace(goFmt, "h", "3", 1)
|
||||||
|
goFmt = strings.Replace(goFmt, "HH", "3", 1)
|
||||||
|
goFmt = strings.Replace(goFmt, "H", "3", 1)
|
||||||
} else {
|
} else {
|
||||||
format = strings.Replace(format, "hh", "15", 1)
|
goFmt = strings.Replace(goFmt, "hh", "15", 1)
|
||||||
format = strings.Replace(format, "h", "15", 1)
|
goFmt = strings.Replace(goFmt, "h", "3", 1)
|
||||||
|
goFmt = strings.Replace(goFmt, "HH", "15", 1)
|
||||||
|
goFmt = strings.Replace(goFmt, "H", "3", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, repl := range replacements {
|
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
|
// If the hour is optional, strip it out, along with the possible dangling
|
||||||
// colon that would remain.
|
// colon that would remain.
|
||||||
if val.Hour() < 1 {
|
if val.Hour() < 1 {
|
||||||
format = strings.Replace(format, "]:", "]", 1)
|
goFmt = strings.Replace(goFmt, "]:", "]", 1)
|
||||||
format = strings.Replace(format, "[03]", "", 1)
|
goFmt = strings.Replace(goFmt, "[03]", "", 1)
|
||||||
format = strings.Replace(format, "[3]", "", 1)
|
goFmt = strings.Replace(goFmt, "[3]", "", 1)
|
||||||
format = strings.Replace(format, "[15]", "", 1)
|
goFmt = strings.Replace(goFmt, "[15]", "", 1)
|
||||||
} else {
|
} else {
|
||||||
format = strings.Replace(format, "[3]", "3", 1)
|
goFmt = strings.Replace(goFmt, "[3]", "3", 1)
|
||||||
format = strings.Replace(format, "[15]", "15", 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.
|
// is12HourTime checks whether an Excel time format string is a 12 hours form.
|
||||||
|
@ -2226,6 +2281,7 @@ func newNumFmt(styleSheet *xlsxStyleSheet, style *Style) int {
|
||||||
// setCustomNumFmt provides a function to set custom number format code.
|
// setCustomNumFmt provides a function to set custom number format code.
|
||||||
func setCustomNumFmt(styleSheet *xlsxStyleSheet, style *Style) int {
|
func setCustomNumFmt(styleSheet *xlsxStyleSheet, style *Style) int {
|
||||||
nf := xlsxNumFmt{FormatCode: *style.CustomNumFmt}
|
nf := xlsxNumFmt{FormatCode: *style.CustomNumFmt}
|
||||||
|
|
||||||
if styleSheet.NumFmts != nil {
|
if styleSheet.NumFmts != nil {
|
||||||
nf.NumFmtID = styleSheet.NumFmts.NumFmt[len(styleSheet.NumFmts.NumFmt)-1].NumFmtID + 1
|
nf.NumFmtID = styleSheet.NumFmts.NumFmt[len(styleSheet.NumFmts.NumFmt)-1].NumFmtID + 1
|
||||||
styleSheet.NumFmts.NumFmt = append(styleSheet.NumFmts.NumFmt, &nf)
|
styleSheet.NumFmts.NumFmt = append(styleSheet.NumFmts.NumFmt, &nf)
|
||||||
|
|
|
@ -201,10 +201,44 @@ func TestNewStyle(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
_, err = f.NewStyle(Style{})
|
_, err = f.NewStyle(Style{})
|
||||||
assert.EqualError(t, err, "invalid parameter type")
|
assert.EqualError(t, err, "invalid parameter type")
|
||||||
|
|
||||||
_, err = f.NewStyle(&Style{Font: &Font{Family: strings.Repeat("s", MaxFontFamilyLength+1)}})
|
_, 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")
|
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}})
|
_, err = f.NewStyle(&Style{Font: &Font{Size: MaxFontSize + 1}})
|
||||||
assert.EqualError(t, err, "font size must be between 1 and 409 points")
|
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, 2, 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, 3, 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) {
|
func TestGetDefaultFont(t *testing.T) {
|
||||||
|
@ -250,3 +284,15 @@ func TestGetStyleID(t *testing.T) {
|
||||||
func TestGetFillID(t *testing.T) {
|
func TestGetFillID(t *testing.T) {
|
||||||
assert.Equal(t, -1, getFillID(NewFile().stylesReader(), &Style{Fill: Fill{Type: "unknown"}}))
|
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, "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"))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue