XML - XSL: генерация PDF с ограниченным количеством строк на странице - PullRequest
0 голосов
/ 07 мая 2018

У меня есть требование к генерации PDF из XML с использованием таблицы стилей XSL. У меня есть больше строк из XML., Поэтому в моем PDF я должен отображать только 4 строки на странице.

Например, если у меня есть 10 строк в моем XML, в моем 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 голосов
/ 07 мая 2018

Если вы хотите сделать это с 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 используется для каждой группы, чтобы обернуть требуемое количество элементов в tbody, но с некоторыми дополнительными усилиями то же самое можно сделать в XSLT 1, если это необходимо. Вы можете запустить XSLT 2 или 3 с Saxon 9 для Java или .NET или C / C ++.

...