Purpose
FreeMarker allows you to define your own number and date/time/datetime formats, and associate a name to them.
Here has an example to demonstrate how to convert amount from 2380 to NT$2,380.
How-To
1. Create custom number format class:
package com.cht.tool.filegenerator.ftl.custom; import freemarker.core.Environment; import freemarker.core.TemplateFormatUtil; import freemarker.core.TemplateNumberFormat; import freemarker.core.TemplateNumberFormatFactory; import freemarker.core.TemplateValueFormatException; import freemarker.core.UnformattableValueException; import freemarker.template.TemplateModelException; import freemarker.template.TemplateNumberModel; import freemarker.template.utility.NumberUtil; import java.text.DecimalFormat; import java.util.Locale; /** * 將金額加上千分號,並註明新台幣 NT * <p> * 使用方式 ${total?string.@ntd},2380 會被轉換為 NT$2,380 */ public class NTDTemplateNumberFormatFactory extends TemplateNumberFormatFactory { public static final NTDTemplateNumberFormatFactory INSTANCE = new NTDTemplateNumberFormatFactory(); private static DecimalFormat ntdFormat = new DecimalFormat("NT$#,###"); private NTDTemplateNumberFormatFactory() { // Defined to decrease visibility } @Override public TemplateNumberFormat get(String s, Locale locale, Environment environment) throws TemplateValueFormatException { TemplateFormatUtil.checkHasNoParameters(s); return NTDTemplateStringFormat.INSTANCE; } private static class NTDTemplateStringFormat extends TemplateNumberFormat { private static final NTDTemplateStringFormat INSTANCE = new NTDTemplateStringFormat(); private NTDTemplateStringFormat() { // Defined to decrease visibility } /** * 2380 會被轉換為 NT$2,380 的邏輯寫在這裡 * * @param numberModel * @return * @throws TemplateValueFormatException * @throws TemplateModelException */ @Override public String formatToPlainText(TemplateNumberModel numberModel) throws TemplateValueFormatException, TemplateModelException { Number number = TemplateFormatUtil.getNonNullNumber(numberModel); try { return ntdFormat.format(NumberUtil.toIntExact(number)); } catch (RuntimeException e) { throw new UnformattableValueException(number + " - 金額轉換失敗", e); } } @Override public boolean isLocaleBound() { return false; } @Override public String getDescription() { return "數字轉新台幣"; } } }
2. Register to freemarker configuration class:
Configuration cfg = new Configuration(Configuration.getVersion()); cfg.setClassForTemplateLoading(this.getClass(), "/"); // register the "ntd" format: Map<String, TemplateNumberFormatFactory> customNumberFormats = new HashMap<>(); customNumberFormats.put("ntd", NTDTemplateNumberFormatFactory.INSTANCE); cfg.setCustomNumberFormats(customNumberFormats);
3. Use this format in ftl template file:
<#-- 取得現在時間 --> <#assign aDateTime = .now> <#-- 只保留日期 --> <#assign aDate = aDateTime?date> <#-- create the macro variable: --> <#macro printDate mingguodate> 列印日期:${mingguodate} </#macro> <#macro footer records amount> ${"-"?right_pad(25, "-")} 總筆數:${records} 總金額:${amount} </#macro> <#-- call the macro: --> <@printDate mingguodate="${aDate?string.@mingguo}" /> <#assign total = 0> ${"水果名稱"?right_pad(10)}${"單價"?right_pad(10)}${"訂購數量"?right_pad(10)} ${"-"?right_pad(25, "-")} <#list rows as row> <#assign total += row.price * row.quantity> ${row.name?right_pad(10)}${row.price?string.@ntd?left_pad(10)}${row.quantity?left_pad(10)} </#list> <#-- call the macro: --> <@footer records="${rows?size?left_pad(10)}" amount="${total?string.@ntd?left_pad(10)}" />
Reference
No comments:
Post a Comment