Fixed parsing decimal precision issue

pull/2/head
xuri 3 years ago
parent f87c39c41d
commit 07be993631
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7

@ -1082,23 +1082,23 @@ func (f *File) getCellStringFunc(sheet, axis string, fn func(x *xlsxWorksheet, c
// it is possible to apply a format to the cell value, it will do so, if not
// then an error will be returned, along with the raw value of the cell.
func (f *File) formattedValue(s int, v string, raw bool) string {
if raw {
return v
}
precise := v
isNum, precision := isNumeric(v)
if isNum && precision > 10 {
precise = roundPrecision(v, -1)
if isNum {
if precision > 15 {
precise = roundPrecision(v, 15)
}
if raw {
return v
if precision <= 15 {
precise = roundPrecision(v, -1)
}
if !isNum {
v = roundPrecision(v, 15)
precise = v
}
if s == 0 {
return precise
}
styleSheet := f.stylesReader()
if s >= len(styleSheet.CellXfs.Xf) {
return precise
}
@ -1116,7 +1116,7 @@ func (f *File) formattedValue(s int, v string, raw bool) string {
}
for _, xlsxFmt := range styleSheet.NumFmts.NumFmt {
if xlsxFmt.NumFmtID == numFmtID {
return format(v, xlsxFmt.FormatCode)
return format(precise, xlsxFmt.FormatCode)
}
}
return precise

@ -130,7 +130,7 @@ func TestSetCellFloat(t *testing.T) {
assert.Equal(t, "123", val, "A1 should be 123")
val, err = f.GetCellValue(sheet, "A2")
assert.NoError(t, err)
assert.Equal(t, "123.0", val, "A2 should be 123.0")
assert.Equal(t, "123", val, "A2 should be 123")
})
t.Run("with a decimal and precision limit", func(t *testing.T) {
@ -288,12 +288,14 @@ func TestGetCellValue(t *testing.T) {
<c r="S1"><v>275.39999999999998</v></c>
<c r="T1"><v>68.900000000000006</v></c>
<c r="U1"><v>8.8880000000000001E-2</v></c>
<c r="V1"><v>4.0000000000000003E-5</v></c>
<c r="V1"><v>4.0000000000000003e-5</v></c>
<c r="W1"><v>2422.3000000000002</v></c>
<c r="X1"><v>1101.5999999999999</v></c>
<c r="Y1"><v>275.39999999999998</v></c>
<c r="Z1"><v>68.900000000000006</v></c>
<c r="AA1"><v>1.1000000000000001</v></c>
<c r="AA2"><v>1234567890123_4</v></c>
<c r="AA3"><v>123456789_0123_4</v></c>
</row>`)))
f.checked = nil
rows, err = f.GetRows("Sheet1")
@ -325,6 +327,8 @@ func TestGetCellValue(t *testing.T) {
"275.4",
"68.9",
"1.1",
"1234567890123_4",
"123456789_0123_4",
}}, rows)
assert.NoError(t, err)
}

@ -675,22 +675,27 @@ func (f *File) addSheetNameSpace(sheet string, ns xml.Attr) {
// isNumeric determines whether an expression is a valid numeric type and get
// the precision for the numeric.
func isNumeric(s string) (bool, int) {
dot, n, p := false, false, 0
dot, e, n, p := false, false, false, 0
for i, v := range s {
if v == '.' {
if dot {
return false, 0
}
dot = true
} else if v == 'E' || v == 'e' {
e = true
} else if v < '0' || v > '9' {
if i == 0 && v == '-' {
continue
}
if e && v == '-' {
continue
}
return false, 0
} else if dot {
n = true
p++
}
n = true
}
return n, p
}

@ -20,6 +20,7 @@ import (
"github.com/xuri/nfp"
)
// languageInfo defined the required fields of localization support for number format.
type languageInfo struct {
apFmt string
tags []string
@ -191,17 +192,18 @@ func format(value, numFmt string) string {
if section.Type != nf.valueSectionType {
continue
}
if nf.isNumberic {
switch section.Type {
case nfp.TokenSectionPositive:
return nf.positiveHandler()
case nfp.TokenSectionNegative:
return nf.negativeHandler()
case nfp.TokenSectionZero:
return nf.zeroHandler()
default:
return nf.textHandler()
return nf.zeroHandler()
}
}
return nf.textHandler()
}
return value
}
@ -211,12 +213,12 @@ func (nf *numberFormat) positiveHandler() (result string) {
nf.t, nf.hours, nf.seconds = timeFromExcelTime(nf.number, false), false, false
for i, token := range nf.section[nf.sectionIdx].Items {
if inStrSlice(supportedTokenTypes, token.TType, true) == -1 || token.TType == nfp.TokenTypeGeneral {
result = fmt.Sprint(nf.number)
result = nf.value
return
}
if token.TType == nfp.TokenTypeCurrencyLanguage {
if err := nf.currencyLanguageHandler(i, token); err != nil {
result = fmt.Sprint(nf.number)
result = nf.value
return
}
}
@ -587,12 +589,12 @@ func (nf *numberFormat) secondsNext(i int) bool {
// negativeHandler will be handling negative selection for a number format
// expression.
func (nf *numberFormat) negativeHandler() string {
return fmt.Sprint(nf.number)
return nf.value
}
// zeroHandler will be handling zero selection for a number format expression.
func (nf *numberFormat) zeroHandler() string {
return fmt.Sprint(nf.number)
return nf.value
}
// textHandler will be handling text selection for a number format expression.

Loading…
Cancel
Save