Format float in golang html/template

huangapple go评论76阅读模式
英文:

Format float in golang html/template

问题

我想在Go语言的html/template中将float64值格式化为两位小数,比如在index.html文件中。在.go文件中,我可以这样格式化:

strconv.FormatFloat(value, 'f', 2, 32)

但是我不知道如何在模板中进行格式化。我正在使用gin-gonic/gin框架作为后端。任何帮助将不胜感激。谢谢。

英文:

I want to format float64 value to 2 decimal places in golang html/template say in index.html file. In .go file I can format like:

strconv.FormatFloat(value, 'f', 2, 32)

But I don't know how to format it in template. I am using gin-gonic/gin framework for backend. Any help will be appreciated. Thanks.

答案1

得分: 36

你有很多选择:

  • 你可以决定在将数字传递给模板执行之前对其进行格式化,例如使用fmt.Sprintf()n1)。
  • 或者你可以创建自己的类型,在其中定义String() string方法,按照你的喜好进行格式化。模板引擎会检查并使用这个方法(n2)。
  • 你也可以直接在模板中调用printf并使用自定义的格式字符串(n3)。
  • 尽管你可以直接调用printf,但这需要传递格式化的字符串。如果你不想每次都这样做,你可以注册一个自定义函数来完成这个任务(n4)。

看看这个例子:

type MyFloat float64

func (mf MyFloat) String() string {
    return fmt.Sprintf("%.2f", float64(mf))
}

func main() {
    t := template.Must(template.New("").Funcs(template.FuncMap{
        "MyFormat": func(f float64) string { return fmt.Sprintf("%.2f", f) },
    }).Parse(templ))
    m := map[string]interface{}{
        "n0": 3.1415,
        "n1": fmt.Sprintf("%.2f", 3.1415),
        "n2": MyFloat(3.1415),
        "n3": 3.1415,
        "n4": 3.1415,
    }
    if err := t.Execute(os.Stdout, m); err != nil {
        fmt.Println(err)
    }
}

const templ = `
Number:         n0 = {{.n0}}
Formatted:      n1 = {{.n1}}
Custom type:    n2 = {{.n2}}
Calling printf: n3 = {{printf "%.2f" .n3}}
MyFormat:       n4 = {{MyFormat .n4}}`

输出结果(在Go Playground上尝试):

Number:         n0 = 3.1415
Formatted:      n1 = 3.14
Custom type:    n2 = 3.14
Calling printf: n3 = 3.14
MyFormat:       n4 = 3.14
英文:

You have many options:

  • You may decide to format the number e.g. using fmt.Sprintf() before passing it to the template execution (n1)
  • Or you may create your own type where you define the String() string method, formatting to your liking. This is checked and used by the template engine (n2).
  • You may also call printf directly and explicitly from the template and use custom format string (n3).
  • Even though you can call printf directly, this requires to pass the format string. If you don't want to do this every time, you can register a custom function doing just that (n4)

See this example:

type MyFloat float64

func (mf MyFloat) String() string {
	return fmt.Sprintf("%.2f", float64(mf))
}

func main() {
	t := template.Must(template.New("").Funcs(template.FuncMap{
		"MyFormat": func(f float64) string { return fmt.Sprintf("%.2f", f) },
	}).Parse(templ))
	m := map[string]interface{}{
		"n0": 3.1415,
		"n1": fmt.Sprintf("%.2f", 3.1415),
		"n2": MyFloat(3.1415),
		"n3": 3.1415,
		"n4": 3.1415,
	}
	if err := t.Execute(os.Stdout, m); err != nil {
		fmt.Println(err)
	}
}

const templ = `
Number:         n0 = {{.n0}}
Formatted:      n1 = {{.n1}}
Custom type:    n2 = {{.n2}}
Calling printf: n3 = {{printf "%.2f" .n3}}
MyFormat:       n4 = {{MyFormat .n4}}`

Output (try it on the Go Playground):

Number:         n0 = 3.1415
Formatted:      n1 = 3.14
Custom type:    n2 = 3.14
Calling printf: n3 = 3.14
MyFormat:       n4 = 3.14

答案2

得分: 15

使用printf 模板内置函数"%.2f"格式:

tmpl := template.Must(template.New("test").Parse(`The formatted value is = {{printf "%.2f" .}}`))

tmpl.Execute(os.Stdout, 123.456789)

Go Playground

英文:

Use the printf template built-in function with the "%.2f" format:

tmpl := template.Must(template.New("test").Parse(`The formatted value is = {{printf "%.2f" .}}`))

tmpl.Execute(os.Stdout, 123.456789)

Go Playgroung

答案3

得分: 4

你可以注册一个FuncMap

package main

import (
	"fmt"
	"os"
	"text/template"
)

type Tpl struct {
	Value float64
}

func main() {
	funcMap := template.FuncMap{
		"FormatNumber": func(value float64) string {
			return fmt.Sprintf("%.2f", value)
		},
	}

	tmpl, _ := template.New("test").Funcs(funcMap).Parse(string("The formatted value is = {{ .Value | FormatNumber  }}"))

	tmpl.Execute(os.Stdout, Tpl{Value: 123.45678})
}

Playground

英文:

You can register a FuncMap.

package main

import (
	"fmt"
	"os"
	"text/template"
)

type Tpl struct {
	Value float64
}

func main() {
	funcMap := template.FuncMap{
		"FormatNumber": func(value float64) string {
			return fmt.Sprintf("%.2f", value)
		},
	}

	tmpl, _ := template.New("test").Funcs(funcMap).Parse(string("The formatted value is = {{ .Value | FormatNumber  }}"))
	
	tmpl.Execute(os.Stdout, Tpl{Value: 123.45678})
}

Playground

答案4

得分: 1

我错了关于四舍五入/截断的问题。

%.2f 格式化的问题在于它不会四舍五入,而是截断。

我开发了一个基于 int64 的十进制类,用于处理金额,可以处理浮点数、字符串解析、JSON 等。

它将金额存储为以分为单位的 64 位整数。可以轻松地从浮点数创建,或者转换回浮点数。

也很方便存储在数据库中。

https://github.com/strongo/decimal

package example

import "github.com/strongo/decimal"

func Example() {
    var amount decimal.Decimal64p2; print(amount)  // 0

    amount = decimal.NewDecimal64p2(0, 43); print(amount)  // 0.43
    amount = decimal.NewDecimal64p2(1, 43); print(amount)  // 1.43
    amount = decimal.NewDecimal64p2FromFloat64(23.100001); print(amount)  // 23.10
    amount, _ = decimal.ParseDecimal64p2("2.34"); print(amount)  // 2.34
    amount, _ = decimal.ParseDecimal64p2("-3.42"); print(amount)  // -3.42
}

对于我的债务追踪应用程序 https://debtstracker.io/ 很有效。

英文:

Edit: I was wrong about rounding/truncating.

<strike>The problem with %.2f formatting is that it does not round but truncates.</strike>

I've developed a decimal class based on int64 for handling money that is handling floats, string parsing, JSON, etc.

It stores amount as 64 bit integer number of cents. Can be easily created from float or converted back to float.

Handy for storing in DB as well.

https://github.com/strongo/decimal

package example

import &quot;github.com/strongo/decimal&quot;

func Example() {
	var amount decimal.Decimal64p2; print(amount)  // 0
	
	amount = decimal.NewDecimal64p2(0, 43); print(amount)  // 0.43
	amount = decimal.NewDecimal64p2(1, 43); print(amount)  // 1.43
	amount = decimal.NewDecimal64p2FromFloat64(23.100001); print(amount)  // 23.10
	amount, _ = decimal.ParseDecimal64p2(&quot;2.34&quot;); print(amount)  // 2.34
	amount, _ = decimal.ParseDecimal64p2(&quot;-3.42&quot;); print(amount)  // -3.42
}

Works well for my debts tracker app https://debtstracker.io/

huangapple
  • 本文由 发表于 2016年12月15日 16:23:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/41159492.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定