本文介绍了XSL FO 生成动态列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm working on an XSL FO to generate PDF using FOP.NET. I've a requirement of generating the columns dynamically based on the XML i get from the DB. Below is the XML format i've and i need to generate the columns dynamically rather than hardcoding them in the xsl fo stylesheet. ANy help would be greatly appreciated.

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

My goal is to build 20 types of reports and want to do it dynamically with 1 xsl fo. Is this possbile? or do I need to have 20 xsl fo files to generate the report? Please suggest an optimal way to do this.. I dont want to use itextsharp and other paid tools. (Only XSL FO)

下面是我从 SQL Server 得到的 XML.

Below is the XML that i get from SQL Server.

    <?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、name、price、quantity、description需要动态绑定.对示例的任何帮助将不胜感激.

The columns id, name, price, quantity, description need to be bound dynamically. Any help with an example would be greatly appreciated.

我的硬编码 XSL 样式表

My Hardcoded XSL stylesheet

    <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>

谢谢,帕文

推荐答案

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

An XSLT 1.0 stylesheet for your sample is below. If you need to produce 20 variations on this, I suggest that you come up with an XML representation of the necessary information for each report -- e.g., the order and column-width for each of your attributes -- then use XSLT on that XML to generate an XSLT stylesheet like the one below. You can then use that XSLT to generate the FO from the XML that you get from SQL Server. It may sound complicated, but it should be simpler than trying to maintain 20 stylesheets.

<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 可能不太有用).

Also look into xsl:attribute-set (see https://www.w3.org/TR/xslt#attribute-sets) as a way to add a bunch of attributes at once (though possibly less useful if you're generating the XSLT anyway).

这篇关于XSL FO 生成动态列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-14 15:13