You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Handlebars访问嵌套对象值?JSReport数据渲染故障排查

问题分析与解决方案

你的核心问题是Java TreeMap序列化后,Handlebars无法读取到itemSalesSummary对象的属性,主要原因集中在Java对象序列化规则、Handlebars遍历逻辑两个层面,以下是具体修复步骤:


1. 先解决Java端序列化问题(最关键)

Java私有字段默认无法被JSON序列化工具(如Jackson)读取,必须为itemSalesSummary添加公开的getter方法,否则JSReport接收的JSON数据里不会包含productName、weekdayMapQty这些属性,Handlebars自然拿不到值。

修正后的Java类:

public class itemSalesSummary {
    private String productCode;
    private String productName;
    private Map<String, Integer> weekdayMapQty;

    // 必须添加以下getter方法
    public String getProductCode() { return productCode; }
    public String getProductName() { return productName; }
    public Map<String, Integer> getWeekdayMapQty() { return weekdayMapQty; }
}

同时确保productCodeMapSummary序列化后的JSON结构符合预期,应该是:

{
  "123": {
    "productCode": "123",
    "productName": "product A",
    "weekdayMapQty": {"Mon":0, "Tue":0, ...}
  },
  "456": {...},
  "subtotal": {...}
}

2. 修正Handlebars遍历代码

方案一:修复原有#each遍历逻辑

添加自定义helper保证星期列的顺序和表头一致,避免Map无序导致列错位:

{{#each productCodeMapSummary}}
{{#xlsxAdd "xl/worksheets/sheet1.xml" "worksheet.sheetData[0].row"}}
    {{#if (isSubtotal @key)}}
        <row>
           <c t="str" ><v></v></c>
           <c t="str" ><v>{{@key}}</v></c>
            {{!-- 按固定顺序遍历星期,匹配表头列 --}}
            {{#each (getWeekdayValues this.weekdayMapQty)}}
                <c t="n" ><v>{{this}}</v></c>
            {{/each}}
       </row>
       {{else}}
       <row>
           <c t="str" ><v>{{@key}}</v></c>
           <c t="str" ><v>{{this.productName}}</v></c>
            {{#each (getWeekdayValues this.weekdayMapQty)}}
                <c t="n" ><v>{{this}}</v></c>
            {{/each}}
       </row>
    {{/if}}
{{/xlsxAdd}}
{{/each}}

// 辅助函数:判断是否为汇总行
Handlebars.registerHelper("isSubtotal", function(key) {
  return key === "subtotal";
});

// 辅助函数:按固定顺序提取星期数值,保证列对应
Handlebars.registerHelper("getWeekdayValues", function(weekdayMap) {
  const order = ["Mon", "Tue", "Wed", "Thur", "Fri", "Sat", "Sun"];
  return order.map(day => weekdayMap[day] || 0);
});

方案二:修复自定义helper的参数错误

你之前的自定义helper参数数量不匹配,导致key变量未定义,修正后:

{{#each productCodeMapSummary}}
{{#xlsxAdd "xl/worksheets/sheet1.xml" "worksheet.sheetData[0].row"}}
    <row>
    {{{printTableContent @key this}}}
   </row>
{{/xlsxAdd}}
{{/each}}

Handlebars.registerHelper("printTableContent", function(key, value) {
   let content = "";
   if(key === "subtotal"){
      content = '<c t="str" ><v></v></c>'
                    +'<c t="str" ><v>'+key+'</v></c>'
   }else{
      content = '<c t="str" ><v>'+key+'</v></c>'
                    +'<c t="str" ><v>'+ value.productName +'</v></c>'
   }
   // 补充星期列
   const order = ["Mon", "Tue", "Wed", "Thur", "Fri", "Sat", "Sun"];
   order.forEach(day => {
       content += `<c t="n" ><v>${value.weekdayMapQty[day] || 0}</v></c>`;
   });
   return new Handlebars.SafeString(content);
});

3. 关键注意点

  • 确认Java端使用的JSON序列化工具(如Jackson)配置正确,没有忽略getter方法。
  • 如果星期顺序仍有问题,Java端可以用LinkedHashMap存储weekdayMapQty,保证遍历顺序固定。
  • 避免使用三重花括号({{{}}})除非需要渲染HTML/XML标签,普通文本用双重花括号即可。

内容的提问来源于stack exchange,提问作者A.T.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 20:33:14