在Jsreport中使用JavaScript计算对象行与列总计的问题
解决Jsreport中行与列总计的计算问题
行总计的修复
你的行总计计算出错,核心原因是模板上下文被内部的each切换了。当你在{{#each incidentTypes}}里嵌套{{#each this}}时,内部的this指向的是数组里的单个数值,而非整个行数组,导致total(this)计算的是单个值本身,不是整行的总和。
修改方法很简单:在外层each中给行数组起一个别名,比如row,这样就能在内部调用时明确引用整个行数组:
修正后的辅助函数(函数本身逻辑没问题,加初始值更稳妥)
function total(input) { return input.reduce((acc, value) => acc + value, 0); // 加初始值0,避免空数组报错 }
修正后的模板代码
{{#each incidentTypes as |row|}} <tr> <td>{{@key}}</td> {{#each row}} <td>{{this}}</td> {{/each}} <td>{{total row}}</td> </tr> {{/each}}
列总计的计算
要计算列总计,需要把所有行对应位置的数值累加起来,新增一个辅助函数来生成列总计数组即可:
新增列总计辅助函数
function columnTotals(data) { const rows = Object.values(data); if (rows.length === 0) return []; // 初始化列总计数组,长度和第一行一致 const totals = new Array(rows[0].length).fill(0); // 遍历每一行,累加对应列的数值 rows.forEach(row => { row.forEach((value, index) => { totals[index] += value; }); }); return totals; }
在模板中添加列总计行
在所有行遍历完成后,插入总计行:
<!-- 列总计行 --> <tr> <td>总计</td> {{#each (columnTotals incidentTypes)}} <td>{{this}}</td> {{/each}} <!-- 最后一个单元格是所有数值的总和 --> <td>{{total (columnTotals incidentTypes)}}</td> </tr>
这样就能同时得到正确的行总计和列总计了。
内容的提问来源于stack exchange,提问作者Jacob Modiba
相关产品推荐
相关产品推荐

