in my Java project I have a lot of JasperReports reports with complex SQL queries, containing a lot of parameters. The reports are used to produce pdf documents containing the data returned by the query, grouped and formatted in various ways.
Now I also have the need to export directly the query result (e.g. a ResultSet, or a Map or a csv file, or similar...). Is it possible to ask JasperReports to execute only the query and return results instead of rendering the pdf page?
(NOTE: it's not the same as choosing a csv output format to the report rendering, because this method tries to convert the report design to a csv file... Instead, I'd like only to "reuse" the query inside a report, also taking advantage of JR parameters management, etc...)
This is my Java code to produce a pdf document from a report:
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;
I saw there's a class called JRJdbcQueryExecuter
inside JasperReports...
Is it possible to call it directly instead of calling fillReport
, in order to get the ResultSet of the executed SQL query?
Thanks
I would like to start with that this feels wrong and hacky, but it is possible, minus actually having JasperReports executing the query.
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();
Note: There is no error checking here, and you should add that. Also not sure if doing this is a great idea. It could be better to move the queries out of the reports and into your java code altogether. Then just pass in the ResultSet as a datasource and you are good to go.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With