一、核心概念

FreeMarker 是一个基于 Java 的模板引擎,常用于生成 HTML、XML、文本等内容。它支持强大的表达式语言和格式化功能,其中 <#ftl number_formats> 用于控制模板中数字的格式化方式。

1. <#ftl number_formats> 的作用

该指令用于在模板中启用或禁用数字格式化功能。当启用后,FreeMarker 会根据区域设置(locale)和数字格式(number_format)来格式化数字输出。

  • 启用格式化:允许使用 ?string.number?string.currency?string.percent 等格式化方法。
  • 禁用格式化:数字将直接输出原始值,不进行格式转换。

2. 数字格式化的类型

格式类型 用法示例 说明
number ?string.number 通用数字格式(千分位)
currency ?string.currency 货币格式(带货币符号)
percent ?string.percent 百分比格式(乘以100并加%)
custom ?string("0.00") 自定义格式(Java DecimalFormat语法)

🛠️ 二、操作步骤(详细)

✅ 步骤 1:启用数字格式化

在模板顶部使用 <#ftl number_formats> 启用数字格式化:

<#ftl number_formats>

说明:此指令必须放在模板最开始,不能在 <#assign><#if> 等逻辑块中使用。

✅ 步骤 2:设置区域(Locale)

数字格式化依赖区域设置(Locale),可以通过以下方式设置:

<#setting locale="zh_CN">

常见区域设置:

  • en_US:美国英语
  • zh_CN:中文简体
  • de_DE:德语德国

提示:可以在 Java 代码中动态设置 locale,模板中也可通过 <#setting> 临时覆盖。

✅ 步骤 3:使用格式化表达式

示例 1:通用数字格式

<#assign price = 1234567.89>
${price?string.number}  <#-- 输出:1,234,567.89(en_US)或 1,234,567.89(zh_CN) -->

示例 2:货币格式

${price?string.currency}  <#-- 输出:$1,234,567.89(en_US)或 ¥1,234,567.89(zh_CN) -->

示例 3:百分比格式

<#assign rate = 0.75>
${rate?string.percent}  <#-- 输出:75% -->

示例 4:自定义格式

${price?string("0.00")}  <#-- 输出:1234567.89 -->

自定义格式使用 Java 的 DecimalFormat 语法,如:

  • 0.00:保留两位小数
  • #,##0.00:千分位加两位小数
  • 0%:百分比,不乘以100

⚠️ 三、常见错误与注意事项

❌ 错误 1:未启用 <#ftl number_formats>

${price?string.number}  <#-- 报错:Method not found -->

解决方法: 在模板顶部加上 <#ftl number_formats>


❌ 错误 2:格式化字符串语法错误

${price?string("0,000.000")}  <#-- 报错:Illegal pattern character -->

解决方法: 使用正确的 DecimalFormat 语法。


❌ 错误 3:区域设置不正确导致格式混乱

<#setting locale="en_US">
${price?string.currency}  <#-- 输出:$1,234,567.89 -->

如果希望使用中文区域但显示英文格式,需手动指定:

<#setting locale="en_US">

❌ 错误 4:对非数字变量进行格式化

<#assign value = "abc">
${value?string.number}  <#-- 报错:Expecting a number -->

解决方法: 确保变量是数字类型(Double, Integer 等)。


🧠 四、使用技巧

1. 动态切换区域设置

<#if user.lang == "zh">
  <#setting locale="zh_CN">
<#else>
  <#setting locale="en_US">
</#if>

2. 保留两位小数且不显示千分位

${price?string("0.00")}

3. 格式化为百分比但不乘以100

<#assign rate = 75>
${rate?string("0%")}  <#-- 输出:75% -->

4. 处理大数字避免科学计数法

<#assign bigNum = 12345678901234567890>
${bigNum?string("0")}  <#-- 输出:12345678901234567890 -->

🏆 五、最佳实践

实践项 建议
模板头部统一启用 <#ftl number_formats> 放在模板顶部
区域设置统一管理 在 Java 层统一设置 locale,避免模板中频繁切换
使用标准格式优先 优先使用 ?string.number?string.currency 等标准格式
避免硬编码格式字符串 将格式字符串提取为变量或配置
使用自定义格式时谨慎 自定义格式可能在不同区域下显示不一致

🔧 六、性能优化

优化项 说明
避免频繁切换 locale 频繁切换 locale 会影响性能,建议在模板外统一设置
避免嵌套格式化 (${price?string.number}) 可能影响性能,建议直接输出
减少自定义格式使用 自定义格式需要额外解析,影响渲染速度
预处理数字格式 在 Java 中预处理格式化,减少模板中处理逻辑
使用缓存机制 FreeMarker 本身有缓存机制,合理使用可提升性能

📚 七、总结

维度 内容
核心指令 <#ftl number_formats>
格式类型 number, currency, percent, custom
区域设置 <#setting locale="zh_CN">
格式化方法 ?string.number, ?string.currency, ?string.percent, ?string("格式")
注意事项 启用格式化、变量类型、区域设置、格式语法
最佳实践 统一设置、避免硬编码、优先使用标准格式
性能优化 减少 locale 切换、减少自定义格式、预处理数据

📌 附录:常见数字格式示例

原始数字 格式表达式 输出(en_US) 输出(zh_CN)
1234567.89 ?string.number 1,234,567.89 1,234,567.89
1234567.89 ?string.currency $1,234,567.89 ¥1,234,567.89
0.75 ?string.percent 75% 75%
1234567.89 ?string("0.00") 1234567.89 1234567.89
1234567.89 ?string("#,##0.00") 1,234,567.89 1,234,567.89

如需进一步了解 Java DecimalFormat 语法,请参考官方文档:
🔗 Java DecimalFormat 文档


📌 总结一句话:
<#ftl number_formats> 是 FreeMarker 中数字格式化的核心指令,通过启用该功能,结合 locale 设置与格式化表达式,可以实现灵活、本地化的数字输出。掌握其用法和最佳实践,是高效开发 FreeMarker 模板的关键。