Экспорт результатов запроса JasperReports

в моем 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;

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

Спасибо

 sigi_tm21 мар. 2012 г., 11:49
Как я уже говорил, у меня есть много отчетов, которые содержат длинные SQL-запросы (со многими параметрами) и производят сложные рендеринг PDF, группирование данных и т. Д. Теперь я также должен извлечь результаты запросов к базе данных, без какой-либо обработки, группировки или рендеринг любого рода. Как будто я вручную копирую запрос из отчета, я заменяю все $ P {} фактическими значениями, вставляю его в клиент SQL, выполняю его и извлекаю как файл csv. Я ищу автоматический способ сделать это с помощью кода, используя преимущества управления параметрами JR и получая запрос, проанализированный и готовый к выполнению ...
 sigi_tm21 мар. 2012 г., 11:56
Я знаю, что мог бы копировать свои запросы отчетов в код Java, вручную заменять все параметры фактическими значениями, используя функции замены строк и т. Д. Но таким образом для каждого отчета мне пришлось бы поддерживать два разных запроса, один жестко закодированный внутри Java и другой включен в отчет!
 sigi_tm21 мар. 2012 г., 12:00
Цель состоит в том, чтобы извлечь результаты запроса в виде файла CSV или XLS, который необходим для какой-либо формы обработки данных.
 Alex K21 мар. 2012 г., 11:52
И какова цель этой работы? Что вы будете делать с возвращенным ResultSet? Просто интересно ...
 Alex K20 мар. 2012 г., 20:41
Почему вы хотите использовать API JasperReports для решения этой задачи?

Ответы на вопрос(1)

Решение Вопроса

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

 sigi_tm21 мар. 2012 г., 11:32
Не работает. Строка queryString по-прежнему содержит параметры в формате JR (например, $ P {PARAM_1}), которые не анализируются. Я ищу способ извлечь окончательный запрос в виде строки, чтобы выполнить его вручную, или способ перехватить момент, когда JR выполняет его, и получить результаты обратно вместо продолжения рендеринга документа ...
 sigi_tm23 мар. 2012 г., 17:29
Хорошо, я немного изменил его, и теперь он работает как шарм. Спасибо! :)
 Vishal Zanzrukia09 июл. 2015 г., 08:09
очень полезно :) спасибо :)
 Jacob Schoen21 мар. 2012 г., 14:04
Вы уверены в этом, когда я запустил параметры, которые были заменены на '?' персонажи. А как насчет цикла через JRQueryChunks? Вы можете перестроить запрос и заменить параметры самостоятельно на вопросительные знаки.

Ваш ответ на вопрос