JasperReportsのプライマリデータソースとしてArrayListを使用すると問題が発生します。
私のプログラムは単純な Java プログラムであり、非常に単純なレポートがあります。ArrayListに 2 つのデータ オブジェクトがあり、これらをJRBeanCollectionDataSourceでラップし、JasperFillManagerを介してJRPrintに渡します。レポートは生成されますが、最初の配列アイテムしか生成されていません。
私は基本的にこのチュートリアルに従い、別の項目をArrayListに追加しています。ただし、出力されるのは 1 つだけです。
コードスニペット:
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";
}
さらに、パラメーター化されたコンストラクター、ゲッターとセッターなど
コンパイルに問題はなく、最初のレポートは問題なく 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>
誰かが私が間違っていることを知っていますか?
編集
OK、AlexK のアドバイスに基づいて、すべてのフィールド、チャート、およびテーブルを詳細 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 のアドバイスは確かに最初の問題を解決し、2 番目の問題を明らかにしました。レポートが次の配列要素protoReport2に移動したとき、このオブジェクトの画像リンクは、可能性のあるものだけを推測するデフォルトのコンストラクターによって提供されたものであることがわかりました。画像ファイルの名前と場所。両方の画像の画像属性onErrorTypeがErrorに設定されていたため、例外がスローされました。iReports で属性をIconに変更するだけで、レポートはそれ以上問題なく生成され、予想どおりの結果が得られました。助けてくれてありがとう!