mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
Merge pull request #15353 from swordqiu/hotfix/qj-excel-output-pretty-float
fix: make excel output floating number pretty
This commit is contained in:
@@ -24,6 +24,8 @@ import (
|
||||
"github.com/360EntSecGroup-Skylar/excelize"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -92,7 +94,13 @@ func exportRow(xlsx *excelize.File, data jsonutils.JSONObject, keys []string, ro
|
||||
val, _ = data.GetIgnoreCases(keys[i])
|
||||
}
|
||||
if val != nil {
|
||||
valStr, _ = val.GetString()
|
||||
// hack, make floating point number prettier
|
||||
if fval, ok := val.(*jsonutils.JSONFloat); ok {
|
||||
f, _ := fval.Float()
|
||||
valStr = stringutils2.PrettyFloat(f, 2)
|
||||
} else {
|
||||
valStr, _ = val.GetString()
|
||||
}
|
||||
}
|
||||
cell := fmt.Sprintf("%s%d", decimal2Alphabet(i), rowIndex)
|
||||
xlsx.SetCellValue(DEFAULT_SHEET, cell, valStr)
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -187,3 +188,49 @@ func FilterEmpty(input []string) []string {
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func PrettyFloat(f float64, precision int) string {
|
||||
fstr := strconv.FormatFloat(f, 'f', -1, 64)
|
||||
dotPos := strings.Index(fstr, ".")
|
||||
if dotPos < 0 {
|
||||
return fstr
|
||||
}
|
||||
neg := false
|
||||
if fstr[0] == '-' {
|
||||
neg = true
|
||||
fstr = fstr[1:]
|
||||
dotPos -= 1
|
||||
}
|
||||
numPart, _ := strconv.ParseInt(fstr[:dotPos], 10, 64)
|
||||
prePartStr := fstr[dotPos+1:]
|
||||
if numPart == 0 {
|
||||
nonZeroPos := 0
|
||||
for prePartStr[nonZeroPos] == '0' {
|
||||
nonZeroPos += 1
|
||||
}
|
||||
precision += nonZeroPos
|
||||
}
|
||||
if precision < len(prePartStr) {
|
||||
prePart, _ := strconv.ParseInt(prePartStr[:precision], 10, 64)
|
||||
if prePartStr[precision] > '4' {
|
||||
// rounding up
|
||||
prePart += 1
|
||||
}
|
||||
prePartStr = fmt.Sprintf(fmt.Sprintf("%%.%dd", precision), prePart)
|
||||
if len(prePartStr) > precision {
|
||||
prePartStr = prePartStr[1:]
|
||||
numPart += 1
|
||||
}
|
||||
}
|
||||
for len(prePartStr) > 0 && prePartStr[len(prePartStr)-1] == '0' {
|
||||
prePartStr = prePartStr[0 : len(prePartStr)-1]
|
||||
}
|
||||
ret := strconv.FormatInt(numPart, 10)
|
||||
if len(prePartStr) > 0 {
|
||||
ret += "." + prePartStr
|
||||
}
|
||||
if neg {
|
||||
ret = "-" + ret
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ package stringutils2
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -211,3 +212,73 @@ func TestFilterEmpty(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrettyFloat(t *testing.T) {
|
||||
cases := []struct {
|
||||
in float64
|
||||
prec int
|
||||
want string
|
||||
}{
|
||||
{
|
||||
in: 3.1415926,
|
||||
prec: 2,
|
||||
want: "3.14",
|
||||
},
|
||||
{
|
||||
in: 3.1415926,
|
||||
prec: 3,
|
||||
want: "3.142",
|
||||
},
|
||||
{
|
||||
in: 3.89999999,
|
||||
prec: 2,
|
||||
want: "3.9",
|
||||
},
|
||||
{
|
||||
in: 3.88999999,
|
||||
prec: 2,
|
||||
want: "3.89",
|
||||
},
|
||||
{
|
||||
in: 3.99999999,
|
||||
prec: 2,
|
||||
want: "4",
|
||||
},
|
||||
{
|
||||
in: 0.000020000001,
|
||||
prec: 2,
|
||||
want: "0.00002",
|
||||
},
|
||||
{
|
||||
in: 0.000021000001,
|
||||
prec: 2,
|
||||
want: "0.000021",
|
||||
},
|
||||
{
|
||||
in: 0.000021100001,
|
||||
prec: 2,
|
||||
want: "0.000021",
|
||||
},
|
||||
{
|
||||
in: -3.15,
|
||||
prec: 1,
|
||||
want: "-3.2",
|
||||
},
|
||||
{
|
||||
in: 3.5,
|
||||
prec: 0,
|
||||
want: "4",
|
||||
},
|
||||
{
|
||||
in: 0.999999999999,
|
||||
prec: 2,
|
||||
want: "1",
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
got := PrettyFloat(c.in, c.prec)
|
||||
if got != c.want {
|
||||
t.Errorf("%s precision %d want %s got %s", strconv.FormatFloat(c.in, 'f', -1, 64), c.prec, c.want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user