处理xsl fo中的动态列numbler

时间:2013-08-21 06:41:01

标签: pdf xsl-fo apache-fop

如何使用xsl fo创建具有动态列数的表。列数因每个输入文件而异,但对于单个输入文件是固定的。

以下是xml示例

<root>
<ColNo>3</ColNo>
<Objects>
<object id="1">
 <prop1 old="5" new="7">
 <prop2 old="2" new="1">
 <prop3 old="3" new="6">
</object>
</Objects>
</root>

我想要一张如下表格

Obj1
------------------------------------------
 prop1     | prop2          | prop3 
-------------------------------------------
old | new  |  old | new     | old  | new
-------------------------------------------
5   | 7    |  2   |  1      | 3    | 6

我遇到了number-columns-repeated属性..但无法理解如何使用它..

如果有更好的方法,请告诉我。

感谢。

1 个答案:

答案 0 :(得分:1)

你没有表明你已经尝试了多少,但我怀疑并不多,因为输入数据不是很好。而且您也没有说明如何表示多行数据,所以我通过修改添加其他信息的数据来猜测。

随后是完整的解决方案。它使用了两种可用的行填充技术,类似于我在教室中使用的插图(以及练习)。

当我通过符合要求的XSL-FO处理器运行下面的输出时,我按照你的要求概述了表格。

t:\ftemp>type table.xml 
<root>
<ColNo>3</ColNo>
<Objects>
<object id="1">
 <prop1 old="5" new="7"/>
 <prop2 old="2" new="1"/>
 <prop3 old="3" new="6"/>
 <prop1 old="15" new="17"/>
 <prop2 old="12" new="11"/>
 <prop3 old="13" new="16"/>
</object>
</Objects>
</root>

t:\ftemp>call xslt table.xml table.xsl table.fo 

t:\ftemp>type table.fo 
<?xml version="1.0" encoding="utf-8"?>
<root xmlns="http://www.w3.org/1999/XSL/Format" font-family="Times" font-size="20pt">
   <layout-master-set>
      <simple-page-master master-name="frame" page-height="210mm" page-width="297mm" margin-top="1cm" margin-bottom="1cm" margin-left="1cm" margin-right="1cm">
         <region-body region-name="frame-body"/>
      </simple-page-master>
   </layout-master-set>
   <page-sequence master-reference="frame">
      <flow flow-name="frame-body">
         <block>Obj1</block>
         <table border="solid 1pt" text-align="center">
            <table-header>
               <table-row>
                  <table-cell number-columns-spanned="2" border="solid 1pt">
                     <block>prop1</block>
                  </table-cell>
                  <table-cell number-columns-spanned="2" border="solid 1pt">
                     <block>prop2</block>
                  </table-cell>
                  <table-cell number-columns-spanned="2" border="solid 1pt">
                     <block>prop3</block>
                  </table-cell>
               </table-row>
               <table-row>
                  <table-cell border="solid 1pt">
                     <block>old</block>
                  </table-cell>
                  <table-cell border="solid 1pt">
                     <block>new</block>
                  </table-cell>
                  <table-cell border="solid 1pt">
                     <block>old</block>
                  </table-cell>
                  <table-cell border="solid 1pt">
                     <block>new</block>
                  </table-cell>
                  <table-cell border="solid 1pt">
                     <block>old</block>
                  </table-cell>
                  <table-cell border="solid 1pt">
                     <block>new</block>
                  </table-cell>
               </table-row>
            </table-header>
            <table-body>
               <table-cell border="solid 1pt">
                  <block>5</block>
               </table-cell>
               <table-cell border="solid 1pt">
                  <block>7</block>
               </table-cell>
               <table-cell border="solid 1pt">
                  <block>2</block>
               </table-cell>
               <table-cell border="solid 1pt">
                  <block>1</block>
               </table-cell>
               <table-cell border="solid 1pt">
                  <block>3</block>
               </table-cell>
               <table-cell border="solid 1pt" ends-row="true">
                  <block>6</block>
               </table-cell>
               <table-cell border="solid 1pt">
                  <block>15</block>
               </table-cell>
               <table-cell border="solid 1pt">
                  <block>17</block>
               </table-cell>
               <table-cell border="solid 1pt">
                  <block>12</block>
               </table-cell>
               <table-cell border="solid 1pt">
                  <block>11</block>
               </table-cell>
               <table-cell border="solid 1pt">
                  <block>13</block>
               </table-cell>
               <table-cell border="solid 1pt" ends-row="true">
                  <block>16</block>
               </table-cell>
            </table-body>
         </table>
      </flow>
   </page-sequence>
</root>
t:\ftemp>type table.xsl 
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/1999/XSL/Format" 
                version="1.0">

<xsl:output indent="yes"/>

<xsl:template match="/">
<root font-family="Times" font-size="20pt">

  <layout-master-set>
    <simple-page-master master-name="frame" 
                        page-height="210mm" page-width="297mm" 
                        margin-top="1cm" margin-bottom="1cm" 
                        margin-left="1cm" margin-right="1cm">
      <region-body region-name="frame-body"/>
    </simple-page-master>
  </layout-master-set>

  <page-sequence master-reference="frame">
    <flow flow-name="frame-body">
      <!--reposition to the top of table data-->
      <xsl:for-each select="root/Objects/object">
        <block>Obj<xsl:value-of select="@id"/></block>
        <table border="solid 1pt" text-align="center">
          <table-header>
            <!--header rows - use row-based row-grouping strategy-->
            <table-row>
              <xsl:for-each select="*[position() &lt;= /root/ColNo]">
                <table-cell number-columns-spanned="2" border="solid 1pt">
                  <block><xsl:value-of select="name(.)"/></block>
                </table-cell>
              </xsl:for-each>
            </table-row>
            <table-row>
              <xsl:for-each select="*[position() &lt;= /root/ColNo]">
                <table-cell border="solid 1pt"><block>old</block></table-cell>
                <table-cell border="solid 1pt"><block>new</block></table-cell>
              </xsl:for-each>
            </table-row>
          </table-header>
          <table-body>
            <!--body rows - use cell-based row-grouping strategy-->
            <xsl:apply-templates select="*"/>
          </table-body>
        </table>
      </xsl:for-each>
    </flow>
  </page-sequence>
</root>
</xsl:template>

<xsl:template match="object/*">
  <table-cell border="solid 1pt">
    <block><xsl:value-of select="@old"/></block>
  </table-cell>
  <table-cell border="solid 1pt">
    <xsl:if test="position() mod /root/ColNo = 0">
      <!--every time the last item of a row is encountered, signal end-->
      <xsl:attribute name="ends-row">true</xsl:attribute>
    </xsl:if>
    <block><xsl:value-of select="@new"/></block>
  </table-cell>
</xsl:template>

</xsl:stylesheet>


t:\ftemp>start table.fo 

t:\ftemp>rem Done!