summaryrefslogtreecommitdiff
path: root/numfmt.go
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2022-03-19 00:05:47 +0800
committerxuri <xuri.me@gmail.com>2022-03-19 00:05:47 +0800
commit94f197c4fe6531f96a42fe4e960c1c921a3ee0e8 (patch)
tree1506b7d9e7584257768843e7723af2208fe6ce20 /numfmt.go
parent14b461420fc3d3b06b01d7b0584b422b3e1b40fb (diff)
This improved formula calculate precision and added zero placeholder number format support
Diffstat (limited to 'numfmt.go')
-rw-r--r--numfmt.go52
1 files changed, 46 insertions, 6 deletions
diff --git a/numfmt.go b/numfmt.go
index 50ce1f3..3b20e02 100644
--- a/numfmt.go
+++ b/numfmt.go
@@ -13,6 +13,7 @@ package excelize
import (
"fmt"
+ "math"
"strconv"
"strings"
"time"
@@ -41,13 +42,15 @@ type numberFormat struct {
var (
// supportedTokenTypes list the supported number format token types currently.
supportedTokenTypes = []string{
+ nfp.TokenSubTypeLanguageInfo,
+ nfp.TokenTypeColor,
nfp.TokenTypeCurrencyLanguage,
nfp.TokenTypeDateTimes,
nfp.TokenTypeElapsedDateTimes,
nfp.TokenTypeGeneral,
nfp.TokenTypeLiteral,
nfp.TokenTypeTextPlaceHolder,
- nfp.TokenSubTypeLanguageInfo,
+ nfp.TokenTypeZeroPlaceHolder,
}
// supportedLanguageInfo directly maps the supported language ID and tags.
supportedLanguageInfo = map[string]languageInfo{
@@ -276,11 +279,9 @@ var (
// prepareNumberic split the number into two before and after parts by a
// decimal point.
func (nf *numberFormat) prepareNumberic(value string) {
- prec := 0
- if nf.isNumberic, prec = isNumeric(value); !nf.isNumberic {
+ if nf.isNumberic, _ = isNumeric(value); !nf.isNumberic {
return
}
- nf.beforePoint, nf.afterPoint = value[:len(value)-prec-1], value[len(value)-prec:]
}
// format provides a function to return a string parse by number format
@@ -336,6 +337,20 @@ func (nf *numberFormat) positiveHandler() (result string) {
nf.result += token.TValue
continue
}
+ if token.TType == nfp.TokenTypeZeroPlaceHolder && token.TValue == "0" {
+ if isNum, precision := isNumeric(nf.value); isNum {
+ if nf.number < 1 {
+ nf.result += "0"
+ continue
+ }
+ if precision > 15 {
+ nf.result += roundPrecision(nf.value, 15)
+ } else {
+ nf.result += fmt.Sprintf("%.f", nf.number)
+ }
+ continue
+ }
+ }
}
result = nf.result
return
@@ -874,8 +889,33 @@ func (nf *numberFormat) secondsNext(i int) bool {
// negativeHandler will be handling negative selection for a number format
// expression.
-func (nf *numberFormat) negativeHandler() string {
- return nf.value
+func (nf *numberFormat) negativeHandler() (result string) {
+ for _, token := range nf.section[nf.sectionIdx].Items {
+ if inStrSlice(supportedTokenTypes, token.TType, true) == -1 || token.TType == nfp.TokenTypeGeneral {
+ result = nf.value
+ return
+ }
+ if token.TType == nfp.TokenTypeLiteral {
+ nf.result += token.TValue
+ continue
+ }
+ if token.TType == nfp.TokenTypeZeroPlaceHolder && token.TValue == "0" {
+ if isNum, precision := isNumeric(nf.value); isNum {
+ if math.Abs(nf.number) < 1 {
+ nf.result += "0"
+ continue
+ }
+ if precision > 15 {
+ nf.result += strings.TrimLeft(roundPrecision(nf.value, 15), "-")
+ } else {
+ nf.result += fmt.Sprintf("%.f", math.Abs(nf.number))
+ }
+ continue
+ }
+ }
+ }
+ result = nf.result
+ return
}
// zeroHandler will be handling zero selection for a number format expression.