Jak przekazać główne źródło danych raportu do subreportu (JasperReports)?

Używam JasperReports i wypełniam JRDataSource do raportu. Teraz chcę przekazać główny REPORT_DATA_SOURCE do podprogramu. Jak mogę to zrobić?

Z tego co wiem, to przedmiot zużywalny, więc można go użyć tylko raz, prawda?. Czy mogę skopiować to źródło danych i przekazać je?

BTW: do tworzenia layoutu używam iReport.

Author: ChrisWue, 2011-12-13

5 answers

Możesz przekazać datasource poprzez wbudowany REPORT_DATA_SOURCE parametr.

Przykład:

<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>

Możesz utworzyć nową instancję datasource na podstawie zmiennej, parametru lub pola.

Próbka:

<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>

Kolejna próbka:

<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>

Lub możesz przekazać datasource za pomocą parametru:

<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>

Uwaga: Użycie tego samego (z głównym raportem) datasource w subreport może spowodować efekt utraty pierwszego wiersza w podprefekturze . Możesz przeczytać dlaczego brakuje pierwszego rekordu w moim subreport? post dla zrozumienia, jak uniknąć tego problemu.

 32
Author: Alex K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-13 19:35:42

Tak, musisz uważać, jak przekazać źródło danych. Dzięki połączeniu SQL możesz po prostu przekazać wyrażenie połączenia, takie jak $P{REPORT_CONNECTION}. Następnie podpreport ma własne zapytanie SQL.

W Twoim przypadku chcesz przekazać rzeczywiste dane. W zależności od szczegółów może to być tak proste, jak zdefiniowanie wyrażenia Mapy parametru, takiego jak $P{REPORT_PARAMETERS_MAP}. Znajduje się na innej karcie w tym samym oknie, w którym ustawiasz połączenie podrzędne w iReport. Często jest to wystarczające do przekazania danych źródło.

Ale możesz potrzebować trochę kodu, żeby sobie z tym poradzić. Rozważ ten przykład ze źródłem danych CSV ponownie wykorzystywanym w podraportach. Powód, dla którego nie możesz po prostu użyć Jrparametru.Obiekt REPORT_DATA_SOURCE jest spowodowany tym, że wskaźnik wiersza indeksu nigdy nie jest resetowany, więc przekazanie tego oryginalnego obiektu do podpreportu spowoduje przedwczesne zamknięcie zestawu rekordów. Rozwiązaliśmy to za pomocą minimalnej klasy pomocniczej:
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; 
    } 
}
 1
Author: mdahlman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-13 18:11:22

Zakładamy, że parametr datasource to "datasourcesparam", a wartość datasource (list) to " dataSourceList" w klasie java umieszczamy:

final Map<String, Object> params = new HashMap<String, Object>();
JRDataSource dataSource = new ListOfArrayDataSource( dataSourceList, 
                          new String[] {"date", "age", "adress", "email"});
params.put("dataSourceParam",dataSourceList);**

W głównym szablonie raportu wstawiamy deklarację parametrów:

<parameter name="dataSourceParam" class="net.sf.jasperreports.engine.JRDataSource"/>

Następnie w znaczniku subreport wstawiamy :

<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>
 0
Author: Shessuky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-29 09:41:57

"REPORT_DATA_SOURCE" jest obiektem zużywalnym, możesz użyć go tyle czasu, ile chcesz.

Przetestowałem datasource jako plik XML dataSource i nie pojawi się tak, jak powiedział ALEX.

" nie spowoduje to utraty pierwszego wiersza w podreport."

Myślę, że mogę użyć xpath, aby wybrać, więc za każdym razem nie będzie strat rekordów.

Jeśli używasz bazy danych JDBC jako źródła danych, pealse przekazuje parametr sql jako podpreport.

Jeśli użyjesz ResultSet jako parametru, może stracisz jeden rekord, jak zdefiniujesz podprogram w szczegółach.

 0
Author: zg_spring,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-07 07:43:27

To jest stare pytanie już odpowiedział, Ale mogę przekazać undelying bean do subreport, unikając utraty pierwszego rekordu lub przekazywanie wszystkich rekordów do subreport. Rozwiązanie to ma tę zaletę, że subreport może być używany jako raport główny i jest "po prostu" przekazać rzeczywisty rekord jako subreport datasource (używając groovy jako raport lang):

<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>
 0
Author: jneira,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-10 09:49:18