0

我有一份正在使用 Java 编写的 Jasper 报告。

在 Java 中,我可以使用以下代码使用数据动态填充 bean:

    List<ThemeBean> themes = new ArrayList<ThemeBean>();
    CSVReader csvReader = new CSVReader(new FileReader(csvFilename));
    List<String[]> data = csvReader.readAll();
    for(String[] d : data) {
        ThemeBean tb = new ThemeBean();
        tb.setThemes(d[0]);
        tb.setComments(d[1]);
        tb.setSentiment(d[2]);
        themes.add(tb);
    }   
        JasperDesign jasperDesign = JRXmlLoader.load(fileName);
        JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(themes);
        JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
        JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null, ds);

当 .jrxml 文件在标签中指定了正确的字段和 textFieldExpression 时,这很有效......

以下内容使用已构建的列表动态填充:

<textFieldExpression><![CDATA[$F{themes}]]></textFieldExpression>

我的问题是弄清楚如何为同一报告中的两个不同表动态地执行此操作。看来我只能用于动态添加数据的一次迭代。我正在尝试实现在同一个报告中生成两个完全不同的表的结果。如果这个问题不清楚,请告诉我,我会尝试解决它。谢谢。

4

3 回答 3

0

You can pass multiple bean collections to a report by creating another bean that holds a beanCollection. Such a bean would look like this:

public class DataBean {
    private Collection beanCollection = null;

    public DataBean() {
    }

    public Collection getBeanCollection() {
        return beanCollection;
    }

    public void setBeanCollection(Collection beanCollection) {
        this.beanCollection = beanCollection;
    }
}

I assume that the other collection will be of a different type than ThemeBean. I'm using FruitBean as an example. For each bean collection you want to pass, you create a DataBean and add it to a collection, then pass that collection to the report. So your code would change to be something like this:

List<DataBean> allData = new ArrayList<DataBean>();

//...Create and populate `List<ThemeBean> themes`

DataBean db = new DataBean();
db.setBeanCollection(themes);
allData.add(db);

//...Create and populate `List<FruitBean> fruits`

db = new DataBean();
db.setBeanCollection(fruits);
allData.add(db);

//... Load the report
JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(allData);
//... Fill the report

The report that you fill with this datasource will be a shell report, containing a subreport for each DataBean you created. There will only be one field available in this report: $F{beanCollection}

Set the datasource expression of the subreport(s) to

new JRBeanCollectionDataSource($F{beanCollection}).

The fields for ThemeBean or FruitBean will then be available within the subreport.

If you prefer to use list components instead of subreports, that would also work.

于 2013-03-22T10:46:39.437 回答
0

Jasper 意识形态:一份报告 - 一个数据源。

在主报告中使用 2 个子报告。Main.jrxml 包含 subreport1(用于显示 List<ThemeBean>)和 subreport2(用于 List<AnotherBean>)。Subreport1 和 Subreport2 放入标题(或摘要)带。

在 Main.jrxml 中定义参数:themesPar, anotherPar as java.util.Collection

将集合作为参数放入主报告:

List<ThemeBean> themes = new ArrayList<ThemeBean>();
themes.add(...);
...
List<AnotherBean> blablas = new ArrayList<AnotherBean>();
blablas.add(...);
...

HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("themesPar", themes);
parameters.put("anotherPar", blablas);

JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, new JREmptyDataSource());

对于主报告中的 subreport1 数据源表达式,如下所示

new JRBeanCollectionDataSource($P{themesPar})

并以与 $P{anotherPar} 相同的方式用于 subreport2。在这两种情况下都设置为子报表

Connection Type = "Use a datasource expression"

为什么有新手问这个问题???:) 为什么这个解决方案没有出现在 jasperforge 常见问题解答中?

于 2013-03-22T10:00:31.303 回答
0

Jasper 意识形态:一份报告 - 一个数据源。

在主报告中使用 2 个子报告。Main.jrxml 包含 subreport1(用于显示列表)和 subreport2(用于列表)。Subreport1 和 Subreport2 放入标题(或摘要)带。

在 Main.jrxml 中定义参数:themesPar, anotherPar as java.util.Collection

于 2014-11-27T11:58:04.333 回答