XSL-FO 文档:在具体的 fo:table-row 中插入 break-before="page" 属性

Posted

技术标签:

【中文标题】XSL-FO 文档:在具体的 fo:table-row 中插入 break-before="page" 属性【英文标题】:XSL-FO Document: Inserting a break-before="page" attribute in a concrete fo:table-row 【发布时间】:2019-04-13 23:44:32 【问题描述】:

我有一个 XSL-FO 文档。这个文档有很多嵌套的 fo:table。 有一个内部 fo:table 有 9 列和很多行,在这个例子中,第一行是表头和其他行,从 1 到 20 的内容。在下面的示例中,您可以看到作为注释,对于每个 FOPTable (fo:table),它被指示一个唯一标识符,但对于同一个表,该标识符并不总是相同的。它由创建此 XSL-FO 文档的应用程序随机生成。

我的问题是:我想找到第一个列标题值设置为 HEADER_COL1 的表(此值始终相同),在此示例中,表标识为 id:997(请记住,我无法搜索表根据此标识符,因为每次应用程序创建 XSL-FO 文档时它都会随机更改)。一旦我在下面找到了我想要的表:

    如何为混凝土插入属性 break-before="page" fo:table-row item? 我想获取这个内表的行数。

例如:

例如,如果我想为第 15 个 fo:table-row 项目插入此属性,我该怎么做?我想要一个参数化的泛型方法,它以一个数字作为参数,指示 fo:table-row 放置此属性的位置。

我知道我可以使用以下方法阅读 XSL-FO 文档:

string xmlFile = File.ReadAllText(@"C:\Temp\MyXSLFO.xml");
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(xmlFile);

但一旦加载,我不知道如何做到这一点。

注意:我使用的是 Visual Studio 2008、C# 和 .NET 3.5。

<?xml version="1.0" encoding="ISO-8859-1" ?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

<fo:page-sequence force-page-count="no-force" master-reference="first" initial-page-number="1">
<fo:flow flow-name="xsl-region-body">
<!--  begin table FOPTable  id: 987 cur_size: 28.7 prv_size: 20.0 prev: <none> cols: 2 locks: 2 flow:FOPFlow:  type: BodyFlow size:4 region:FOPRegion:  type:3 extent:0.0  
  --> 
<fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">
</fo:table>
<!--  endof table id FOPTable  id: 987 cur_size: 28.7 prv_size: 20.0 prev: <none> cols: 2 locks: 5 flow:FOPFlow:  type: BodyFlow size:4 region:FOPRegion:  type:3 extent:0.0  
  --> 
<!--  begin table FOPTable  id: 992 cur_size: 28.7 prv_size: 20.0 prev: <none> cols: 2 locks: 2 flow:FOPFlow:  type: BodyFlow size:3 region:FOPRegion:  type:3 extent:0.0  
  --> 
<fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">
</fo:table>
<!--  endof table id FOPTable  id: 992 cur_size: 28.7 prv_size: 20.0 prev: <none> cols: 2 locks: 4 flow:FOPFlow:  type: BodyFlow size:3 region:FOPRegion:  type:3 extent:0.0  
  --> 
<!--  begin table FOPTable  id: 995 cur_size: 28.7 prv_size: 0.0 prev: <none> cols: 2 locks: 2 flow:FOPFlow:  type: BodyFlow size:2 region:FOPRegion:  type:3 extent:0.0  
  --> 
<fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">

<!--  begin table FOPTable  id: 996 cur_size: 0.0 prv_size: 20.41 prev: 995 cols: 1 locks: 2 flow:null  
  --> 
<fo:table font-size="8pt" font-family="sans-serif" table-layout="fixed">

<!--  begin table FOPTable  id: 997 cur_size: 0.0 prv_size: 20.409999999999997 prev: 996 cols: 9 locks: 5 flow:null  
  --> 
<fo:table font-size="8pt" font-family="sans-serif" table-layout="fixed">
  <fo:table-column column- /> 
  <fo:table-column column- /> 
  <fo:table-column column- /> 
  <fo:table-column column- /> 
  <fo:table-column column- /> 
  <fo:table-column column- /> 
  <fo:table-column column- /> 
  <fo:table-column column- /> 
  <fo:table-column column- /> 
<fo:table-header>
<fo:table-row>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL1</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL2</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL3</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL4</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL5</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL6</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL7</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL8</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
  <fo:block>HEADER_COL9</fo:block> 
  </fo:table-cell>
  </fo:table-row>
  </fo:table-header>
<fo:table-body>
<fo:table-row>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW1_COL1_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW1_COL2_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW1_COL3_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW1_COL4_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW1_COL5_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW1_COL6_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-right="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block text-align="end">ROW1_COL7_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW1_COL8_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW1_COL9_VALUE</fo:block> 
  </fo:table-cell>
  </fo:table-row>


<!-- A LOT OF ROWS HERE -->

<!-- I want to insert a break-before attribute as below -->
<fo:table-row break-before="page">
<!-- columns here -->
</fo:table-row>

<!-- MORE ROWS HERE -->

<!-- LAST ROW NEXT -->
<fo:table-row>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW20_COL1_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW20_COL2_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW20_COL3_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW20_COL4_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW20_COL5_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW20_COL6_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-right="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block text-align="end">ROW20_COL7_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW20_COL8_VALUE</fo:block> 
  </fo:table-cell>
<fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" font-family="sans-serif" font-size="7pt">
  <fo:block>ROW20_COL9_VALUE</fo:block> 
  </fo:table-cell>
  </fo:table-row>
  </fo:table-body>
  </fo:table>
<!--  endof table id FOPTable  id: 997 cur_size: 28.7 prv_size: 20.409999999999997 prev: 996 cols: 9 locks: 6 flow:null  
  --> 
</fo:table>

</fo:table>

</fo:flow>
</fo:page-sequence>
</fo:root>

【问题讨论】:

我会使用 XSLT。由于您使用的是 VS2008,请参阅w3.org/TR/1999/REC-xslt-19991116。您可以为您的上下文制作一个模板,为属性添加属性,并制作一个身份模板,将文档的其余部分复制到结果树中。 将表格嵌套 3 层似乎过于复杂。这真的有必要吗? 【参考方案1】:

获取您的数据并删除所有单元格和其他不重要的内容,您可以简单地将标识 XSL 应用于 XSL FO 并仅修改目标行。

从这个 XML 开始:

<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

    <fo:page-sequence force-page-count="no-force" master-reference="first" initial-page-number="1">
        <fo:flow flow-name="xsl-region-body">
            <fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">
            </fo:table>
            <fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">
            </fo:table>
            <fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">
                <fo:table font-size="8pt" font-family="sans-serif" table-layout="fixed">
                    <fo:table font-size="8pt" font-family="sans-serif" table-layout="fixed">
                        <fo:table-column column- /> 
                        <fo:table-column column- /> 
                        <fo:table-column column- /> 
                        <fo:table-column column- /> 
                        <fo:table-column column- /> 
                        <fo:table-column column- /> 
                        <fo:table-column column- /> 
                        <fo:table-column column- /> 
                        <fo:table-column column- /> 
                        <fo:table-header>
                            <fo:table-row>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL1</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL2</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL3</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL4</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL5</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL6</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL7</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL8</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL9</fo:block> 
                                </fo:table-cell>
                            </fo:table-row>
                        </fo:table-header>
                        <fo:table-body>
                            <fo:table-row/>
                            <fo:table-row/>
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                        </fo:table-body>
                    </fo:table>
                </fo:table>

            </fo:table>

        </fo:flow>
    </fo:page-sequence>
</fo:root>

并应用此 XSL,它按原样输出所有内容,除了在目标表的第 12 行插入分页符的模板:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fo="http://www.w3.org/1999/XSL/Format"
    version="2.0">
    <xsl:param name="breakrow" select="12"/>

    <xsl:template match="fo:table-row">
        <xsl:variable name="rowcnt" select="count(preceding-sibling::fo:table-row)"/>
        <xsl:choose>
            <xsl:when test="parent::fo:table-header">
                <fo:table-row>
                    <xsl:apply-templates/>
                </fo:table-row>
            </xsl:when>
            <xsl:when test="$rowcnt = $breakrow and ancestor::fo:table[1]/fo:table-header/fo:table-row[1]/fo:table-cell[1]/fo:block/text() = 'HEADER_COL1'">
                <fo:table-row break-before="page"/>
            </xsl:when>
            <xsl:otherwise>
                <fo:table-row/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

结果是这样的:

<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

    <fo:page-sequence force-page-count="no-force" master-reference="first" initial-page-number="1">
        <fo:flow flow-name="xsl-region-body">
            <fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">
            </fo:table>
            <fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">
            </fo:table>
            <fo:table font-size="8pt" font-family="sans-serif" space-before.optimum="0.05cm" table-layout="fixed">
                <fo:table font-size="8pt" font-family="sans-serif" table-layout="fixed">
                    <fo:table font-size="8pt" font-family="sans-serif" table-layout="fixed">
                        <fo:table-column column-/> 
                        <fo:table-column column-/> 
                        <fo:table-column column-/> 
                        <fo:table-column column-/> 
                        <fo:table-column column-/> 
                        <fo:table-column column-/> 
                        <fo:table-column column-/> 
                        <fo:table-column column-/> 
                        <fo:table-column column-/> 
                        <fo:table-header>
                            <fo:table-row>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL1</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL2</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL3</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL4</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL5</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL6</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL7</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL8</fo:block> 
                                </fo:table-cell>
                                <fo:table-cell padding-top="2.0pt" padding-left="2.0pt" border-style="solid" border- border-color="#000000" background-color="#D6DEE7" font-family="sans-serif">
                                    <fo:block>HEADER_COL9</fo:block> 
                                </fo:table-cell>
                            </fo:table-row>
                        </fo:table-header>
                        <fo:table-body>
                            <fo:table-row/>
                            <fo:table-row/>
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row break-before="page"/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                            <fo:table-row/>                            
                        </fo:table-body>
                    </fo:table>
                </fo:table>

            </fo:table>

        </fo:flow>
    </fo:page-sequence>
</fo:root>

我将 12 作为参数传入,并假设您只有一个位置……第 12 行。您当然可以使用“mod”并每隔 12 行执行一次或任何您想要的。

例如:

 <xsl:when test="$rowcnt mod $breakrow = $breakrow - 1 and ancestor::fo:table[1]/fo:table-header/fo:table-row[1]/fo:table-cell[1]/fo:block/text() = 'HEADER_COL1'">

当然,您可以只添加到行中以获取所有单元格内容输出。

【讨论】:

很好的方法,出于好奇,我可以应用更多 吗?例如:如果 $rowcnt >10 并且 $rowcnt =20 并且 $rowcnt 当然,但通常情况下,我会使用 mod 执行我上次写的操作,mod 会在每“x”行插入一个中断 如果答案帮助您考虑适当地标记问题。 答案有所帮助,但您能告诉我如何执行我之前评论中解释的操作吗?

以上是关于XSL-FO 文档:在具体的 fo:table-row 中插入 break-before="page" 属性的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 XSL-FO 在 PDF 中添加分页符?

在 XSL-FO 中使用外部 CSS

有免费的 XSL-FO 编辑器吗? [关闭]

XSL-FO 忽略最后一个分页符但是如何?

pdfbox / XSL + FOP 转换 PDF文档

pdfbox / XSL + FOP 转换 PDF文档