2012-03-20 66 views
6

我有很多JasperReports报告包含复杂的SQL查询,其中包含大量参数。这些报告用于生成包含查询返回的数据的pdf文档,并以各种方式进行分组和格式化。在我的Java项目中导出JasperReports查询结果

现在我也需要直接导出查询结果(例如ResultSet,或者Map或者csv文件,或者类似的...)。 是否有可能要求JasperReports仅执行查询并返回结果而不是呈现PDF页面? (注意:它与选择csv输出格式到报表呈现不同,因为此方法试图将报表设计转换为csv文件...相反,我只想“重用”报告中的查询,JR也趁着参数管理,等...)

这是我的Java代码从报表生成PDF文档:

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; 

我看到有一个叫JRJdbcQueryExecuter类内JasperReports ... 是否可以直接调用它而不是调用fillReport,为了得到执行的SQL查询的ResultSet?

感谢

+0

为什么你想使用JasperReports API来解决这个任务? – 2012-03-20 19:41:18

+0

正如我之前所说,我有很多报告,其中包含很长的SQL查询(有很多参数)并生成复杂的pdf渲染,将数据分组在一起等等。现在我还必须提取数据库查询结果,而不进行任何处理,分组或呈现任何形式。这就像我手动复制报表中的查询,我将所有$ P {}替换为实际值,将其粘贴到SQL客户端中,执行并将其作为csv文件提取。我正在寻找一种自动的方式来做到这一点的代码,利用JR参数管理和获得解析的查询和准备执行... – 2012-03-21 10:49:45

+0

这是什么工作的目的?你将如何处理返回的ResultSet?只是有趣的...... – 2012-03-21 10:52:48

回答

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作为数据源,您就可以开始使用了。

+0

不起作用。 queryString仍然包含JR格式的参数(例如$ P {PARAM_1}),不会被解析。 我正在寻找一种方法来提取最终查询作为一个字符串,以手动执行它,或者一种方法来拦截JR执行它的时刻,并得到的结果,而不是继续文档渲染的时刻... – 2012-03-21 10:32:44

+0

你确定吗,当我运行它的参数替换为'?'时字符。通过JRQueryChunks循环怎么样?您可以重建查询并用问号自己替换参数。 – 2012-03-21 13:04:51

+0

好吧,我改变了一下,现在它像一个魅力。谢谢! :) – 2012-03-23 16:29:50