XSL FO生成动态列

时间:2016-06-20 07:07:30

标签: xslt-1.0 xsl-fo

我正在使用XSL FO使用FOP.NET生成PDF。我需要根据从数据库中获取的XML动态生成列。下面是我的XML格式,我需要动态生成列,而不是在xsl fo样式表中对它们进行硬编码。非常感谢你的帮助。

编辑:

我的目标是构建20种类型的报告,并希望以1 xsl fo动态执行。这可能吗?或者我需要有20个xsl fo文件来生成报告吗?请建议一个最佳的方法来做到这一点..我不想使用itextsharp和其他付费工具。 (只有XSL FO)

下面是我从SQL Server获取的XML。

    <?xml version="1.0" standalone="yes"?>

<Products>
<Product id="1" name="Rendezvous with Rama by Arthur C. Clarke" price="15" quantity="3" description="An all-time science fiction classic, Rendezvous with Rama is also one of Clarke's best novels--it won the Campbell, Hugo, Jupiter, and Nebula Awards." />
<Product id="2" name="Dune Chronicles by Frank Herbert" price="60" quantity="5" description="Dune is one of the most famous science fiction novels ever written, and deservedly so. The setting is elaborate and ornate, the plot labyrinthine, the adventures exciting. Five sequels follow." />
<Product id="3" name="Schindler's List by Thomas Keneally" price="21" quantity="6" description="A mesmerizing novel based on the true story of Oskar Schindler, a German industralist who saved and succored more than 1000 Jews from the Nazis at enormous financial and emotional expense." />
<Product id="4" name="Middle Passage by Charles Johnson" price="17" quantity="4" description="In this savage parable of the African American experience, Rutherford Calhoun, a newly freed slave eking out a living in New Orleans in 1830, hops aboard a square rigger to evade the prim Boston schoolteacher who wants to marry him. But the Republic turns out to be a slave clipper bound for Africa." />
<Product id="5" name="Underworld:A Novel by Don DeLillo" price="14" quantity="3" description="Underworld opens with a breathlessly graceful prologue set during the final game of the Giants-Dodgers pennant race in 1951. Written in what DeLillo calls super-omniscience the sentences sweep from young Cotter Martin as he jumps the gate to the press box, soars over the radio waves, runs out to the diamond, slides in on a fast ball, pops into the stands where J. It's an absolutely thrilling literary moment." />
<Product id="6" name="Stones from the River by Ursula Hegi" price="16" quantity="4" description="Ursula Hegi's Stones from the River clamors for comparisons to Gunter Grass's The Tin Drum; her protagonist Trudi Montag--like the unforgettable Oskar Mazerath--is a dwarf living in Germany during the two World Wars. " />
<Product id="7" name="Empire of the Sun by J. G. Ballard" price="12" quantity="3" description="Ballard's enduring novel of war and deprivation, internment camps and death marches, and starvation and survival is an honest coming-of-age tale set in a world thrown utterly out of joint." />    
</Products>

列id,名称,价格,数量,描述需要动态绑定。任何有关示例的帮助都将非常感激。

我的硬编码XSL样式表

    <fo:table border-bottom-width="5pt" width="1500pt" border-bottom-color="rgb(0,51,102)" border-collapse="collapse" background-color="rgb(255,255,255)">
            <fo:table-column column-width="proportional-column-width(6.77)" column-number="1"/>
            <fo:table-column column-width="proportional-column-width(5.09)" column-number="2"/>
            <fo:table-column column-width="proportional-column-width(5.63)" column-number="3"/>
            <fo:table-column column-width="proportional-column-width(5.94)" column-number="4"/>
            <fo:table-column column-width="proportional-column-width(5.79)" column-number="5"/>

            <fo:table-header>
              <fo:table-row height="20.81pt" display-align="center" overflow="hidden">
                <fo:table-cell text-align="center" border-left-color="rgb(0, 0, 0)" border-left-style="solid" border-left-width="1pt" border-right-color="rgb(0, 0, 0)" border-right-style="solid" border-right-width="1pt" border-top-color="rgb(0, 0, 0)" border-top-style="solid" border-top-width="1pt" border-bottom-color="rgb(0, 0, 0)" border-bottom-style="solid" border-bottom-width="1pt" padding-left="2pt" padding-right="2pt" padding-top="2pt" padding-bottom="2pt">
                  <fo:block color="rgb(0,0,0)" text-align="center" font-weight="normal" font-family="{$columnFontType}" font-size="{$columnFontSize}">Transaction</fo:block>
                  <fo:block color="rgb(0,0,0)" text-align="center" font-weight="normal" font-family="{$columnFontType}" font-size="{$columnFontSize}">Date</fo:block>
                </fo:table-cell>
                <fo:table-cell text-align="center" border-left-color="rgb(0, 0, 0)" border-left-style="solid" border-left-width="1pt" border-right-color="rgb(0, 0, 0)" border-right-style="solid" border-right-width="1pt" border-top-color="rgb(0, 0, 0)" border-top-style="solid" border-top-width="1pt" border-bottom-color="rgb(0, 0, 0)" border-bottom-style="solid" border-bottom-width="1pt" padding-left="2pt" padding-right="2pt" padding-top="2pt" padding-bottom="2pt">
                  <fo:block color="rgb(0,0,0)" text-align="center" font-weight="normal" font-family="{$columnFontType}" font-size="{$columnFontSize}">Cust ID</fo:block>
                </fo:table-cell>
                <fo:table-cell text-align="center" border-left-color="rgb(0, 0, 0)" border-left-style="solid" border-left-width="1pt" border-right-color="rgb(0, 0, 0)" border-right-style="solid" border-right-width="1pt" border-top-color="rgb(0, 0, 0)" border-top-style="solid" border-top-width="1pt" border-bottom-color="rgb(0, 0, 0)" border-bottom-style="solid" border-bottom-width="1pt" padding-left="2pt" padding-right="2pt" padding-top="2pt" padding-bottom="2pt">
                  <fo:block color="rgb(0,0,0)" text-align="center" font-weight="normal" font-family="{$columnFontType}" font-size="{$columnFontSize}">Cust No</fo:block>
                </fo:table-cell>
                <fo:table-cell text-align="center" border-left-color="rgb(0, 0, 0)" border-left-style="solid" border-left-width="1pt" border-right-color="rgb(0, 0, 0)" border-right-style="solid" border-right-width="1pt" border-top-color="rgb(0, 0, 0)" border-top-style="solid" border-top-width="1pt" border-bottom-color="rgb(0, 0, 0)" border-bottom-style="solid" border-bottom-width="1pt" padding-left="2pt" padding-right="2pt" padding-top="2pt" padding-bottom="2pt">
                  <fo:block color="rgb(0,0,0)" text-align="center" font-weight="normal" font-family="{$columnFontType}" font-size="{$columnFontSize}">Client Name</fo:block>
                </fo:table-cell>
                <fo:table-cell text-align="center" border-left-color="rgb(0, 0, 0)" border-left-style="solid" border-left-width="1pt" border-right-color="rgb(0, 0, 0)" border-right-style="solid" border-right-width="1pt" border-top-color="rgb(0, 0, 0)" border-top-style="solid" border-top-width="1pt" border-bottom-color="rgb(0, 0, 0)" border-bottom-style="solid" border-bottom-width="1pt" padding-left="2pt" padding-right="2pt" padding-top="2pt" padding-bottom="2pt">
                  <fo:block color="rgb(0,0,0)" text-align="center" font-weight="normal" font-family="{$columnFontType}" font-size="{$columnFontSize}">Long ID</fo:block>
                </fo:table-cell>
              </fo:table-row>
            </fo:table-header>
            <fo:table-body>
              <fo:table-row display-align="before">
                <fo:table-cell text-align="center" border-top-color="rgb(0, 0, 0)" border-top-style="solid" border-left-width="1pt" border-right-width="1pt" border-top-width="1pt" border-bottom-width="1pt" padding-left="2pt" padding-right="2pt" padding-top="2pt" padding-bottom="2pt">
                  <fo:block>
                    1
                  </fo:block>
                </fo:table-cell>
                <fo:table-cell text-align="left" border-top-color="rgb(0, 0, 0)" border-top-style="solid" border-left-width="1pt" border-right-width="1pt" border-top-width="1pt" border-bottom-width="1pt" padding-left="2pt" padding-right="2pt" padding-top="2pt" padding-bottom="2pt">
                  <fo:block>
                    Rendezvous with Rama by Arthur C. Clarke
                  </fo:block>
                </fo:table-cell>
                <fo:table-cell text-align="right" border-top-color="rgb(0, 0, 0)" border-right-color="rgb(0, 0, 0)" border-top-style="solid" border="1pt " padding="2pt">
                  <fo:block>
                    3
                  </fo:block>
                </fo:table-cell>
                <fo:table-cell text-align="right" border-top-style="solid" border="1pt rgb(0, 0, 0)" padding="2pt">
                  <fo:block>
                    $15.00
                  </fo:block>
                </fo:table-cell>
                <fo:table-cell text-align="left" border-top-color="rgb(0, 0, 0)" border-left-color="rgb(0, 0, 0)" border-top-style="solid" border="1pt " padding="2pt">
                  <fo:block>
                    An all-time science fiction classic, Rendezvous with Rama is also one of Clarke's best novels--it won the Campbell, Hugo, Jupiter, and Nebula Awards.
                  </fo:block>
                </fo:table-cell>
              </fo:table-row>
            </fo:table-body>
          </fo:table>

谢谢, 帕

2 个答案:

答案 0 :(得分:0)

下面是您的示例的XSLT 1.0样式表。如果您需要为此生成20个变体,我建议您为每个报告提供必要信息的XML表示 - 例如,每个属性的顺序和列宽 - 然后在该XML上使用XSLT生成如下所示的XSLT样式表。然后,您可以使用该XSLT从您从SQL Server获得的XML生成FO。这可能听起来很复杂,但它应该比试图维护20个样式表更简单。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
version="1.0">
<xsl:variable name="columnFontType" select="'sans-serif'"/>
<xsl:variable name="columnFontSize" select="'12pt'"/>
<xsl:template match="Products">
    <fo:root>
        <fo:layout-master-set>
            <fo:simple-page-master master-name="a">
                <fo:region-body margin="10mm"/>
            </fo:simple-page-master>
        </fo:layout-master-set>
        <fo:page-sequence master-reference="a">
            <fo:flow flow-name="xsl-region-body">
                <fo:table border-bottom-width="5pt"  border-bottom-color="rgb(0,51,102)" border-collapse="collapse" background-color="rgb(255,255,255)">
                    <fo:table-column column-width="proportional-column-width(6.77)" column-number="1"/>
                    <fo:table-column column-width="proportional-column-width(5.09)" column-number="2"/>
                    <fo:table-column column-width="proportional-column-width(5.63)" column-number="3"/>
                    <fo:table-column column-width="proportional-column-width(5.94)" column-number="4"/>
                    <fo:table-column column-width="proportional-column-width(5.79)" column-number="5"/>

                    <fo:table-header>
                        <fo:table-row height="20.81pt" display-align="center" overflow="hidden">
                            <fo:table-cell text-align="center" border-left-color="rgb(0, 0, 0)" border-left-style="solid" border-left-width="1pt" border-right-color="rgb(0, 0, 0)" border-right-style="solid" border-right-width="1pt" border-top-color="rgb(0, 0, 0)" border-top-style="solid" border-top-width="1pt" border-bottom-color="rgb(0, 0, 0)" border-bottom-style="solid" border-bottom-width="1pt" padding-left="2pt" padding-right="2pt" padding-top="2pt" padding-bottom="2pt">
                                <fo:block color="rgb(0,0,0)" text-align="center" font-weight="normal" font-family="{$columnFontType}" font-size="{$columnFontSize}">Transaction</fo:block>
                                <fo:block color="rgb(0,0,0)" text-align="center" font-weight="normal" font-family="{$columnFontType}" font-size="{$columnFontSize}">Date</fo:block>
                            </fo:table-cell>
                            <fo:table-cell text-align="center" border-left-color="rgb(0, 0, 0)" border-left-style="solid" border-left-width="1pt" border-right-color="rgb(0, 0, 0)" border-right-style="solid" border-right-width="1pt" border-top-color="rgb(0, 0, 0)" border-top-style="solid" border-top-width="1pt" border-bottom-color="rgb(0, 0, 0)" border-bottom-style="solid" border-bottom-width="1pt" padding-left="2pt" padding-right="2pt" padding-top="2pt" padding-bottom="2pt">
                                <fo:block color="rgb(0,0,0)" text-align="center" font-weight="normal" font-family="{$columnFontType}" font-size="{$columnFontSize}">Cust ID</fo:block>
                            </fo:table-cell>
                            <fo:table-cell text-align="center" border-left-color="rgb(0, 0, 0)" border-left-style="solid" border-left-width="1pt" border-right-color="rgb(0, 0, 0)" border-right-style="solid" border-right-width="1pt" border-top-color="rgb(0, 0, 0)" border-top-style="solid" border-top-width="1pt" border-bottom-color="rgb(0, 0, 0)" border-bottom-style="solid" border-bottom-width="1pt" padding-left="2pt" padding-right="2pt" padding-top="2pt" padding-bottom="2pt">
                                <fo:block color="rgb(0,0,0)" text-align="center" font-weight="normal" font-family="{$columnFontType}" font-size="{$columnFontSize}">Cust No</fo:block>
                            </fo:table-cell>
                            <fo:table-cell text-align="center" border-left-color="rgb(0, 0, 0)" border-left-style="solid" border-left-width="1pt" border-right-color="rgb(0, 0, 0)" border-right-style="solid" border-right-width="1pt" border-top-color="rgb(0, 0, 0)" border-top-style="solid" border-top-width="1pt" border-bottom-color="rgb(0, 0, 0)" border-bottom-style="solid" border-bottom-width="1pt" padding-left="2pt" padding-right="2pt" padding-top="2pt" padding-bottom="2pt">
                                <fo:block color="rgb(0,0,0)" text-align="center" font-weight="normal" font-family="{$columnFontType}" font-size="{$columnFontSize}">Client Name</fo:block>
                            </fo:table-cell>
                            <fo:table-cell text-align="center" border-left-color="rgb(0, 0, 0)" border-left-style="solid" border-left-width="1pt" border-right-color="rgb(0, 0, 0)" border-right-style="solid" border-right-width="1pt" border-top-color="rgb(0, 0, 0)" border-top-style="solid" border-top-width="1pt" border-bottom-color="rgb(0, 0, 0)" border-bottom-style="solid" border-bottom-width="1pt" padding-left="2pt" padding-right="2pt" padding-top="2pt" padding-bottom="2pt">
                                <fo:block color="rgb(0,0,0)" text-align="center" font-weight="normal" font-family="{$columnFontType}" font-size="{$columnFontSize}">Long ID</fo:block>
                            </fo:table-cell>
                        </fo:table-row>
                    </fo:table-header>
                    <fo:table-body>
                    <xsl:apply-templates />
                    </fo:table-body>
                </fo:table>
            </fo:flow>
        </fo:page-sequence>
    </fo:root>
</xsl:template>

<xsl:template match="Product">
    <fo:table-row display-align="before">
        <xsl:call-template name="cell">
            <xsl:with-param name="value" select="@id"/>
        </xsl:call-template>
        <xsl:call-template name="cell">
            <xsl:with-param name="value" select="@name"/>
        </xsl:call-template>
        <xsl:call-template name="cell">
            <xsl:with-param name="value" select="@quantity"/>
        </xsl:call-template>
        <xsl:call-template name="cell">
            <xsl:with-param name="value" select="format-number(@price, '$0.00')"/>
        </xsl:call-template>
        <xsl:call-template name="cell">
            <xsl:with-param name="value" select="@description"/>
        </xsl:call-template>
    </fo:table-row>
</xsl:template>

<xsl:template name="cell">
    <xsl:param name="value" />
    <fo:table-cell text-align="center" border-top-color="rgb(0, 0, 0)" border-top-style="solid" border-left-width="1pt" border-right-width="1pt" border-top-width="1pt" border-bottom-width="1pt" padding-left="2pt" padding-right="2pt" padding-top="2pt" padding-bottom="2pt">
        <fo:block>
           <xsl:value-of select="$value"/>
        </fo:block>
    </fo:table-cell>

</xsl:template>
</xsl:stylesheet>

另请查看xsl:attribute-set(请参阅https://www.w3.org/TR/xslt#attribute-sets),以便同时添加一堆属性(如果您正在生成XSLT,则可能不太有用)。

答案 1 :(得分:0)

  

我的目标是构建20种类型的报告,并希望动态执行   1 xsl fo。这可能吗?

这是可能的 - 如果所有报告都遵循一些共同的模式。

例如,如果行始终是根元素的子元素,并且单元格是行的属性,则可以执行以下操作(为了演示而简化的代码):

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/*">
    <table>
        <header>
            <row>
                <xsl:for-each select="*[1]/@*">
                    <cell>
                        <xsl:value-of select="name()"/>
                    </cell>
                </xsl:for-each>
            </row>  
        </header>
        <body>
            <xsl:for-each select="*">
                <row>
                    <xsl:for-each select="@*">
                        <cell>
                            <xsl:value-of select="."/>
                        </cell>
                    </xsl:for-each>
                </row>
            </xsl:for-each>
        </body>
    </table>
</xsl:template>

</xsl:stylesheet>

应用于您的输入示例,结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<table>
   <header>
      <row>
         <cell>id</cell>
         <cell>name</cell>
         <cell>price</cell>
         <cell>quantity</cell>
         <cell>description</cell>
      </row>
   </header>
   <body>
      <row>
         <cell>1</cell>
         <cell>Rendezvous with Rama by Arthur C. Clarke</cell>
         <cell>15</cell>
         <cell>3</cell>
         <cell>An all-time science fiction classic, Rendezvous with Rama is also one of Clarke's best novels--it won the Campbell, Hugo, Jupiter, and Nebula Awards.</cell>
      </row>
      <row>
         <cell>2</cell>
         <cell>Dune Chronicles by Frank Herbert</cell>
         <cell>60</cell>
         <cell>5</cell>
         <cell>Dune is one of the most famous science fiction novels ever written, and deservedly so. The setting is elaborate and ornate, the plot labyrinthine, the adventures exciting. Five sequels follow.</cell>
      </row>
      <row>
         <cell>3</cell>
         <cell>Schindler's List by Thomas Keneally</cell>
         <cell>21</cell>
         <cell>6</cell>
         <cell>A mesmerizing novel based on the true story of Oskar Schindler, a German industralist who saved and succored more than 1000 Jews from the Nazis at enormous financial and emotional expense.</cell>
      </row>
      <row>
         <cell>4</cell>
         <cell>Middle Passage by Charles Johnson</cell>
         <cell>17</cell>
         <cell>4</cell>
         <cell>In this savage parable of the African American experience, Rutherford Calhoun, a newly freed slave eking out a living in New Orleans in 1830, hops aboard a square rigger to evade the prim Boston schoolteacher who wants to marry him. But the Republic turns out to be a slave clipper bound for Africa.</cell>
      </row>
      <row>
         <cell>5</cell>
         <cell>Underworld:A Novel by Don DeLillo</cell>
         <cell>14</cell>
         <cell>3</cell>
         <cell>Underworld opens with a breathlessly graceful prologue set during the final game of the Giants-Dodgers pennant race in 1951. Written in what DeLillo calls super-omniscience the sentences sweep from young Cotter Martin as he jumps the gate to the press box, soars over the radio waves, runs out to the diamond, slides in on a fast ball, pops into the stands where J. It's an absolutely thrilling literary moment.</cell>
      </row>
      <row>
         <cell>6</cell>
         <cell>Stones from the River by Ursula Hegi</cell>
         <cell>16</cell>
         <cell>4</cell>
         <cell>Ursula Hegi's Stones from the River clamors for comparisons to Gunter Grass's The Tin Drum; her protagonist Trudi Montag--like the unforgettable Oskar Mazerath--is a dwarf living in Germany during the two World Wars. </cell>
      </row>
      <row>
         <cell>7</cell>
         <cell>Empire of the Sun by J. G. Ballard</cell>
         <cell>12</cell>
         <cell>3</cell>
         <cell>Ballard's enduring novel of war and deprivation, internment camps and death marches, and starvation and survival is an honest coming-of-age tale set in a world thrown utterly out of joint.</cell>
      </row>
   </body>
</table>