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

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条有效数据,但报表中对应表格始终无数据展示、显示为空。

根因分析

代码存在两个核心错误导致数据加载失败:

  1. 变量作用域错误:len和count都是fetch事件内的局部变量。BIRT脚本数据集的fetch方法每读取一行就会调用一次,每次调用都会重新执行count = 0的初始化逻辑,导致遍历指针永远无法向后推进,甚至会触发死循环被BIRT中断执行,最终无法渲染数据。
  2. 初始化逻辑位置错误:遍历计数器、数组长度这类只需要初始化一次的全局遍历状态,不能放在fetch事件中重复执行,否则状态会被反复重置。
  3. 额外注意:如果两个表格在报表中为同层级元素,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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:57:24