Экспорт результатов запроса JasperReports - PullRequest
6 голосов
/ 20 марта 2012

в моем Java-проекте у меня много отчетов JasperReports со сложными SQL-запросами, содержащими много параметров. Отчеты используются для создания PDF-документов, содержащих данные, возвращаемые запросом, сгруппированные и отформатированные различными способами.

Теперь у меня также есть необходимость напрямую экспортировать результат запроса (например, 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;

Я видел, что внутри JasperReports есть класс JRJdbcQueryExecuter ... Можно ли вызвать его напрямую вместо вызова fillReport, чтобы получить ResultSet выполненного SQL-запроса?

Спасибо

1 Ответ

7 голосов
/ 20 марта 2012

Я хотел бы начать с того, что это кажется неправильным и хакерским, но это возможно, за исключением того, что 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 в качестве источника данных, и все готово.

...