You need to enable JavaScript to run this app. 转换为PDF后如何获取Jasper Report中已填充的参数值
优惠活动
大模型
产品
解决方案
定价
更多

转换为PDF后如何获取Jasper Report中已填充的参数值

结论

该需求完全可以实现,针对不同使用场景有两种可落地的方案:

方案一:直接从JasperPrint对象获取参数(单元测试首选)

你现有代码中完成报表填充后生成的JasperPrint对象本身就存储了所有填充时传入的参数,不需要解析PDF字节数组,也不需要修改现有业务逻辑,是单元测试场景下最简便的实现方式。

操作代码

// 你原有代码中的JasperPrint对象
JasperPrint jasperPrint = JasperFillManager
    .fillReport(resourceFile.getInputStream(), parameters, new JREmptyDataSource());

// 直接调用方法获取所有填充用参数
Map<String, Object> filledParams = jasperPrint.getParameters();

// 单元测试断言示例(以JUnit 5为例)
String actualFullName = (String) filledParams.get("name");
org.junit.jupiter.api.Assertions.assertEquals("张三 李四", actualFullName);

方案二:从PDF字节数组中提取参数(仅适用于只能拿到PDF文件的场景)

如果你的单元测试只能拿到最终生成的PDF字节数组,无法获取JasperPrint对象,可以在导出PDF时把需要校验的参数写入PDF自定义元数据,后续再从PDF中读取元数据即可。

步骤1:修改PDF导出逻辑,写入自定义元数据

改用JRPdfExporter导出PDF,同时把需要校验的参数写入PDF的XMP自定义元数据:

import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.export.SimpleExporterInput;
import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;
import net.sf.jasperreports.export.SimplePdfExporterConfiguration;

// 原有填充逻辑不变
Map<String, Object> parameters = new HashMap<>();
parameters.put("name", (employee.getFirstName() + " " + employee.getLastName()));
JasperPrint jasperPrint = JasperFillManager
    .fillReport(resourceFile.getInputStream(), parameters, new JREmptyDataSource());

// 导出时写入自定义元数据
JRPdfExporter exporter = new JRPdfExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(outputStream));

SimplePdfExporterConfiguration config = new SimplePdfExporterConfiguration();
// 写入自定义参数到元数据,前缀可自定义,避免和系统元数据冲突
config.addXmpMetadataProperty("custom:fullName", (String) parameters.get("name"));
exporter.setConfiguration(config);

exporter.exportReport();
byte[] content = outputStream.toByteArray();

步骤2:单元测试读取PDF元数据

引入PDFBox依赖,读取PDF中的自定义元数据做校验:

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;

// 读取PDF字节数组中的元数据
try (PDDocument pdfDoc = PDDocument.load(content)) {
    PDDocumentInformation docInfo = pdfDoc.getDocumentInformation();
    String actualFullName = docInfo.getCustomMetadataValue("custom:fullName");
    // 执行断言
    org.junit.jupiter.api.Assertions.assertEquals("张三 李四", actualFullName);
}

方案对比

  • 方案一无需修改业务逻辑、无需引入额外依赖,执行效率高,是单元测试场景的首选
  • 方案二仅适用于无法获取JasperPrint对象,只能拿到最终PDF的特殊场景

内容的提问来源于stack exchange,提问作者Hamza Belmellouki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 11:45:04