FreeMarker/NetSuite PDF模板:含空值的日期双重排序问题
FreeMarker实现多字段二级排序(含空值处理)
为什么你之前的写法无效
?sort_by(['from_date', 'to_date']):FreeMarker的?sort_by只支持单个属性参数,不接受数组,因此这种写法语法错误,无法生效。?sort_by("from_date")?sort_by("to_date"):第二次sort_by会完全基于to_date重新排序,会打乱第一次from_date的排序结果,无法实现“先按from_date排序,再按to_date二次排序”的需求。
正确实现方式:使用?sort_with自定义比较逻辑
FreeMarker的?sort_with允许你自定义比较器函数,实现多字段的层级排序,同时可以灵活处理空值的排序位置。
方案1:精细控制空值排序位置(非空值优先)
<#list invoices?sort_with((a, b) -> { // 第一步:比较from_date if (a.from_date?has_content && b.from_date?has_content) { var fromCompare = a.from_date?compare_to(b.from_date); if (fromCompare != 0) { return fromCompare; } // from_date相等,第二步:比较to_date if (a.to_date?has_content && b.to_date?has_content) { return a.to_date?compare_to(b.to_date); } else if (a.to_date?has_content) { return -1; // 有to_date的记录排前面 } else if (b.to_date?has_content) { return 1; } return 0; } else if (a.from_date?has_content) { return -1; // 有from_date的记录排前面 } else if (b.from_date?has_content) { return 1; } // 两个from_date都为空,直接比较to_date if (a.to_date?has_content && b.to_date?has_content) { return a.to_date?compare_to(b.to_date); } else if (a.to_date?has_content) { return -1; } else if (b.to_date?has_content) { return 1; } return 0; }) as inv> <!-- 表格行渲染逻辑 --> <tr> <td>${inv.from_date?string("yyyy-MM-dd")!""}</td> <td>${inv.to_date?string("yyyy-MM-dd")!""}</td> <!-- 其他列内容 --> </tr> </#list>
方案2:简化空值处理(空值排最后)
如果希望所有空值(from_date或to_date为空)统一排到列表末尾,可以给空值设置一个极大的默认日期,简化比较逻辑:
<#list invoices?sort_with((a, b) -> { // 给空的from_date设置默认极大日期,让空值排最后 var aFrom = a.from_date!new Date(9999, 11, 31); var bFrom = b.from_date!new Date(9999, 11, 31); var fromCompare = aFrom?compare_to(bFrom); if (fromCompare != 0) { return fromCompare; } // from_date相同,给空的to_date设置默认极大日期 var aTo = a.to_date!new Date(9999, 11, 31); var bTo = b.to_date!new Date(9999, 11, 31); return aTo?compare_to(bTo); }) as inv> <!-- 表格行渲染逻辑 --> </#list>
关键说明
?compare_to:FreeMarker日期类型的内置比较方法,返回值为-1(小于)、0(等于)、1(大于)。?has_content:判断字段是否非空(包括不为null、空字符串、空集合等)。!:FreeMarker的默认值运算符,当字段为空时返回指定的默认值(方案2中用它给空日期设置极大值)。
内容的提问来源于stack exchange,提问作者Edgardo
相关产品推荐
相关产品推荐

