导出JasperReports查询结果

6
在我的Java项目中,我有很多包含复杂SQL查询和许多参数的JasperReports报表。这些报表用于生成以各种方式分组和格式化的数据返回的pdf文档。
现在,我还需要直接导出查询结果(例如ResultSet、Map或csv文件等)。是否可以要求JasperReports仅执行查询并返回结果,而不是呈现pdf页面?
(注意:这与选择csv输出格式来呈现报表不同,因为此方法尝试将报表设计转换为csv文件...相反,我只想“重用”报表中的查询,还要利用JR参数管理等...)
以下是我用于从报表生成pdf文档的Java代码:
JasperReport report = (JasperReport) JRLoader.loadObject(inStream);
JasperPrint jasperprint = JasperFillManager.fillReport(report, params, conn);
JRAbstractExporter exporter = new JRPdfExporter();
exporter.exportReport();
ByteArrayOutputStream os = (ByteArrayOutputStream) exporter.getParameter(JRExporterParameter.OUTPUT_STREAM);
byte[] formattedReportBytes = os.toByteArray();
return formattedReportBytes;

我看到JasperReports中有一个名为JRJdbcQueryExecuter的类... 是否可以直接调用它而不是调用fillReport,以获取执行的SQL查询结果集?谢谢。

你为什么想要使用JasperReports API来解决这个任务? - Alex K
就像我之前所说的那样,我有很多包含长SQL查询(带有许多参数)并生成复杂PDF渲染、将数据分组等的报告。现在我还需要提取数据库查询结果,不进行任何处理、分组或任何形式的渲染。这就像我手动从报告中复制查询,用实际值替换所有$P{},将其粘贴到SQL客户端中,执行并将其提取为CSV文件。我正在寻找一种自动化的方法来通过代码完成此操作,利用JR参数管理,并获得解析后准备好执行的查询... - sigi_tm
这项工作的目的是什么?你会如何处理返回的ResultSet?只是好奇... - Alex K
我知道我可以将我的报告查询复制到Java代码中,手动使用字符串替换函数用实际值替换所有参数等...但这样做对于每个报告,我都必须维护两个不同的查询,一个硬编码在Java中,另一个包含在报告内部! - sigi_tm
目的是将查询结果提取为 csv 或 xls 文件,这些文件需要某种形式的数据处理。 - sigi_tm
1个回答

7
我想先说这种做法感觉有些不对和拙劣,但实际上可以实现,只需不执行JasperReports查询。
JasperReport report = (JasperReport) JRLoader.loadObject(inStream);

//this is the actual query in the report
JRQuery query = report.getMainDataSet().getQuery;

//once here you get the entire sql string, this will have any parameters replaced with 
//the '?' character
String queryString = query.getText();

//now start building your prepared statement, I am assuming you already have your
//connection in the conn variable
PrepararedStatment statement = con.prepareStatement(queryString);

//almost there, need to set the parameters
//the sql query is broke up into chunks inside the JRQuery. The chunks have types 
//that are  either text, parameter, or parameter clause. We care about parameter, 
//not sure what parameter clause would be to be honest
int index = 0; //this is the index to set the parameter at in the statement
for (JRQueryChunk chunk : query.getChunks()){
     if (chunk.getType() == JRQueryChunk .TYPE_PARAMETER){
         statement.setObject(index, params.get(chunk.getText()));
         index = index + 1;
     }
}
//then execute the query
ResultSet results = statement.executeQuery();

注意: 这里没有错误检查,您应该添加它。而且我也不确定这样做是否是个好主意。将查询从报告中移出并完全放入您的Java代码中可能会更好。然后只需将ResultSet作为数据源传递,并且您可以开始工作了。


不起作用。查询字符串仍然包含JR格式的参数(例如$P{PARAM_1}),未解析。 我正在寻找一种将最终查询作为字符串提取以便手动执行它的方法,或者拦截JR执行它的时刻并获取结果,而不是继续进行文档渲染的方法... - sigi_tm
你确定吗?当我运行它时,参数被替换为“?”字符。那么循环遍历JRQueryChunks呢?你可以重建查询并用问号自己替换参数。 - Jacob Schoen
非常有帮助 :) 谢谢 :) - Vishal Zanzrukia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接