
在 freemarker 模板中,`double` 类型本身不保存小数位数信息,需通过格式化指令显式指定两位小数输出,推荐使用 `${value?string('0.00')}` 实现统一、可靠的数值格式化。
当使用 OpenHTMLToPDF 渲染 PDF 时,常遇到数值字段显示不一致的问题:字符串 "1200.00" 能原样输出,但 Double 类型的 100.00 却被渲染为 100 —— 这并非数据丢失,而是 FreeMarker 默认采用简洁数字格式(如 100.0 → 100),省略了末尾零和小数点。
要强制保留两位小数,必须显式调用内建格式化函数:
${amount?string('0.00')}
${price?string('#,##0.00')} ✅ 关键说明:
- '0.00' 中的 0 表示必显数字位(不足补零),区别于 #(可选位,不补零);
- 此格式对正数、负数、零均生效:0.0 → 0.00,-5 → -5.00;
- 不依赖 Java 层预格式化为字符串,避免类型转换与空值风险(注意:若 amount 为 null,需先判空,如 ${(amount!0)?string('0.00')})。
⚠️ 注意事项:
- 避免使用 ${amount?c}(计算机格式)或默认插值,它们均不保证小数位数;
- 全局统一格式可配置 FreeMarker Configuration 的 setNumberFormat("0.00"),但模板级控制更灵活、可读性更强;
- 若项目中大量使用货币字段,建议定义宏复用:
<#macro money v>${(v!0)?string('0.00')}#macro> <@money v=total />
通过 ?string('0.00'),你能在 OpenHTMLToPDF 输出中稳定获得符合财务/报表要求的两位小数格式,兼顾准确性与专业呈现。










