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 date from 2020/07/16 to 109/07/16
How-To
1. Create custom number format class:
package com.cht.tool.filegenerator.ftl.custom; import freemarker.core.Environment; import freemarker.core.TemplateDateFormat; import freemarker.core.TemplateDateFormatFactory; import freemarker.core.TemplateFormatUtil; import freemarker.core.TemplateValueFormatException; import freemarker.core.UnparsableValueException; import freemarker.template.TemplateDateModel; import freemarker.template.TemplateModelException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.TimeZone; /** * 將西元年轉為民國年 * <p> * 使用方式 ${aDate?string.@mingguo}, 會將 2020/07/16 轉為 109/07/16 */ public class MingGuoTemplateDateFormatFactory extends TemplateDateFormatFactory { public static final MingGuoTemplateDateFormatFactory INSTANCE = new MingGuoTemplateDateFormatFactory(); private MingGuoTemplateDateFormatFactory() { // Defined to decrease visibility } @Override public TemplateDateFormat get(String s, int i, Locale locale, TimeZone timeZone, boolean b, Environment environment) throws TemplateValueFormatException { TemplateFormatUtil.checkHasNoParameters(s); return MingGuoTemplateDateFormat.INSTANCE; } private static class MingGuoTemplateDateFormat extends TemplateDateFormat { public static final MingGuoTemplateDateFormat INSTANCE = new MingGuoTemplateDateFormat(); private MingGuoTemplateDateFormat() { // Defined to decrease visibility } @Override public String formatToPlainText(TemplateDateModel templateDateModel) throws TemplateModelException { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd"); Date date = new Date(TemplateFormatUtil.getNonNullDate(templateDateModel).getTime()); String dateStr = dateFormat.format(date); return (Integer.parseInt(dateStr.substring(0, 4)) - 1911) + dateStr.substring(4); } @Override public Object parse(String s, int i) throws TemplateValueFormatException { try { return new Date(Long.parseLong(s)); } catch (NumberFormatException e) { throw new UnparsableValueException("Malformed long"); } } @Override public boolean isLocaleBound() { return false; } @Override public boolean isTimeZoneBound() { 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 "mingguo" format: Map<String, TemplateDateFormatFactory> customDateFormats = new HashMap<>(); customDateFormats.put("mingguo", MingGuoTemplateDateFormatFactory.INSTANCE); cfg.setCustomDateFormats(customDateFormats);
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