我将xml文件提供给 JasperReports 以生成单个发票。这很好。
但是,我还想从单个xml文件生成多个发票(即给定用户的所有发票)。输出应该只是一个pdf文件。
XML文件看起来像这样
<orders>
<order>
...
</order>
<order>
...
</order>
<order>
...
</order>
</orders>
只需编辑jrxml文件, JasperReports 是否可以实现?我知道我可以通过循环调用 JasperReports 为每张发票生成一个pdf。但是我想避免这种情况,因为它需要修改很多代码。
更新
我使用RoR的Jasper-Rails插件生成报告。 https://github.com/fortesinformatica/jasper-rails/blob/master/lib/jasper-rails/jasper_reports_renderer.rb
单张发票的xml只是<order> ... </order>
jrxml(注意:xPath已经改变以反映mkl&#39; s方法)http://pastebin.com/R0vnrQgU
答案 0 :(得分:1)
如果之前可以为单张发票生成PDF,则可以生成包含多张发票的单个PDF。
目前尚不清楚需要对JRXML进行多少更改。不幸的是,OP没有提供JRXML。为了说明一个简单的案例:
如果order
仅包含一些静态数据量,因此JRXML只能在一个数据集上运行,几乎没有任何改变。 e.g:
假设您拥有与此示例类似的原始XML:
<order>
<name>Mr. Smith</name>
<quantity>2</quantity>
<item>bike</item>
<price>200</price>
</order>
和类似于此示例的原始JRXML:
<queryString language="xPath">
<![CDATA[/order]]>
</queryString>
<field name="name" class="java.lang.String">
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
<field name="quantity" class="java.lang.String">
<fieldDescription><![CDATA[quantity]]></fieldDescription>
</field>
<field name="item" class="java.lang.String">
<fieldDescription><![CDATA[item]]></fieldDescription>
</field>
<field name="price" class="java.lang.String">
<fieldDescription><![CDATA[price]]></fieldDescription>
</field>
<variable name="aggregated" class="java.lang.Number">
<variableExpression><![CDATA[java.lang.Integer.parseInt($F{quantity}) * java.lang.Float.parseFloat($F{price})]]></variableExpression>
</variable>
<detail>
<band height="125" splitType="Stretch">
<textField>
<reportElement x="0" y="0" width="535" height="20"/>
<textElement/>
<textFieldExpression><![CDATA["Dear " + $F{name} + ","]]></textFieldExpression>
</textField>
<textField>
<reportElement x="0" y="40" width="100" height="20" backcolor="#CCCCCC"/>
<textElement textAlignment="Right"/>
<textFieldExpression><![CDATA[$F{quantity}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="100" y="40" width="235" height="20" backcolor="#CCCCCC"/>
<textElement textAlignment="Center"/>
<textFieldExpression><![CDATA[$F{item}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="335" y="40" width="100" height="20" backcolor="#CCCCCC"/>
<textElement textAlignment="Right"/>
<textFieldExpression><![CDATA[$F{price}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="0" y="75" width="535" height="35"/>
<textElement/>
<textFieldExpression><![CDATA["Please pay " + $V{aggregated} + " soon."]]></textFieldExpression>
</textField>
<textField>
<reportElement x="435" y="40" width="100" height="20" backcolor="#CCCCCC"/>
<textElement textAlignment="Right"/>
<textFieldExpression><![CDATA[$V{aggregated}]]></textFieldExpression>
</textField>
</band>
</detail>
现在对于像这样的样本的多发票XML:
<orders>
<order>
<name>Mr. Smith</name>
<quantity>2</quantity>
<item>bike</item>
<price>200</price>
</order>
<order>
<name>Mr. Fisher</name>
<quantity>3</quantity>
<item>box</item>
<price>10</price>
</order>
</orders>
您在JRXML中所要做的就是更改xPath表达式以匹配所有order
元素,并在数据集之间添加分页符:
...
<queryString language="xPath">
<![CDATA[//order]]>
</queryString>
...
<detail>
<band height="125" splitType="Stretch">
...
<break>
<reportElement x="0" y="124" width="535" height="1"/>
</break>
</band>
</detail>
即使order
包含更多动态数据,例如可变数量的项目,只要order元素定义主数据集(可变数量的项目可能由在子数据集上工作的某个表元素处理),它就可能同样容易。
在OP提供他的JRXML文件之后,事实证明它基本上是上面指出的简单类型。但是需要进行小的修正:
OP的JRXML仅使用两个部分,标题和页脚。后者确实用于页面页脚材料,但前者不用于标题,而是用于实际发票主体,即用于不打印一次(作为标题)但多次打印数据集的材料!因此,要为多发票输出做好准备,首先必须将 title 频段移动为 detail 频段:
...
</background>
<title>
<band height="616" splitType="Stretch">
...
</band>
</title>
<pageFooter>
...
变为
...
</background>
<detail>
<band height="616" splitType="Stretch">
...
</band>
</detail>
<pageFooter>
...
由于此频段的大小,这已经足以使JRXML为多个order
输入做好准备:在下一个详细信息部分之前自动发生分页信息对于下一个数据集,因为这些波段中不超过一个适合页面而波段splitType
是&#34;拉伸&#34;。
答案 1 :(得分:0)
单个pdf的输出不是重点。 关键是如何使用每个发票的分页符以及标题/波段的使用,我认为。