【问题标题】:Wrapping a table in PDF using XSLT that exceeds the page size使用超出页面大小的 XSLT 在 PDF 中包装表格
【发布时间】:2019-05-09 14:31:54
【问题描述】:

我正在尝试在标准 A4 页面中适应基于 XML 文件的多列表。问题是超出边距的列没有出现在生成的文件中(如预期的那样)。我想让外列出现在下一行,但是我找不到任何方法来做到这一点。我试图简单地更改字体大小或页面的方向,但这些解决方案只是一种绕过方式,当列数较高时会失败。 这甚至可以使用普通的 XSLT 1.0 来做到这一点吗? 我的代码如下:

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

<xsl:template match="/">
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
        <fo:layout-master-set>
            <fo:simple-page-master master-name="A4" page-height="29cm" page-width="21cm"
                margin-bottom="2cm" margin-top="2cm" margin-left="1.5cm" margin-right="1.5cm">
                <fo:region-body margin-top="1cm"/>
                <fo:region-before extent="1.5cm"/>
                <fo:region-after extent="1.5cm"/>
            </fo:simple-page-master>
        </fo:layout-master-set>

        <fo:page-sequence master-reference="A4">


            <fo:static-content flow-name="xsl-region-before">
                <fo:block>Stylistique suppliers report. Generated <xsl:value-of
                        select="report/statistics/dateOfGeneration"/></fo:block>
            </fo:static-content>
            <fo:static-content flow-name="xsl-region-after">
                <fo:block>Page <fo:page-number/></fo:block>
            </fo:static-content>

            <fo:flow flow-name="xsl-region-body">
                <fo:block>
                    <fo:external-graphic src="logo.jpg" width="auto" height="auto"
                        content-height="300px"/>
                </fo:block>

                <fo:block linefeed-treatment="preserve">Summary table</fo:block>
                <fo:table>
                    <xsl:for-each select="report/suppliers/supplier">
                        <fo:table-column column-width="30mm"/>
                    </xsl:for-each>

                    <fo:table-header>
                        <fo:table-row>
                            <xsl:for-each select="report/suppliers/supplier">

                                <fo:table-cell>
                                    <fo:block font-weight="bold" width="30mm" font-size="8px">
                                        <xsl:value-of select="name"/>
                                    </fo:block>
                                </fo:table-cell>
                            </xsl:for-each>
                        </fo:table-row>
                    </fo:table-header>

                    <fo:table-body>

                        <fo:table-row>
                            <xsl:for-each select="report/suppliers/supplier">
                                <fo:table-cell>
                                    <xsl:for-each select="productList/product">
                                        <fo:block>
                                            <xsl:value-of select="name"/>
                                        </fo:block>
                                        <fo:block>
                                            <xsl:value-of select="priceInPLN"/>
                                        </fo:block>

                                    </xsl:for-each>
                                </fo:table-cell>

                            </xsl:for-each>
                        </fo:table-row>

                    </fo:table-body>
                </fo:table>

            </fo:flow>

        </fo:page-sequence>
    </fo:root>
</xsl:template>

</xsl:stylesheet>

【问题讨论】:

  • 您还应该提供源 XML 文件。
  • 每列总是30mm吗?
  • @TonyGraham 是的,问题是如果列大小等于30mm,一些单元格内容相互重叠,但是如果我增加宽度,剩余的单元格会从文档中剪切,所以这就是为什么我需要包裹桌子。
  • 您使用的是哪种格式化程序?
  • @TonyGraham Apache FOP 用于 FO,Saxon6.5.5 用于 XSLT

标签: xml pdf xslt-1.0 transformation xsl-fo


【解决方案1】:

对表格行使用fo:block,对每个表格单元格使用fo:inline-container(具有固定宽度)来伪造表格。

您可能无法让“单元格”具有相同的高度,但您想要做的事情超出了fo:table 的范围。

或者,如果您确切知道桌子应该在哪里休息,您可以省略 fo:table-row 并使用 fo:table-cell 上的 starts-rowends-row 属性来导致您的休息。


由于您使用的是 XSLT 1.0 并且您知道表格单元格的宽度,因此您可以使用 Muenchian Grouping (https://stackoverflow.com/search?q=muenchian) 对每行适当数量的单元格进行分组。 (如果您使用 XSLT 2.0 或 XSLT 3.0 并且可以使用xsl:for-each-group,这将简单得多。)

此外,还有多个关于在表格单元格中换行的 SO 问题已得到解答,包括:

(如果您使用 XSLT 2.0 或 XSLT 3.0(或使用 AH Formatter,FWIW),则换行文本也会更简单。请参阅,例如,https://stackoverflow.com/a/33689540/4092205。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多