XML - XSL:每页限制行数的PDF生成

时间:2018-05-07 12:57:21

标签: xml xslt xslt-1.0

我需要使用XSL样式表从XML生成PDF。我有更多来自XML的行。所以在我的PDF中我必须每页只显示4行。

就像,如果我的XML中有10行,在我的PDF中它应该显示为每页4个,总共3个PDF页面和每页4个。

第1页:4行 第2页:4行 第3页:2行

请找到我的XML:

<receipt>
    <order>
        <page>
            <line_number>1</line_number>
            <product_code>S10</product_code>
            <line_number>2</line_number>
            <product_code>S20</product_code>
            <line_number>3</line_number>
            <product_code>S92</product_code>
            <line_number>4</line_number>
            <product_code>S31</product_code>
            <line_number>5</line_number>
            <product_code>S31</product_code>
       </page>
       <page>
            <line_number>6</line_number>
            <product_code>S31</product_code>
            <line_number>7</line_number>
            <product_code>S31</product_code>
            <line_number>8</line_number>
            <product_code>S31</product_code>
            <line_number>9</line_number>
            <product_code>S31</product_code>
            <line_number>10</line_number>
            <product_code>S31</product_code>
        </page>
    </order>
</receipt>

请立即查找XSL模板,它在一个页面中显示所有10行。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"   
                              xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="date">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    <xsl:template match="/receipt">
        <html>
            <head>
            <style>@page {size: a4 landscape;}</style>
            </head>
            <body>

                <table >
                    <thead>
                        <tr >
                            <th >Line</th>
                            <th>Item Code</th>
                        </tr>
                    </thead>
                <tbody>
                  <xsl:for-each select="order/page/line_number">
                            <tr style="font-size: 9px; ">
                                <td><xsl:value-of select="." /></td>
                                <td><xsl:value-of select="following-sibling::product_code[1]" /></td>
                            </tr>
                 </xsl:for-each>
                </tbody>
                </table>
                <br />
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:0)

如果你想用HTML做,那么就像我在一个类似的问题中告诉你的那样,一种方法是生成任意数量的tbody部分,并使用CSS page-break-after: always tbody s:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0">

  <xsl:param name="rows-per-page" select="4"/>

  <xsl:output method="html" indent="yes" html-version="5"/>

    <xsl:template match="/receipt">
        <html>
            <head>
            <style>
                @page {size: a4 landscape;}
                tbody { page-break-after: always; }
            </style>
            </head>
            <body>

                <table >
                    <thead>
                        <tr >
                            <th >Line</th>
                            <th>Item Code</th>
                        </tr>
                    </thead>
                  <xsl:for-each-group select="order/page/line_number" group-adjacent="(position() - 1) idiv $rows-per-page">
                      <tbody>
                          <xsl:apply-templates select="current-group()"/>
                      </tbody>
                 </xsl:for-each-group>
                </table>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="line_number">
        <tr style="font-size: 9px;">
            <td><xsl:value-of select="." /></td>
            <td><xsl:value-of select="following-sibling::product_code[1]" /></td>
        </tr>
    </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/jyH9rM7

该示例使用XSLT 2/3 for-each-group将所需数量的项目包装在tbody中,但如果需要,可以在XSLT 1中完成相同的工作。您可以使用Saxon 9 for Java或.NET或C / C ++运行XSLT 2或3。