BIRT报表解析PostgreSQL JSON列数据填充表格为空问题
问题描述
现有PostgreSQL数据表,部分业务信息存储在JSON类型列中,需要提取该JSON列的数据填充BIRT报表内的第二张表格。
目前已成功将数据解析为可正常调用的JSON对象,但绑定该JSON数据源的第二张表格始终无法填充任何数据,已确认JSON对象内存在有效数据。
现有数据源配置:
- DataSource1绑定基于PostgreSQL的DataSet1
- DataSource2为脚本数据源(Scripted DS),绑定已预先定义好列结构的DataSet2
DataSet1的OnFetch事件中编写代码生成JSON数组:
vars["invoiceData"] = JSON.parse(row["i_invoice"]);
用于处理JSON数据的DataSet2的fetch事件中逻辑如下:
// Get the length of the object len = vars["invoiceData"].labor.length; count = 0;// Counter used to step through each item in the JSON object. // Loop through the JSON object adding it to the scripted data source if(count < len && len != 0) { row["hrs"] = vars["invoiceData"].labor[count].hrs; row["desc"] = vars["invoiceData"].labor[count].desc; row["rate"] = vars["invoiceData"].labor[count].rate; row["amount"] = vars["invoiceData"].labor[count].amount; count++; return true; } return false;
经输出校验,目标数组长度为1,确实存在1条有效数据,但报表中对应表格始终无数据展示、显示为空。
根因分析
代码存在两个核心错误导致数据加载失败:
- 变量作用域错误:
len和count都是fetch事件内的局部变量。BIRT脚本数据集的fetch方法每读取一行就会调用一次,每次调用都会重新执行count = 0的初始化逻辑,导致遍历指针永远无法向后推进,甚至会触发死循环被BIRT中断执行,最终无法渲染数据。 - 初始化逻辑位置错误:遍历计数器、数组长度这类只需要初始化一次的全局遍历状态,不能放在
fetch事件中重复执行,否则状态会被反复重置。 - 额外注意:如果两个表格在报表中为同层级元素,BIRT会按照元素从上到下的顺序执行,若DataSet2绑定的表格位置在DataSet1绑定的表格之前,DataSet2取数时
vars["invoiceData"]还未被赋值,也会导致读不到数据。
修复步骤
1. 在DataSet2的open事件中添加初始化逻辑
open事件只会在数据集开始取数前执行一次,适合做一次性的状态初始化:
// 把待遍历的数组、总长度、计数器都存入全局vars,避免被fetch事件重置 vars["laborList"] = vars["invoiceData"].labor; vars["laborTotalLen"] = vars["laborList"].length; vars["laborIndex"] = 0;
2. 重写DataSet2的fetch事件逻辑
删除fetch事件内的初始化代码,直接读取全局状态完成遍历:
const currentIndex = vars["laborIndex"]; if (currentIndex < vars["laborTotalLen"]) { const currentLaborItem = vars["laborList"][currentIndex]; row["hrs"] = currentLaborItem.hrs; row["desc"] = currentLaborItem.desc; row["rate"] = currentLaborItem.rate; row["amount"] = currentLaborItem.amount; // 计数器自增后存回全局变量 vars["laborIndex"] = currentIndex + 1; return true; } // 所有数据遍历完成后返回false,终止取数 return false;
3. 校验元素执行顺序(无数据时补充检查)
如果修改代码后表格仍然为空,打开BIRT报表的XML源码,确认DataSet1绑定的表格在XML中的节点顺序早于DataSet2绑定的表格,保证主表的JSON解析逻辑先执行、全局变量赋值完成后,子表再开始取数。
内容的提问来源于stack exchange,提问作者jfreak53
相关产品推荐
相关产品推荐

