This roundup time value when a millisecond great than 500 to fix the accuracy issue
- Correction example in the documentation of set cell formula - Rename the internal function `parseOptions` to `getOptions` - Update unit tests
This commit is contained in:
parent
4f0025aab0
commit
917e6e19d6
2
calc.go
2
calc.go
|
@ -769,7 +769,7 @@ type formulaFuncs struct {
|
||||||
// ZTEST
|
// ZTEST
|
||||||
func (f *File) CalcCellValue(sheet, cell string, opts ...Options) (result string, err error) {
|
func (f *File) CalcCellValue(sheet, cell string, opts ...Options) (result string, err error) {
|
||||||
var (
|
var (
|
||||||
rawCellValue = parseOptions(opts...).RawCellValue
|
rawCellValue = getOptions(opts...).RawCellValue
|
||||||
styleIdx int
|
styleIdx int
|
||||||
token formulaArg
|
token formulaArg
|
||||||
)
|
)
|
||||||
|
|
10
cell.go
10
cell.go
|
@ -71,7 +71,7 @@ func (f *File) GetCellValue(sheet, cell string, opts ...Options) (string, error)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", true, err
|
return "", true, err
|
||||||
}
|
}
|
||||||
val, err := c.getValueFrom(f, sst, parseOptions(opts...).RawCellValue)
|
val, err := c.getValueFrom(f, sst, getOptions(opts...).RawCellValue)
|
||||||
return val, true, err
|
return val, true, err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -640,12 +640,12 @@ type FormulaOpts struct {
|
||||||
//
|
//
|
||||||
// err := f.SetCellFormula("Sheet1", "A3", "=SUM(A1,B1)")
|
// err := f.SetCellFormula("Sheet1", "A3", "=SUM(A1,B1)")
|
||||||
//
|
//
|
||||||
// Example 2, set one-dimensional vertical constant array (row array) formula
|
// Example 2, set one-dimensional vertical constant array (column array) formula
|
||||||
// "1,2,3" for the cell "A3" on "Sheet1":
|
// "1,2,3" for the cell "A3" on "Sheet1":
|
||||||
//
|
//
|
||||||
// err := f.SetCellFormula("Sheet1", "A3", "={1,2,3}")
|
// err := f.SetCellFormula("Sheet1", "A3", "={1;2;3}")
|
||||||
//
|
//
|
||||||
// Example 3, set one-dimensional horizontal constant array (column array)
|
// Example 3, set one-dimensional horizontal constant array (row array)
|
||||||
// formula '"a","b","c"' for the cell "A3" on "Sheet1":
|
// formula '"a","b","c"' for the cell "A3" on "Sheet1":
|
||||||
//
|
//
|
||||||
// err := f.SetCellFormula("Sheet1", "A3", "={\"a\",\"b\",\"c\"}")
|
// err := f.SetCellFormula("Sheet1", "A3", "={\"a\",\"b\",\"c\"}")
|
||||||
|
@ -654,7 +654,7 @@ type FormulaOpts struct {
|
||||||
// the cell "A3" on "Sheet1":
|
// the cell "A3" on "Sheet1":
|
||||||
//
|
//
|
||||||
// formulaType, ref := excelize.STCellFormulaTypeArray, "A3:A3"
|
// formulaType, ref := excelize.STCellFormulaTypeArray, "A3:A3"
|
||||||
// err := f.SetCellFormula("Sheet1", "A3", "={1,2,\"a\",\"b\"}",
|
// err := f.SetCellFormula("Sheet1", "A3", "={1,2;\"a\",\"b\"}",
|
||||||
// excelize.FormulaOpts{Ref: &ref, Type: &formulaType})
|
// excelize.FormulaOpts{Ref: &ref, Type: &formulaType})
|
||||||
//
|
//
|
||||||
// Example 5, set range array formula "A1:A2" for the cell "A3" on "Sheet1":
|
// Example 5, set range array formula "A1:A2" for the cell "A3" on "Sheet1":
|
||||||
|
|
2
col.go
2
col.go
|
@ -92,7 +92,7 @@ func (cols *Cols) Rows(opts ...Options) ([]string, error) {
|
||||||
if cols.stashCol >= cols.curCol {
|
if cols.stashCol >= cols.curCol {
|
||||||
return rowIterator.cells, rowIterator.err
|
return rowIterator.cells, rowIterator.err
|
||||||
}
|
}
|
||||||
cols.rawCellValue = parseOptions(opts...).RawCellValue
|
cols.rawCellValue = getOptions(opts...).RawCellValue
|
||||||
if cols.sst, rowIterator.err = cols.f.sharedStringsReader(); rowIterator.err != nil {
|
if cols.sst, rowIterator.err = cols.f.sharedStringsReader(); rowIterator.err != nil {
|
||||||
return rowIterator.cells, rowIterator.err
|
return rowIterator.cells, rowIterator.err
|
||||||
}
|
}
|
||||||
|
|
6
date.go
6
date.go
|
@ -156,7 +156,11 @@ func timeFromExcelTime(excelTime float64, date1904 bool) time.Time {
|
||||||
date = excel1900Epoc
|
date = excel1900Epoc
|
||||||
}
|
}
|
||||||
durationPart := time.Duration(nanosInADay * floatPart)
|
durationPart := time.Duration(nanosInADay * floatPart)
|
||||||
return date.AddDate(0, 0, wholeDaysPart).Add(durationPart).Truncate(time.Second)
|
date = date.AddDate(0, 0, wholeDaysPart).Add(durationPart)
|
||||||
|
if date.Nanosecond()/1e6 > 500 {
|
||||||
|
return date.Round(time.Second)
|
||||||
|
}
|
||||||
|
return date.Truncate(time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExcelDateToTime converts a float-based excel date representation to a time.Time.
|
// ExcelDateToTime converts a float-based excel date representation to a time.Time.
|
||||||
|
|
|
@ -161,7 +161,7 @@ func OpenReader(r io.Reader, opts ...Options) (*File, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
f := newFile()
|
f := newFile()
|
||||||
f.options = parseOptions(opts...)
|
f.options = getOptions(opts...)
|
||||||
if err = f.checkOpenReaderOptions(); err != nil {
|
if err = f.checkOpenReaderOptions(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -198,9 +198,9 @@ func OpenReader(r io.Reader, opts ...Options) (*File, error) {
|
||||||
return f, err
|
return f, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseOptions provides a function to parse the optional settings for open
|
// getOptions provides a function to parse the optional settings for open
|
||||||
// and reading spreadsheet.
|
// and reading spreadsheet.
|
||||||
func parseOptions(opts ...Options) *Options {
|
func getOptions(opts ...Options) *Options {
|
||||||
options := &Options{}
|
options := &Options{}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
options = &opt
|
options = &opt
|
||||||
|
|
|
@ -49,9 +49,9 @@ func TestNumFmt(t *testing.T) {
|
||||||
{"43543.086539351854", "AM/PM hh:mm:ss a/p", "AM 02:04:37 a"},
|
{"43543.086539351854", "AM/PM hh:mm:ss a/p", "AM 02:04:37 a"},
|
||||||
{"43528", "YYYY", "2019"},
|
{"43528", "YYYY", "2019"},
|
||||||
{"43528", "", "43528"},
|
{"43528", "", "43528"},
|
||||||
{"43528.2123", "YYYY-MM-DD hh:mm:ss", "2019-03-04 05:05:42"},
|
{"43528.2123", "YYYY-MM-DD hh:mm:ss", "2019-03-04 05:05:43"},
|
||||||
{"43528.2123", "YYYY-MM-DD hh:mm:ss;YYYY-MM-DD hh:mm:ss", "2019-03-04 05:05:42"},
|
{"43528.2123", "YYYY-MM-DD hh:mm:ss;YYYY-MM-DD hh:mm:ss", "2019-03-04 05:05:43"},
|
||||||
{"43528.2123", "M/D/YYYY h:m:s", "3/4/2019 5:5:42"},
|
{"43528.2123", "M/D/YYYY h:m:s", "3/4/2019 5:5:43"},
|
||||||
{"43528.003958333335", "m/d/yyyy h:m:s", "3/4/2019 0:5:42"},
|
{"43528.003958333335", "m/d/yyyy h:m:s", "3/4/2019 0:5:42"},
|
||||||
{"43528.003958333335", "M/D/YYYY h:mm:s", "3/4/2019 0:05:42"},
|
{"43528.003958333335", "M/D/YYYY h:mm:s", "3/4/2019 0:05:42"},
|
||||||
{"0.64583333333333337", "h:mm:ss am/pm", "3:30:00 pm"},
|
{"0.64583333333333337", "h:mm:ss am/pm", "3:30:00 pm"},
|
||||||
|
|
2
rows.go
2
rows.go
|
@ -138,7 +138,7 @@ func (rows *Rows) Columns(opts ...Options) ([]string, error) {
|
||||||
}
|
}
|
||||||
var rowIterator rowXMLIterator
|
var rowIterator rowXMLIterator
|
||||||
var token xml.Token
|
var token xml.Token
|
||||||
rows.rawCellValue = parseOptions(opts...).RawCellValue
|
rows.rawCellValue = getOptions(opts...).RawCellValue
|
||||||
if rows.sst, rowIterator.err = rows.f.sharedStringsReader(); rowIterator.err != nil {
|
if rows.sst, rowIterator.err = rows.f.sharedStringsReader(); rowIterator.err != nil {
|
||||||
return rowIterator.cells, rowIterator.err
|
return rowIterator.cells, rowIterator.err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1052,6 +1052,8 @@ func TestNumberFormats(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
numFmt10, err := f.NewStyle(&Style{NumFmt: 10})
|
numFmt10, err := f.NewStyle(&Style{NumFmt: 10})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
numFmt21, err := f.NewStyle(&Style{NumFmt: 21})
|
||||||
|
assert.NoError(t, err)
|
||||||
numFmt37, err := f.NewStyle(&Style{NumFmt: 37})
|
numFmt37, err := f.NewStyle(&Style{NumFmt: 37})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
numFmt38, err := f.NewStyle(&Style{NumFmt: 38})
|
numFmt38, err := f.NewStyle(&Style{NumFmt: 38})
|
||||||
|
@ -1093,6 +1095,9 @@ func TestNumberFormats(t *testing.T) {
|
||||||
{"A30", numFmt40, -8.8888666665555493e+19, "(88,888,666,665,555,500,000.00)"},
|
{"A30", numFmt40, -8.8888666665555493e+19, "(88,888,666,665,555,500,000.00)"},
|
||||||
{"A31", numFmt40, 8.8888666665555487, "8.89 "},
|
{"A31", numFmt40, 8.8888666665555487, "8.89 "},
|
||||||
{"A32", numFmt40, -8.8888666665555487, "(8.89)"},
|
{"A32", numFmt40, -8.8888666665555487, "(8.89)"},
|
||||||
|
{"A33", numFmt21, 44729.999988368058, "23:59:59"},
|
||||||
|
{"A34", numFmt21, 44944.375005787035, "09:00:00"},
|
||||||
|
{"A35", numFmt21, 44944.375005798611, "09:00:01"},
|
||||||
} {
|
} {
|
||||||
cell, styleID, value, expected := cases[0].(string), cases[1].(int), cases[2], cases[3].(string)
|
cell, styleID, value, expected := cases[0].(string), cases[1].(int), cases[2], cases[3].(string)
|
||||||
assert.NoError(t, f.SetCellStyle("Sheet1", cell, cell, styleID))
|
assert.NoError(t, f.SetCellStyle("Sheet1", cell, cell, styleID))
|
||||||
|
|
Loading…
Reference in New Issue