在JasperReports中使用ArrayList作为主数据源

编程入门 行业动态 更新时间:2024-10-25 16:22:01
在JasperReports中使用ArrayList作为主数据源 - 仅打印第一个元素(Using an ArrayList as primary datasource in JasperReports - Only first element prints)

我在使用ArrayList作为JasperReports中的数据源时遇到了问题。

我的程序是一个简单的Java程序,我有一个非常简单的报告。 我在ArrayList中有两个数据对象,我用JRBeanCollectionDataSource包装它们,并通过JasperFillManager将它传递给JRPrint 。 生成了我的报告,但只生成了第一个数组项。

我基本上遵循本教程 ,然后将另一个项添加到ArrayList 。 但只有一个打印出来。

代码段:

ArrayList<ProtoReport> listOfReports = new ArrayList<ProtoReport>();

ProtoReport protoReport1 = new ProtoReport();
ProtoReport protoReport2 = new ProtoReport();

//Simple Fields and text
protoReport1.setTitle("Example Fact Sheet");
protoReport2.setTitle("2nd Fact Sheet");

//add all reports to the list
listOfReports.add(protoReport1);
listOfReports.add(protoReport2);

//and wrap the ArrayList in a JRBeanCollectionDataSource
JRBeanCollectionDataSource beanBurritoWrap = new JRBeanCollectionDataSource(listOfReports);

//build the jasper report
JasperReport jasperReport;
JasperPrint jasperPrint;
HashMap<String, Object> hashMap = new HashMap<>();
boolean reportCreated;

try {
    jasperReport = JasperCompileManager.compileReport(jrxmlLocation);
    jasperPrint = JasperFillManager.fillReport(jasperReport, hashMap, beanBurritoWrap);
    JasperExportManager.exportReportToPdfFile(jasperPrint, outputFileName);
    reportCreated = true;
} catch (JRException e) {
    e.printStackTrace();
    reportCreated = false;
}

//Report on build status
System.out.println("Jasper Report built: " + reportCreated);
 

ProtoReport类基本上只是报表字段,表格和图表数据的容器 例如:

package org.reportprotojava.protosheet; import java.util.ArrayList; public class ProtoReport { private String outputFileName; private String title; private String logoLocation; private String paragraphText; private ArrayList<String> tableData; private String picLocation; private int[][] graphData; //TODO decide how to store chart data private ChartData chartData; private String path; //default constructor public ProtoReport() { // Initialize object fields outputFileName = "PrototypeReport"; title = "Prototype Report"; paragraphText = "Default text"; tableData = new ArrayList<String>(); chartData = new ChartData(); //set path to working directory path = System.getProperty("user.dir"); //default to assumed report location //(ie same folder as .jrxml and .jasper files) logoLocation = path + "\\reports"; picLocation = path + "\\reports"; }

加上参数化的构造函数,然后是getter和setter等

编译没有问题,第一个报告导出到pdf没问题。 我得到的唯一警告是:

log4j:WARN No appenders could be found for logger (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory). log4j:WARN Please initialize the log4j system properly.

但我不认为这与这个问题有任何关系(如果不是这样,请纠正我)。

这是我的.jrxml文件(忽略图表的东西,我现在正在努力,但它正在形成另一个问题的材料;-))

<?xml version="1.0" encoding="UTF-8"?> <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="ReportPrototype.jrxml" pageWidth="595" pageHeight="842" columnWidth="495" leftMargin="57" rightMargin="43" topMargin="43" bottomMargin="43" uuid="10825c57-f953-4166-bf03-8ecabe8a8f47"> <property name="ireport.zoom" value="1.0"/> <property name="ireport.x" value="0"/> <property name="ireport.y" value="128"/> <subDataset name="ChartData" uuid="ebdb66fc-82b2-489c-8187-731eed51dd7a"> <field name="xAxis" class="java.util.List"/> <field name="yAxis" class="java.util.List"/> </subDataset> <queryString language="SQL"> <![CDATA[]]> </queryString> <field name="title" class="java.lang.String"/> <field name="logoLocation" class="java.lang.String"/> <field name="picLocation" class="java.lang.String"/> <field name="chartData" class="java.lang.Object"/> <field name="xAxis" class="java.util.List"/> <field name="yAxis" class="java.util.List"/> <title> <band height="115" splitType="Stretch"> <textField isStretchWithOverflow="true" pattern=""> <reportElement uuid="519c6bb5-72f9-4c25-8e91-47865ae0c9df" mode="Opaque" x="0" y="70" width="495" height="45" forecolor="#000099"/> <textElement> <font size="26"/> </textElement> <textFieldExpression><![CDATA[$F{title}]]></textFieldExpression> </textField> <image> <reportElement uuid="f989f871-32ea-4f13-ae3f-3f487cde76dd" x="295" y="0" width="200" height="42"/> <imageExpression><![CDATA[$F{logoLocation}]]></imageExpression> </image> </band> </title> <pageHeader> <band height="45" splitType="Stretch"> <staticText> <reportElement uuid="34054fe4-f5c8-4154-b11e-558ad49c9bed" x="195" y="14" width="100" height="20"/> <textElement/> <text><![CDATA[Static text]]></text> </staticText> </band> </pageHeader> <columnHeader> <band height="105" splitType="Stretch"> <image> <reportElement uuid="3759a707-32a4-49ef-a9c6-b0ad7136f738" x="242" y="0" width="253" height="105"/> <imageExpression><![CDATA[$F{picLocation}]]></imageExpression> </image> </band> </columnHeader> <detail> <band height="184" splitType="Stretch"> <xyLineChart> <chart> <reportElement uuid="3b739a73-6612-42b0-bdf9-46f5d9a9899d" x="0" y="0" width="495" height="184"/> <chartTitle/> <chartSubtitle/> <chartLegend/> </chart> <xyDataset> <dataset> <datasetRun subDataset="ChartData" uuid="d84314f7-4580-4b2b-a190-b0bbe4ea63df"> <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.JRBeanCollectionDataSource($F{chartData})]]></dataSourceExpression> </datasetRun> </dataset> </xyDataset> <linePlot> <plot/> </linePlot> </xyLineChart> </band> </detail> <columnFooter> <band height="45" splitType="Stretch"/> </columnFooter> <pageFooter> <band height="45" splitType="Stretch"/> </pageFooter> <lastPageFooter> <band height="45" splitType="Stretch"/> </lastPageFooter> <summary> <band height="45" splitType="Stretch"/> </summary>

有没有人知道我做错了什么?

编辑

好吧我已经基于AlexK的建议做了一些更改,将我的所有字段,图表和表格移动到Detail 1乐队中,但现在当我去编译时,我得到以下错误:

net.sf.jasperreports.engine.JRException: Byte data not found at : C:\Users\eljaydub\workspace\ReportProtoJava\reports at net.sf.jasperreports.repo.RepositoryUtil.getBytesFromLocation(RepositoryUtil.java:324) at net.sf.jasperreports.engine.RenderableUtil.getRenderable(RenderableUtil.java:121) at net.sf.jasperreports.engine.fill.JRFillImage.evaluateImage(JRFillImage.java:505) at net.sf.jasperreports.engine.fill.JRFillImage.evaluate(JRFillImage.java:442) at net.sf.jasperreports.engine.fill.JRFillElementContainer.evaluate(JRFillElementContainer.java:257) at net.sf.jasperreports.engine.fill.JRFillBand.evaluate(JRFillBand.java:457) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillColumnBand(JRVerticalFiller.java:2037) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillDetail(JRVerticalFiller.java:771) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportContent(JRVerticalFiller.java:301) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:148) at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:909) at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:841) at net.sf.jasperreports.engine.fill.JRFiller.fill(JRFiller.java:88) at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:653) at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:969) at org.reportprotojava.protosheet.Program.main(Program.java:130)

我做了一些谷歌搜索,发现大部分时间这是由与图像文件位置有关的问题引起的,所以我用这个修改了我的代码:

//Locations //Absolute protoReport1.setLogoLocation("C:\\Users\\eljaydub\\workspace\\ReportProtoJava\\reports\\logo.gif"); protoReport1.setPicLocation("C:\\Users\\eljaydub\\workspace\\ReportProtoJava\\reports\\portfolio.jpg"); //Relative // protoReport1.setLogoLocation(protoReport1.getPath() + "\\reports\\logo.gif"); // protoReport1.setPicLocation(protoReport1.getPath() + "\\reports\\portfolio.jpg");

并尝试了相对和绝对路径,但得到了相同的错误。 这些是相关的,还是应该为此错误创建新帖子?

编辑

解决了! AlexK的建议确实解决了第一个问题,然后揭示了第二个问题:当报告转到下一个数组元素protoReport2时 ,它发现该对象的图像链接是我的默认构造函数提供的,只猜测可能的图像文件的名称和位置。 然后抛出异常,因为两个图像的imageType属性onErrorType都设置为Error 。 我只需要在iReports中将属性更改为Icon ,生成的报告没有进一步的问题,我得到了我的预期:两个数组元素打印在不同的页面上,第二个使用默认的构造函数值。 谢谢您的帮助!

I'm having a problem using an ArrayList as my primary datasource in JasperReports.

My program is a simple Java program and I have a very simple report. I have two data object in my ArrayList and I wrap these with JRBeanCollectionDataSource and pass it to JRPrint via JasperFillManager. My report gets generated but only the first array item has been generated.

I am essentially following this tutorial and then adding another item to the ArrayList. But only one prints out.

Code snippet:

ArrayList<ProtoReport> listOfReports = new ArrayList<ProtoReport>();

ProtoReport protoReport1 = new ProtoReport();
ProtoReport protoReport2 = new ProtoReport();

//Simple Fields and text
protoReport1.setTitle("Example Fact Sheet");
protoReport2.setTitle("2nd Fact Sheet");

//add all reports to the list
listOfReports.add(protoReport1);
listOfReports.add(protoReport2);

//and wrap the ArrayList in a JRBeanCollectionDataSource
JRBeanCollectionDataSource beanBurritoWrap = new JRBeanCollectionDataSource(listOfReports);

//build the jasper report
JasperReport jasperReport;
JasperPrint jasperPrint;
HashMap<String, Object> hashMap = new HashMap<>();
boolean reportCreated;

try {
    jasperReport = JasperCompileManager.compileReport(jrxmlLocation);
    jasperPrint = JasperFillManager.fillReport(jasperReport, hashMap, beanBurritoWrap);
    JasperExportManager.exportReportToPdfFile(jasperPrint, outputFileName);
    reportCreated = true;
} catch (JRException e) {
    e.printStackTrace();
    reportCreated = false;
}

//Report on build status
System.out.println("Jasper Report built: " + reportCreated);
 

The ProtoReport class is basically just a container for report field, table and chart data For example:

package org.reportprotojava.protosheet; import java.util.ArrayList; public class ProtoReport { private String outputFileName; private String title; private String logoLocation; private String paragraphText; private ArrayList<String> tableData; private String picLocation; private int[][] graphData; //TODO decide how to store chart data private ChartData chartData; private String path; //default constructor public ProtoReport() { // Initialize object fields outputFileName = "PrototypeReport"; title = "Prototype Report"; paragraphText = "Default text"; tableData = new ArrayList<String>(); chartData = new ChartData(); //set path to working directory path = System.getProperty("user.dir"); //default to assumed report location //(ie same folder as .jrxml and .jasper files) logoLocation = path + "\\reports"; picLocation = path + "\\reports"; }

Plus a parametrized constructor and then getters and setters etc

There are no problems compiling and the first report exports to pdf no problem. The only warning I get is:

log4j:WARN No appenders could be found for logger (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory). log4j:WARN Please initialize the log4j system properly.

But I don't think that has anything to do with this issue (please correct me if that's not true).

Here is my .jrxml file (ignore the chart stuff, I'm working on that right now but it's shaping up to become material for another question ;-) )

<?xml version="1.0" encoding="UTF-8"?> <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="ReportPrototype.jrxml" pageWidth="595" pageHeight="842" columnWidth="495" leftMargin="57" rightMargin="43" topMargin="43" bottomMargin="43" uuid="10825c57-f953-4166-bf03-8ecabe8a8f47"> <property name="ireport.zoom" value="1.0"/> <property name="ireport.x" value="0"/> <property name="ireport.y" value="128"/> <subDataset name="ChartData" uuid="ebdb66fc-82b2-489c-8187-731eed51dd7a"> <field name="xAxis" class="java.util.List"/> <field name="yAxis" class="java.util.List"/> </subDataset> <queryString language="SQL"> <![CDATA[]]> </queryString> <field name="title" class="java.lang.String"/> <field name="logoLocation" class="java.lang.String"/> <field name="picLocation" class="java.lang.String"/> <field name="chartData" class="java.lang.Object"/> <field name="xAxis" class="java.util.List"/> <field name="yAxis" class="java.util.List"/> <title> <band height="115" splitType="Stretch"> <textField isStretchWithOverflow="true" pattern=""> <reportElement uuid="519c6bb5-72f9-4c25-8e91-47865ae0c9df" mode="Opaque" x="0" y="70" width="495" height="45" forecolor="#000099"/> <textElement> <font size="26"/> </textElement> <textFieldExpression><![CDATA[$F{title}]]></textFieldExpression> </textField> <image> <reportElement uuid="f989f871-32ea-4f13-ae3f-3f487cde76dd" x="295" y="0" width="200" height="42"/> <imageExpression><![CDATA[$F{logoLocation}]]></imageExpression> </image> </band> </title> <pageHeader> <band height="45" splitType="Stretch"> <staticText> <reportElement uuid="34054fe4-f5c8-4154-b11e-558ad49c9bed" x="195" y="14" width="100" height="20"/> <textElement/> <text><![CDATA[Static text]]></text> </staticText> </band> </pageHeader> <columnHeader> <band height="105" splitType="Stretch"> <image> <reportElement uuid="3759a707-32a4-49ef-a9c6-b0ad7136f738" x="242" y="0" width="253" height="105"/> <imageExpression><![CDATA[$F{picLocation}]]></imageExpression> </image> </band> </columnHeader> <detail> <band height="184" splitType="Stretch"> <xyLineChart> <chart> <reportElement uuid="3b739a73-6612-42b0-bdf9-46f5d9a9899d" x="0" y="0" width="495" height="184"/> <chartTitle/> <chartSubtitle/> <chartLegend/> </chart> <xyDataset> <dataset> <datasetRun subDataset="ChartData" uuid="d84314f7-4580-4b2b-a190-b0bbe4ea63df"> <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.JRBeanCollectionDataSource($F{chartData})]]></dataSourceExpression> </datasetRun> </dataset> </xyDataset> <linePlot> <plot/> </linePlot> </xyLineChart> </band> </detail> <columnFooter> <band height="45" splitType="Stretch"/> </columnFooter> <pageFooter> <band height="45" splitType="Stretch"/> </pageFooter> <lastPageFooter> <band height="45" splitType="Stretch"/> </lastPageFooter> <summary> <band height="45" splitType="Stretch"/> </summary>

Does anyone have an idea of what I'm doing wrong?

EDIT

Ok I've made some changes based on AlexK's advice by moving all of my fields, charts and tables into the Detail 1 band but now when I go to compile I get the following error:

net.sf.jasperreports.engine.JRException: Byte data not found at : C:\Users\eljaydub\workspace\ReportProtoJava\reports at net.sf.jasperreports.repo.RepositoryUtil.getBytesFromLocation(RepositoryUtil.java:324) at net.sf.jasperreports.engine.RenderableUtil.getRenderable(RenderableUtil.java:121) at net.sf.jasperreports.engine.fill.JRFillImage.evaluateImage(JRFillImage.java:505) at net.sf.jasperreports.engine.fill.JRFillImage.evaluate(JRFillImage.java:442) at net.sf.jasperreports.engine.fill.JRFillElementContainer.evaluate(JRFillElementContainer.java:257) at net.sf.jasperreports.engine.fill.JRFillBand.evaluate(JRFillBand.java:457) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillColumnBand(JRVerticalFiller.java:2037) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillDetail(JRVerticalFiller.java:771) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportContent(JRVerticalFiller.java:301) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:148) at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:909) at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:841) at net.sf.jasperreports.engine.fill.JRFiller.fill(JRFiller.java:88) at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:653) at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:969) at org.reportprotojava.protosheet.Program.main(Program.java:130)

I've done some googling and found that most of the time this is caused by problems relating to image file locations so I've modified my code with this:

//Locations //Absolute protoReport1.setLogoLocation("C:\\Users\\eljaydub\\workspace\\ReportProtoJava\\reports\\logo.gif"); protoReport1.setPicLocation("C:\\Users\\eljaydub\\workspace\\ReportProtoJava\\reports\\portfolio.jpg"); //Relative // protoReport1.setLogoLocation(protoReport1.getPath() + "\\reports\\logo.gif"); // protoReport1.setPicLocation(protoReport1.getPath() + "\\reports\\portfolio.jpg");

and have tried both relative and absolute paths but get the same error. Are these related or should I create a new post for this error?

Edit

Solved! AlexK's advice did indeed solve the first problem and that then revealed the second: When the report went to the next array element, protoReport2, it found that the image links for this object were those supplied by my default constructor, which only guess at the probable name and location of the images files. The exception was then thrown because the image attribute onErrorType was set to Error for both images. I simply had to change the attribute to Icon in iReports and the report generated without further problems and I got what I expected: The two array elements printed on separate pages, the second one using default constructor values. Thanks for the help!

最满意答案

您应该使用Detail band来显示数据源中的数据标题带不是通过数据源迭代的正确选择。

你应该把textField (带有<textFieldExpression><![CDATA[$F{title}]]></textFieldExpression> )和图像 (带有<imageExpression><![CDATA[$F{logoLocation}]]></imageExpression> )到细节乐队。


有关JasperReports Ultimate Guide乐队的更多信息:

标题带 - 这是报告的第一部分。 它仅在报告填充过程中生成一次,并代表生成的文档的开头。 细节带 - 对于数据源中的每条记录,引擎会尝试生成此部分。 细节部分可以由多个带组成。

这篇关于使用JavaBean数据源的文章可以帮助理解如何使用JavaBean数据源。


来自jasperreports.sourceforge.net网站的另一篇有用的文章 - 这是关于图像的 。

You should use Detail band for showing data from the datasource. The Title band it not right choice for iterating thru the datasource.

You should put textField (with <textFieldExpression><![CDATA[$F{title}]]></textFieldExpression>) and image (with <imageExpression><![CDATA[$F{logoLocation}]]></imageExpression>) to the Detail band.


Additional information about bands from the JasperReports Ultimate Guide:

Title band - This is the first section of the report. It is generated only once during the report-filling process and represents the beginning of the resulting document. Detail band - For each record in the data source, the engine tries to generate this section. The detail section can be made of multiple bands.

This article about using JavaBean Data Sources can help to understand how to work with JavaBean datasource.


Another useful article from the jasperreports.sourceforge.net site - this one is about images.

更多推荐

本文发布于:2023-07-25 10:45:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1260046.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数据源   JasperReports   ArrayList

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!