7
votes

My main report contains 5 fields, 4 of them are of type java.lang.String and the last one is of type java.util.List. I used its latter as the data source for the subreport. I set the datasource of the subreport.

Subreport properties:

Connection Type : Use a datasource expression
Datasource Expression : new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{Field5})

Passing of data is working fine (I guess) because when I fill the report inside the Java application. I can view the data passed to fields 1 to 4 but in field 5, at first, I can't verify because the subreport does not show data, only the static texts defined in the Column Header.

Then when I placed the fields of the subreport in the Page Footer, I found out that the data is passed successfully, the problem is that the Detail band itself is not showing.

Why is it not showing?

In the subreport properties, I have:

When no data: All Sections, No Detail

Please can anyone shed some light on this.

5
I am having the same problem with one newly-created report. The Detail band does not display anything, not even a static field.Raul Rene

5 Answers

11
votes

I had the same problem for more than 1 day. In the application I am developing on there are multiple JasperReports which work. I encountered this problem when adding a new one. No matter what I tried, nothing displayed in the Detail band. I tried everything from triple-checking the Controller that populates the report, to upgrading to the latest jasperreports jar and latest iReports version. Nothing seemed to work.

The problem is that the report is set by default to: When No Data: All Sections, No Detail, which basically means that if no data is sent to the report, it will display all sections, except for the Detail one.

Although besides static text which I was using to test the report I was passing parameters directly from the Java Controller, it did not work until I added an EXEC [myFunction] $P{parameterId} to the Query Text property of the report. The function is a simple straightforward one, which takes a parameterId passed from Java as a parameter and returns something. (also, make sure you set the The language for the dataset query sql property to SQL).

To sum up, for some reason the report doesn't seem to take the Java parameters as data (so it displays all the sections, except for Detail), so when I explicitly call a SQL function which returns some parameters and put them into my detail page, it works.

I hope this helps you, I busted my head for 10 hours to figure this out.

1
votes

You can try this sample.

The POJO (Bean):

public class BeanWithList {

    private List<String> m_cities;
    private Integer m_id;

    public BeanWithList(List<String> cities, Integer id) {
        m_cities = cities;
        m_id = id;
    }

    public List<String> getCities() {
        return m_cities;
    }

    public Integer getId() {
        return m_id;
    }
}

The code to fill report:

public static void testBuildPdf() {
    try {

        Map<String, Object> params = new HashMap<String, Object>();

        params.put("BeanSubreport", JasperCompileManager.compileReport(subreportSource));

        JasperReport jasperReport = JasperCompileManager.compileReport(masterSource);
        JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params, getDataSource());

        JasperExportManager.exportReportToPdfFile(jasperPrint, outputFileName);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private static JRDataSource getDataSource() {
    Collection<BeanWithList> coll = new ArrayList<BeanWithList>();

    BeanWithList bean = new BeanWithList(Arrays.asList("London", "Paris"), 1);

    coll.add(bean);

    bean = new BeanWithList(Arrays.asList("London", "Madrid", "Moscow"), 2);
    coll.add(bean);

    bean = new BeanWithList(Arrays.asList("Rome"), 3);
    coll.add(bean);

    return new JRBeanCollectionDataSource(coll);
}

The subreport jrxml:

<?xml version="1.0" encoding="UTF-8"?>
<jasperReport .. leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0">
    <field name="city" class="java.lang.String">
        <fieldDescription><![CDATA[_THIS]]></fieldDescription>
    </field>
    <detail>
        <band height="20" splitType="Stretch">
            <textField>
                <reportElement positionType="Float" x="0" y="0" width="100" height="20"/>
                <box leftPadding="10">
                    <topPen lineWidth="1.0"/>
                    <leftPen lineWidth="1.0"/>
                    <bottomPen lineWidth="1.0"/>
                    <rightPen lineWidth="1.0"/>
                </box>
                <textElement/>
                <textFieldExpression><![CDATA[$F{city}]]></textFieldExpression>
            </textField>
        </band>
    </detail>
</jasperReport>

The master jrxml:

<?xml version="1.0" encoding="UTF-8"?>
<jasperReport ...>
    <parameter name="BeanSubreport" class="net.sf.jasperreports.engine.JasperReport"/>
    <field name="id" class="java.lang.Integer"/>
    <field name="cities" class="java.util.Collection"/>
    <title>
        <band height="103" splitType="Stretch">
            <staticText>
                <reportElement x="138" y="28" width="258" height="20"/>
                <textElement textAlignment="Center" verticalAlignment="Middle">
                    <font isBold="true" isItalic="true"/>
                </textElement>
                <text><![CDATA[Bean with List sample]]></text>
            </staticText>
        </band>
    </title>
    <columnHeader>
        <band height="20">
            <staticText>
                <reportElement x="0" y="0" width="100" height="20"/>
                <box>
                    <topPen lineWidth="1.0"/>
                    <leftPen lineWidth="1.0"/>
                    <bottomPen lineWidth="1.0"/>
                    <rightPen lineWidth="1.0"/>
                </box>
                <textElement textAlignment="Center" verticalAlignment="Middle">
                    <font isBold="true" isItalic="true" isUnderline="false"/>
                </textElement>
                <text><![CDATA[Id]]></text>
            </staticText>
            <staticText>
                <reportElement x="100" y="0" width="100" height="20"/>
                <box>
                    <topPen lineWidth="1.0"/>
                    <leftPen lineWidth="1.0"/>
                    <bottomPen lineWidth="1.0"/>
                    <rightPen lineWidth="1.0"/>
                </box>
                <textElement textAlignment="Center" verticalAlignment="Middle">
                    <font isBold="true" isItalic="true" isUnderline="false"/>
                </textElement>
                <text><![CDATA[City name]]></text>
            </staticText>
        </band>
    </columnHeader>
    <detail>
        <band height="20" splitType="Stretch">
            <textField>
                <reportElement stretchType="RelativeToTallestObject" x="0" y="0" width="100" height="20"/>
                <box leftPadding="10">
                    <topPen lineWidth="1.0"/>
                    <leftPen lineWidth="1.0"/>
                    <bottomPen lineWidth="1.0"/>
                    <rightPen lineWidth="1.0"/>
                </box>
                <textElement/>
                <textFieldExpression><![CDATA[$F{id}]]></textFieldExpression>
            </textField>
            <subreport>
                <reportElement positionType="Float" stretchType="RelativeToTallestObject" x="100" y="0" width="100" height="20" isPrintWhenDetailOverflows="true"/>
                <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{cities})]]></dataSourceExpression>
                <subreportExpression><![CDATA[$P{BeanSubreport}]]></subreportExpression>
            </subreport>
        </band>
    </detail>
</jasperReport>

The result will be:

The report in PDF format


The main trick of this sample is the using of _THIS "variable".

For more information you can read JavaBean Data Sources article.

0
votes

When you pass parameters to FillManager, don't use null, use JREmptyDataSource.

Correct way: JasperFillManager.fillReport(this.getReportTemplate(JASPER_REPORT_EXPIRY_LETTER),this.parameters,new JREmptyDataSource());

Wrong way: JasperFillManager.fillReport(this.getReportTemplate(JASPER_REPORT_EXPIRY_LETTER),this.parameters, null);

0
votes
import java.awt.Desktop;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.xml.JRXmlLoader;
import net.sf.jasperreports.swing.JRViewer;
import net.sf.jasperreports.view.JasperViewer;

public class MyForm extends JFrame {



    public static JasperDesign jasperDesign;
    public static JasperPrint jasperPrint;
    public static JasperReport jasperReport;
    static JRBeanCollectionDataSource jrBeanCollectionDataSource;
    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                MyForm frame = new MyForm();
                frame.setVisible(true);
            }
        });
    }

    /**
     * Create the frame.
     */
    public MyForm() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 431, 286);
        setTitle("ThaiCreate.Com Java GUI Tutorial");
        getContentPane().setLayout(null);


        // Button Report
        JButton btnOpenReport = new JButton("Open Report");
        btnOpenReport.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                Connection connect = null;

                try {
                    Class.forName("com.mysql.jdbc.Driver");
                    connect =  DriverManager.getConnection("jdbc:mysql://localhost:3306/test" ,"root","");
                    System.out.println("Connected....");
                }
                catch (ClassNotFoundException e1) 
                {e1.printStackTrace();} 
                catch (SQLException e) 
                {e.printStackTrace();}

                // Application path
                FileInputStream report = null;
                try {
                     FileInputStream input = new FileInputStream(new File("C:\\Users\\admin\\Desktop\\report1.jrxml"));
                      try 
                     {

                        jasperDesign = JRXmlLoader.load(input);
                        jasperReport = JasperCompileManager.compileReport(jasperDesign);
                        jasperPrint = JasperFillManager.fillReport(jasperReport, null, connect);
                        JasperExportManager.exportReportToPdfFile(jasperPrint, "E:\\demo.pdf");



//                      Desktop.getDesktop().open(new File("D:/ReceiptReport.pdf"));

                    } catch (JRException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } 



                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }

                JFrame frame = new JFrame();
                frame.setTitle("ThaiCreate.Com Customer Report");
                frame.setBounds(100, 100, 800,600);
                frame.getContentPane().add(new JRViewer(jasperPrint));
                frame.setVisible(true);

                try {
                    connect.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });

        btnOpenReport.setBounds(137, 98, 146, 23);
        getContentPane().add(btnOpenReport);
        setResizable (false);
    }
}
0
votes

I solved it by setting the subreport parameter during runtime.

For those who encounter the same problem I just stored the JasperReport object (datatype is net.sf.jasperreports.engine.JasperReport) in a java variable then pass the variable to the parameter inside the report. This parameter is set as the value for Subreport Expression. Expression class of the subreport parameter should be net.sf.jasperreports.engine.JasperReport.