XSL FO按列动态分组

时间:2016-07-05 07:35:13

标签: xml xslt xsl-fo

我是一个来自数据库存储过程的XML文件,我需要使用XSL FO.Net生成一个带有分组的PDF,如下图所示。任何人都可以指导我如何对列进行分组,并且分组列不应该出现在HEADER列中。

enter image description here

就像我可以有两个级别的分组。我使用下面的XML和XSL FO来生成它。但是不能按列分组。

<PdfPrinter>
    <Reports>
    <Header>
    <PrintedDate>2016-07-01T15:16:09.473</PrintedDate>
    <PrintedBy>Pavan</PrintedBy>
    </Header>
    <Report>
    <Name>S</Name>
    <UserName />
    <Remarks />
    <IPAddress>192.168.1.83</IPAddress>
    <DateCreated>2015-10-07T17:48:35.243</DateCreated>
    <AppID>OS</AppID>
    <AppVersion>0.0.0.2</AppVersion>
    <LoginDate>2015-10-07T17:48:05.380</LoginDate>
    <LogoutDate>1900-01-01T00:00:00</LogoutDate>
    </Report>
    <Report>
    <Name>S</Name>
    <UserName />
    <Remarks />
    <IPAddress>192.168.1.83</IPAddress>
    <DateCreated>2015-10-07T17:49:36.107</DateCreated>
    <AppID>OS</AppID>
    <AppVersion>0.0.0.2</AppVersion>
    <LoginDate>2015-10-07T17:49:26.287</LoginDate>
    <LogoutDate>1900-01-01T00:00:00</LogoutDate>
    </Report>
    </Reports>
</PdfPrinter>

XSLT:

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:ext="http://exslt.org/common"
xmlns:utilityExtension="pdfprinter:extensions:utility"
exclude-result-prefixes="msxsl utilityExtension">
  <!--<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" encoding="utf-8"/>-->
  <xsl:template match="/">

    <xsl:variable name="columnFontSize">12pt</xsl:variable>
    <xsl:variable name="columnFontType">Helvetica</xsl:variable>

    <xsl:variable name="headerPrintedBy">Printed By</xsl:variable>
    <xsl:variable name="headerPrintedDate">Printed Date</xsl:variable>
    <xsl:variable name="headerReportID">Report ID</xsl:variable>
    <xsl:variable name="logo" select="utilityExtension:MapPath('~/App_Data/Resources/IMAGES/logo.jpg')"/>

    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <!-- defines the layout master -->
      <fo:layout-master-set>
        <fo:simple-page-master master-name="all-pages" page-width="1600pt" page-height="1190pt">
          <fo:region-body region-name="xsl-region-body" column-gap="0.250in" margin="0.7in" margin-left="0.7in"/>
          <fo:region-before region-name="xsl-region-before" display-align="after" extent="0.700in" />
          <fo:region-after region-name="xsl-region-after" extent="0.700in"/>
        </fo:simple-page-master>
        <fo:page-sequence-master master-name="default-sequence">
          <fo:repeatable-page-master-reference master-reference="all-pages"/>
        </fo:page-sequence-master>
      </fo:layout-master-set>
      <!-- starts actual layout -->
      <fo:page-sequence master-reference="default-sequence">
        <fo:static-content border-bottom-width="1pt" border-bottom-style="solid" border-bottom-color="rgb(192,192,192)" flow-name="xsl-region-before" font-size="10pt" font-family="Helvetica">
          <fo:block color="rgb(105,105,105)" text-align-last="justify">

          </fo:block>
        </fo:static-content>
        <fo:static-content border-top-width="1pt" width="1000pt" border-top-style="solid" border-top-color="rgb(192,192,192)" padding-top="2pt" flow-name="xsl-region-after" font-size="10pt" font-family="Helvetica">
          <fo:table table-layout="fixed" width="500pt">
            <fo:table-column column-width="proportional-column-width(4)"/>
            <fo:table-column column-width="proportional-column-width(1)"/>
            <fo:table-body>
              <fo:table-row>
                <fo:table-cell>
                  <fo:block text-align="right" color="rgb(105,105,105)">&#160;</fo:block>
                </fo:table-cell>
              </fo:table-row>
            </fo:table-body>
          </fo:table>
        </fo:static-content>
        <fo:flow flow-name="xsl-region-body" font-size="10pt" font-family="Helvetica">
          <fo:block>
            <fo:table border-collapse="collapse" width="1200pt"  table-layout="auto" margin-top="-0.002in">
              <fo:table-column column-width="proportional-column-width(55)" column-number="1"/>
              <fo:table-column column-width="proportional-column-width(45)" column-number="2"/>
              <fo:table-body>
                <fo:table-row>
                  <fo:table-cell>
                    <fo:block color="rgb(0,0,128)" font-size="16pt" font-weight="bold">&#160;</fo:block>
                    <fo:block color="rgb(0,0,128)" font-weight="bold"></fo:block>
                    <fo:block color="rgb(0,0,0)" font-weight="bold" font-family="{$columnFontType}" font-size="{$columnFontSize}">
                      <fo:external-graphic src="{$logo}"/>&#160;&#160;&#160;&#160;
                      <fo:block>
                        <xsl:value-of select="$headerOrgName"/>
                      </fo:block>
                    </fo:block>
                    <fo:block color="rgb(0,0,128)" font-weight="bold">&#160;&#160;&#160;&#160;</fo:block>
                    <fo:block color="rgb(0,0,0)" font-weight="bold" font-family="{$columnFontType}" font-size="{$columnFontSize}">
                      <xsl:value-of select="$headerReportID"/>
                    </fo:block>
                    <fo:block>
                      <xsl:value-of select="/PdfPrinter/Reports/Header/ReportID" />
                    </fo:block>
                  </fo:table-cell>
                  <fo:table-cell>
                    <fo:block text-align="left">
                      <fo:inline font-weight="bold" font-family="{$columnFontType}" font-size="{$columnFontSize}">
                        <xsl:value-of select="$headerPrintedBy"/>  :
                      </fo:inline>
                      <fo:block>
                        <xsl:value-of select="/PdfPrinter/Reports/Header/PrintedBy" />
                      </fo:block>
                    </fo:block>
                    <fo:block text-align="left">
                      <fo:inline font-weight="bold" font-family="{$columnFontType}" font-size="{$columnFontSize}">
                        <xsl:value-of select="$headerPrintedDate"/>  :
                      </fo:inline>
                      <fo:block>
                        <xsl:value-of select="/PdfPrinter/Reports/Header/PrintedDate" />
                      </fo:block>
                    </fo:block>
                  </fo:table-cell>
                </fo:table-row>
              </fo:table-body>
            </fo:table>
            <fo:block/>
          </fo:block>
          <fo:block text-align="center">
            <fo:table border-bottom-width="5pt" font-weight="bold" inline-progression-dimension="auto" table-layout="auto" border-bottom-color="rgb(51,51,153)" border-collapse="collapse">
              <fo:table-column column-number="1"/>
              <fo:table-body>
                <fo:table-row border-bottom-color="rgb(0,0,255)" display-align="before">
                  <fo:table-cell border-bottom-width="3pt" border-bottom-style="solid" border-bottom-color="rgb(51,51,153)" padding="2pt" text-align="left">
                    <fo:block text-align="center" font-size="12pt" font-weight="bold" font-family="Helvetica" border-bottom="10pt  "></fo:block>
                    <fo:block>
                      <xsl:value-of select="/PdfPrinter/Reports/Header/ReportTitle" />
                    </fo:block>
                    <fo:block border-bottom-width="10pt" text-align="center"/>
                  </fo:table-cell>
                </fo:table-row>
              </fo:table-body>
            </fo:table>
          </fo:block>
          <fo:block font-size="18pt"
                font-family="sans-serif"
                line-height="24pt"
                space-after.optimum="15pt"
                background-color="blue"
                color="white"
                text-align="center"
                padding-top="3pt">
           Users Report
          </fo:block>
          <fo:block text-align="center">
            <!-- table start -->
            <fo:table border-bottom-width="5pt" width="1200pt" border-bottom-color="rgb(0,51,102)" border-collapse="collapse" background-color="rgb(255,255,255)">
              <!--table header-->
              <xsl:for-each select="/PdfPrinter/Reports/Report[1]/*">
                <fo:table-column column-width="proportional-column-width(4.77)"/>
              </xsl:for-each>
              <fo:table-header>
                  <fo:table-row height="20.81pt" display-align="center" overflow="hidden">
                    <xsl:for-each select="/PdfPrinter/Reports/Report[1]/*">
                    <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}">
                        <xsl:value-of select="name()"/>
                      </fo:block>
                    </fo:table-cell>
                    </xsl:for-each>
                  </fo:table-row>
              </fo:table-header>
              <!--table body-->
              <fo:table-body>
                <xsl:for-each select="PdfPrinter/Reports/Report">
                  <fo:table-row display-align="before">
                    <xsl:for-each select="*">
                    <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="."/>
                      </fo:block>
                    </fo:table-cell>
                    </xsl:for-each>
                  </fo:table-row>
                </xsl:for-each>
              </fo:table-body>
            </fo:table>
            <!-- table end -->
          </fo:block>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  </xsl:template>
</xsl:stylesheet>

我能够动态生成列,但需要按列分组并显示结果,如上图所示。请帮帮我。

提前致谢!

1 个答案:

答案 0 :(得分:0)

由于您使用的是XSLT 2.0,因此可以使用xsl:for-each-groupReport进行分组。生成Namefo:table-column以及跨越整行时,您还需要不考虑fo:table-cell元素。

<fo:table border-bottom-width="5pt" width="1200pt" border-bottom-color="rgb(0,51,102)" border-collapse="collapse" background-color="rgb(255,255,255)">
  <!--table header-->
  <xsl:for-each select="/PdfPrinter/Reports/Report[1]/(* except Name)">
    <fo:table-column column-width="proportional-column-width(4.77)"/>
  </xsl:for-each>
  <fo:table-header>
      <fo:table-row height="20.81pt" display-align="center" overflow="hidden">
        <xsl:for-each select="/PdfPrinter/Reports/Report[1]/(* except Name)">
        <fo:table-cell text-align="center" border="rgb(0, 0, 0) solid 1pt" padding="2pt">
          <fo:block color="rgb(0,0,0)" text-align="center" font-weight="normal" font-family="{$columnFontType}" font-size="{$columnFontSize}">
            <xsl:value-of select="name()"/>
          </fo:block>
        </fo:table-cell>
        </xsl:for-each>
      </fo:table-row>
  </fo:table-header>
  <!--table body-->
  <fo:table-body>
    <xsl:for-each-group select="PdfPrinter/Reports/Report"
      group-adjacent="Name">
      <fo:table-row>
        <fo:table-cell number-columns-spanned="{count(*) - 1}">
          <fo:block><xsl:apply-templates select="Name" /></fo:block>
        </fo:table-cell>
      </fo:table-row>
      <xsl:for-each select="current-group()">
        <fo:table-row display-align="before">
          <xsl:for-each select="* except Name">
            <fo:table-cell text-align="center" border-top-color="rgb(0, 0, 0)" border-top-style="solid" border-width="1pt" padding="2pt">
              <fo:block>
                <xsl:value-of select="."/>
              </fo:block>
            </fo:table-cell>
          </xsl:for-each>
        </fo:table-row>
      </xsl:for-each>
    </xsl:for-each-group>
  </fo:table-body>
</fo:table>

将Muenchian分组与XSLT 1.0处理器一起使用:

更改version="2.0"&#39;到&#39; version="1.0"&#39;因此,您对使用的XSLT版本的混淆程度较低。

在顶层添加此内容,例如在xsl:output

之后
  <xsl:key name="Report" match="Report" use="Name" />

使用此:

<fo:table border-bottom-width="5pt" width="1200pt" border-bottom-color="rgb(0,51,102)" border-collapse="collapse" background-color="rgb(255,255,255)">
  <!--table header-->
  <xsl:for-each select="/PdfPrinter/Reports/Report[1]/*[local-name() != 'Name']">
    <fo:table-column column-width="proportional-column-width(4.77)"/>
  </xsl:for-each>
  <fo:table-header>
      <fo:table-row height="20.81pt" display-align="center" overflow="hidden">
        <xsl:for-each select="/PdfPrinter/Reports/Report[1]/*[local-name() != 'Name']">
        <fo:table-cell text-align="center" border="rgb(0, 0, 0) solid 1pt" padding="2pt">
          <fo:block color="rgb(0,0,0)" text-align="center" font-weight="normal" font-family="{$columnFontType}" font-size="{$columnFontSize}">
            <xsl:value-of select="name()"/>
          </fo:block>
        </fo:table-cell>
        </xsl:for-each>
      </fo:table-row>
  </fo:table-header>
  <!--table body-->
  <fo:table-body>
    <xsl:for-each select="PdfPrinter/Reports/Report[generate-id() = generate-id(key('Report', Name)[1])]">
      <fo:table-row>
        <fo:table-cell number-columns-spanned="{count(*) - 1}">
          <fo:block><xsl:apply-templates select="Name" /></fo:block>
        </fo:table-cell>
      </fo:table-row>
      <xsl:for-each select="key('Report', Name)">
        <fo:table-row display-align="before">
          <xsl:for-each select="*[local-name() != 'Name']">
            <fo:table-cell text-align="center" border-top-color="rgb(0, 0, 0)" border-top-style="solid" border-width="1pt" padding="2pt">
              <fo:block>
                <xsl:value-of select="."/>
              </fo:block>
            </fo:table-cell>
          </xsl:for-each>
        </fo:table-row>
      </xsl:for-each>
    </xsl:for-each>
  </fo:table-body>
</fo:table>