2016-07-05 230 views
0

我有一个来自数据库存储过程的XML文件,并且需要使用XSL FO.Net生成PDF,如下图所示。任何人都可以请指导我如何分组列和分组列不应该在HEADER列。XSL FO group by columns dynamicaly

enter image description here

喜欢,我可以有2级分组。我使用下面的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> 

我能够动态地生成的列,但是,需要按列和显示为所示的上述附加的图像中的结果。请帮助我。

在此先感谢!

+0

我跑你提供的XML和XSLT,并有一个空的'FO:表头/ fo:table-row'和空'fo:table-body'。 XML需要一个外部的'PdfPrinter'或者你的XPath需要改变。 –

+0

@ Tony,是的..很抱歉,通过编程的方式进行处理。您需要在顶部添加。谢谢.. –

+0

您的图形显示4/5列,但您的XML生成9列。什么是XML中的分组列? –

回答

0

由于您使用的是XSLT 2.0,因此可以使用xsl:for-each-groupReport分组。生成fo:table-columnfo:table-cell时以及跨越整行时,您还不需要考虑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]/(* 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" '到' version="1.0"',所以有较少混淆这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> 
+0

我尝试了上面的表,并获得了XSLT 2.0错误。 (命名空间'http://www.w3.org/1999/XSL/Transform'中的元素模板在命名空间'http://www.w3.org/1999/XSL'中具有无效子元素'for-each-group'/Transform'。预期的可能元素列表:'apply-templates,call-template,apply-imports,for-each,value-of,copy-of,number,choose等等在命名空间'http://www.w3 .org/1999/XSL/Transform'以及命名空间'## other'中的任何元素。) 编辑:我想使用XSLT 1.0 ..如果我需要使用2.0,我需要引用任何东西吗?请澄清..非常感谢! –

+0

您的样式表包含''version =“2.0”'',所以我给了一个XSLT 2.0解决方案。要使用XSLT 2.0,您需要XSLT 2.0处理器,如Saxon(http://www.saxonica.com)。要使用XSLT 1.0进行这种分组,请查看如何做'Meunchian分组',例如http://stackoverflow.com/questions/24411173/muenchian-grouping-with-xsl-fo-table?rq = 1 –

+0

好吧,我需要添加任何dll到我的项目使用xslt 2.0?如何在我的项目中使用XSLT 2.0?请建议.. –