如何创建包含多张发票的单个pdf

时间:2014-05-21 23:55:37

标签: jasper-reports

我将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

2 个答案:

答案 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的输出不是重点。 关键是如何使用每个发票的分页符以及标题/波段的使用,我认为。