Как передать основной источник данных отчета в подзаголовок (JasperReports)?
Я использую JasperReports, и я заполняю JRDataSource
для отчета.
Теперь я хочу передать основной REPORT_DATA_SOURCE
в подзаголовок. Как я могу это сделать?
Насколько я знаю, REPORT_DATA_SOURCE
является расходным объектом, поэтому его можно использовать только один раз, правильно?. Можно ли скопировать этот источник данных и передать его?
Кстати: я использую iReport для создания макета.
Ответы
Ответ 1
Вы можете передать источник данных с помощью встроенного параметра REPORT_DATA_SOURCE
.
Пример:
<subreport>
<reportElement x="261" y="25" width="200" height="100"/>
<dataSourceExpression><![CDATA[$P{REPORT_DATA_SOURCE}]]></dataSourceExpression>
<subreportExpression><![CDATA[$P{SUBREPORT_DIR} + "subreport.jasper"]]></subreportExpression>
</subreport>
Вы можете создать новый экземпляр источника данных на основе переменной, параметра или поля.
Образец:
<variable name="HeadingsCollection" class="java.util.Collection" calculation="System">
<initialValueExpression><![CDATA[new java.util.ArrayList()]]></initialValueExpression>
</variable>
...
<subreport>
<reportElement x="0" y="0" width="515" height="20"/>
<subreportParameter name="ReportTitle">
<subreportParameterExpression><![CDATA[$P{ReportTitle}]]></subreportParameterExpression>
</subreportParameter>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($V{HeadingsCollection})]]></dataSourceExpression>
<subreportExpression class="java.lang.String"><![CDATA["HeadingsReport.jasper"]]></subreportExpression>
</subreport>
Еще один пример:
<field name="cast" class="java.util.Collection"/>
...
<subreport>
<reportElement positionType="Float" x="15" y="25" width="245" height="20" isRemoveLineWhenBlank="true" backcolor="#99CCFF"/>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{cast})]]></dataSourceExpression>
<subreportExpression class="java.lang.String"><![CDATA["JRMDbCastSubreport.jasper"]]></subreportExpression>
</subreport>
Или вы можете передать источник данных с помощью параметра:
<parameter name="SubreportDataSource" class="net.sf.jasperreports.engine.JRDataSource"/>
...
<subreport>
<reportElement positionType="Float" x="15" y="25" width="245" height="20" isRemoveLineWhenBlank="true"/>
<dataSourceExpression>$P{SubreportDataSource}</dataSourceExpression>
<subreportExpression class="java.lang.String"><![CDATA["Subreport.jasper"]]></subreportExpression>
</subreport>
Примечание:
Используя тот же (с основным отчетом) источник данных в подрепорте, может вызвать эффект потери первой строки в подрепорте. Вы можете прочитать Почему первая запись отсутствует в моем сообщении? для понимания того, как избежать этой проблемы.
Ответ 2
Да, вы должны быть осторожны в том, как передавать источник данных. С помощью SQL-соединения вы можете просто передать выражение соединения, например $P{REPORT_CONNECTION}
. Затем в subreport есть собственный SQL-запрос.
В вашем случае вы хотите передать фактические данные. В зависимости от деталей, это может быть так просто, как просто определить выражение Parameter Map Expression, например $P{REPORT_PARAMETERS_MAP}
. Он находится на другой вкладке в том же окне, где вы устанавливаете подсоединение subreport в iReport. Часто этого достаточно для передачи источника данных.
Но вам может понадобиться небольшой код для обработки вещей. Рассмотрим этот пример с источником данных CSV, повторно используемым в подписях. Причина, по которой вы не можете просто использовать объект JRParameter.REPORT_DATA_SOURCE, заключается в том, что указатель строки индекса никогда не reset, поэтому передача этого исходного объекта в подзаголовок приведет к преждевременному закрытию набора записей. Мы решили это с минимальным вспомогательным классом:
package com.jaspersoft.untested_unsupported;
import java.io.File;
import java.io.FileNotFoundException;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.data.JRCsvDataSource;
public class CsvDataSourceFactory {
public static JRDataSource getDataSource(String fileName, boolean firstRowHeaders) throws FileNotFoundException {
JRCsvDataSource csvDs = new JRCsvDataSource(new File(fileName));
csvDs.setUseFirstRowAsHeader(firstRowHeaders);
return csvDs;
}
}
Ответ 3
мы предполагаем, что параметром datasource является "dataSourceParam", а значение источника данных (list) - это "dataSourceList",
в классе java мы помещаем:
final Map<String, Object> params = new HashMap<String, Object>();
JRDataSource dataSource = new ListOfArrayDataSource( dataSourceList,
new String[] {"date", "age", "adress", "email"});
params.put("dataSourceParam",dataSourceList);**
в основном шаблоне отчета мы помещаем в объявление параметров:
<parameter name="dataSourceParam" class="net.sf.jasperreports.engine.JRDataSource"/>
то в теге subreport мы помещаем:
<subreport isUsingCache="true">
<reportElement key="subreport-1" stretchType="RelativeToTallestObject" isPrintRepeatedValues="false" x="112" y="45" width="338" height="29"/>
<subreportParameter name="otherParameter">
<subreportParameterExpression><![CDATA[$P{sumM1}]]></subreportParameterExpression>
</subreportParameter>
<dataSourceExpression><![CDATA[$P{dataSourceParam}]]></dataSourceExpression>
<subreportExpression class="net.sf.jasperreports.engine.JasperReport"><![CDATA[$P{subReportFile}]]></subreportExpression>
</subreport>
Ответ 4
"REPORT_DATA_SOURCE" - это расходный объект, вы можете использовать столько времени, сколько хотите.
Я тестировал источник данных как xml File dataSource и не появлялся, как сказал ALEX.
"это не будет потерять первую строку в подрепорте."
Я думаю, может быть, я использую xpath для выбора, поэтому каждый раз не будет записей о потерях.
Если вы используете базу данных JDBC в качестве источника данных, pealse передает параметр sql как параметр для представления отчета.
Если вы используете ResultSet в качестве параметра, возможно, потеряете одну запись, поскольку вы определяете подробный список вложенных отчетов.
Ответ 5
Это уже старый вопрос, но я получаю сообщение в
<subreport>
<reportElement x="261" y="25" width="200" height="100"/>
<dataSourceExpression><![CDATA[new JRBeanCollectionDataSource(
$P{REPORT_DATA_SOURCE}.data.toList().subList($V{REPORT_COUNT}-1,$V{REPORT_COUNT})]]></dataSourceExpression>
<subreportExpression><![CDATA[$P{SUBREPORT_DIR} + "subreport.jasper"]]></subreportExpression>
</subreport>