我有以下要求。
输入
———
———
<table>
<thead>
<tr>
<th></th>
<th></th>
<th></th>
…………..
…………...
</tr>
…………..
…………...
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
…………..
…………...
</tr>
…………..
…………...
</tbody>
</table>
———
———
像这样多个表格。
现在我需要为不同的表创建不同的工作表(用于工作簿/ Excel文件)。工作表的数量取决于表的数量。我需要使用Xslt来做到这一点。
没有表不是常数,它会有所不同。
如果您有任何想法,请告诉我。我在互联网上做了一些研究,但我找不到任何东西。
我写了以下xsl。我能够生成多张纸。但该表仅印在第一张纸上。我希望把桌子放在所有床单上。
<?xml version="1.0"?>
<xsl:stylesheet
version="1.0"
xmlns="http://www.w3.org/TR/REC-html40"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:exslt="http://exslt.org/common"
xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
xmlns:php="http://php.net/xsl"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:rs="urn:schemas-microsoft-com:xml-analysis:rowset"
xmlns:x="urn:schemas-microsoft-com:office:excel"
exclude-result-prefixes="xsl xsd exslt fn php SOAP-ENV rs">
<xsl:output method="html" omit-xml-declaration="yes" />
<!--
Beginning of template processing, start at document root
//-->
<xsl:variable name="pageBreakAfterTable">false</xsl:variable>
<xsl:template match="/">
</xsl:template>
<xsl:template match="/">
<xsl:text disable-output-escaping="yes"><html xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
<meta name=ProgId content=Excel.Sheet>
<meta name=Generator content="Microsoft Excel 11">
<!--[if gte mso 9]><xml>
<x:ExcelWorkbook>
<x:ExcelWorksheets>
</xsl:text>
<xsl:for-each select="//html/body/table">
<xsl:text disable-output-escaping="yes">
<x:ExcelWorksheet>
<x:Name>Report Results</x:Name>
<x:WorksheetOptions>
<x:Selected/>
<x:ShowGridlines/>
<x:ProtectContents>False</x:ProtectContents>
<x:ProtectObjects>False</x:ProtectObjects>
<x:ProtectScenarios>False</x:ProtectScenarios>
</x:WorksheetOptions>
</xsl:text>
<xsl:element name="table">
<xsl:call-template name="processRows">
<xsl:with-param name="rows" select="./thead/tr"/>
</xsl:call-template>
<xsl:call-template name="processRows">
<xsl:with-param name="rows" select="./tbody/tr"/>
</xsl:call-template>
<xsl:call-template name="processRows">
<xsl:with-param name="rows" select="./tr"/>
</xsl:call-template>
<xsl:element name="tr"/>
</xsl:element>
<xsl:text disable-output-escaping="yes"></x:ExcelWorksheet></xsl:text>
</xsl:for-each>
<xsl:text disable-output-escaping="yes">
</x:ExcelWorksheets>
<x:ProtectStructure>False</x:ProtectStructure>
<x:ProtectWindows>False</x:ProtectWindows>
</x:ExcelWorkbook>
</xml><![endif]-->
</head>
<body></xsl:text>
<xsl:text disable-output-escaping="yes"></body></html></xsl:text>
<!-- Translate each table -->
<!-- <xsl:call-template name="processTables">
<xsl:with-param name="tables" select="//html/body/table"/>
</xsl:call-template>-->
</xsl:template>
<!-- <xsl:template name="processTables">
<xsl:param name="tables"/>
</xsl:template>-->
<xsl:template name="processRows">
<xsl:param name="rows"/>
<xsl:for-each select="$rows">
<xsl:if test="not(contains(@class,'emptyValue'))">
<xsl:element name="tr">
<xsl:attribute name="style">
<!-- Do we need to display a drill-down depth? -->
<xsl:choose>
<xsl:when test="count(./node()[contains(@class,'ds-drilldown-level-6')]) > 0">
<xsl:text>mso-outline-level:6;</xsl:text>
</xsl:when>
<xsl:when test="count(./node()[contains(@class,'ds-drilldown-level-5')]) > 0">
<xsl:text>mso-outline-level:5;</xsl:text>
</xsl:when>
<xsl:when test="count(./node()[contains(@class,'ds-drilldown-level-4')]) > 0">
<xsl:text>mso-outline-level:4;</xsl:text>
</xsl:when>
<xsl:when test="count(./node()[contains(@class,'ds-drilldown-level-3')]) > 0">
<xsl:text>mso-outline-level:3;</xsl:text>
</xsl:when>
<xsl:when test="count(./node()[contains(@class,'ds-drilldown-level-2')]) > 0">
<xsl:text>mso-outline-level:2;</xsl:text>
</xsl:when>
<xsl:when test="count(./node()[contains(@class,'ds-drilldown-level-1')]) > 0">
<xsl:text>mso-outline-level:1;</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:attribute>
<xsl:for-each select="./node()">
<xsl:if test="normalize-space(.) != '' or normalize-space(@*) != ''">
<xsl:element name="td">
<xsl:if test="@colspan">
<xsl:copy-of select="@colspan"/>
</xsl:if>
<xsl:if test="@rowspan">
<xsl:copy-of select="@rowspan"/>
</xsl:if>
<xsl:if test="name(.)='td'">
<xsl:attribute name="align"><xsl:text>right</xsl:text></xsl:attribute>
</xsl:if>
<xsl:attribute name="style">
<xsl:if test="name(.)='th'">
<xsl:text> font-weight:bold;</xsl:text>
</xsl:if>
<xsl:if test="contains(@class,' red')">
<xsl:text> color:red;</xsl:text>
</xsl:if>
<xsl:if test="contains(@class,' green')">
<xsl:text> color:green;</xsl:text>
</xsl:if>
</xsl:attribute>
<xsl:value-of select="text()"/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:0)
禁止输出转义以执行输出的方法不是推荐的方法,尤其是因为它使XML非常难以阅读。您还可以将HTML添加到Excel电子表格中。我相信Excel可以导入HTML,但最好在这里使用“XML Spreadsheet 2003”格式。
首先,您需要让Excel为您付出艰苦的努力。打开Excel,输入一些测试数据来表示您希望表格显示的内容,然后将其保存为“XML Spreadsheet 2003”格式。然后,您可以在记事本中打开它以查看Excel期望的内容。实际上,您可以将大量复制并粘贴到Excel中。
您需要在XSLT中采用的方法是基于模板的方法。首先匹配 body 元素。在模板中,您可以输出工作簿元素,并包含 xsl:apply-templates 以查找任何表格元素。例如
<xsl:template match="body">
<Workbook>
<!-- More properties here -->
<Styles>
<!-- Styles here -->
</Styles>
<xsl:apply-templates select=".//table" />
</Workbook>
</xsl:template>
然后,将使用匹配表的模板进行输出。请注意使用“属性值模板**来计算列数和行数
<xsl:template match="table">
<Worksheet ss:Name="Sheet{count(preceding::table) + 1}">
<Table ss:ExpandedColumnCount="{count(thead/tr/th)}" ss:ExpandedRowCount="{count(.//tr)}" x:FullColumns="1" x:FullRows="1" ss:DefaultRowHeight="15">
<xsl:apply-templates select=".//tr" />
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<!-- options -->
</WorksheetOptions>
</Worksheet>
</xsl:template>
然后,您可以继续使用此方法,使用匹配 tr 的模板输出行元素,以及匹配 td 的模板(或 th )用于输出 Cell 元素。
尝试使用此XSLT作为初学者
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<xsl:output indent="yes"/>
<xsl:template match="body">
<Workbook>
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
<Author>Test</Author>
<LastAuthor>Test</LastAuthor>
<Created>2014-06-20T12:40:11Z</Created>
<Version>14.00</Version>
</DocumentProperties>
<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
<AllowPNG/>
</OfficeDocumentSettings>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
<WindowHeight>4680</WindowHeight>
<WindowWidth>16275</WindowWidth>
<WindowTopX>120</WindowTopX>
<WindowTopY>120</WindowTopY>
<ActiveSheet>1</ActiveSheet>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
<Styles>
<Style ss:ID="Default" ss:Name="Normal">
<Alignment ss:Vertical="Bottom"/>
<Borders/>
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#000000"/>
<Interior/>
<NumberFormat/>
<Protection/>
</Style>
</Styles>
<xsl:apply-templates select=".//table" />
</Workbook>
</xsl:template>
<xsl:template match="table">
<Worksheet ss:Name="Sheet{count(preceding::table) + 1}">
<Table ss:ExpandedColumnCount="{count(thead/tr/th)}" ss:ExpandedRowCount="{count(.//tr)}" x:FullColumns="1" x:FullRows="1" ss:DefaultRowHeight="15">
<xsl:apply-templates select=".//tr" />
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<PageSetup>
<Header x:Margin="0.3"/>
<Footer x:Margin="0.3"/>
<PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
</PageSetup>
<Panes>
<Pane>
<Number>3</Number>
<ActiveRow>1</ActiveRow>
<ActiveCol>2</ActiveCol>
</Pane>
</Panes>
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
</Worksheet>
</xsl:template>
<xsl:template match="tr">
<Row>
<xsl:apply-templates select="th|td" />
</Row>
</xsl:template>
<xsl:template match="th|td">
<Cell>
<Data ss:Type="String"><xsl:value-of select="." /></Data>
</Cell>
</xsl:template>
</xsl:stylesheet>
这确实假设您的表格结构合理。如果你有 colspan 和 rowspan ,它会变得更复杂。
答案 1 :(得分:0)
这是我写的代码。基于变量,我们可以获得单页或多页数据。
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<xsl:output indent="yes"/>
<!--
Beginning of template processing, start at document root
//-->
<xsl:param name="pageBreakAfterTable" select="0"/>
<xsl:template match="/">
<Workbook>
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
<LastAuthor>Intervolve</LastAuthor>
</DocumentProperties>
<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
<AllowPNG/>
</OfficeDocumentSettings>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
<WindowHeight>10880</WindowHeight>
<WindowWidth>25600</WindowWidth>
<WindowTopX>0</WindowTopX>
<WindowTopY>0</WindowTopY>
<ActiveSheet>0</ActiveSheet>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
<Styles>
<Style ss:ID="Default" ss:Name="Normal">
<Alignment ss:Vertical="Bottom"/>
<Borders/>
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="12" ss:Color="#000000"/>
<Interior/>
<NumberFormat/>
<Protection/>
</Style>
<Style ss:ID="s62">
<Alignment ss:Horizontal="Left" ss:Vertical="Bottom" ss:WrapText="1"/>
</Style>
<Style ss:ID="s63">
<Alignment ss:Vertical="Bottom" ss:WrapText="1"/>
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="12" ss:Color="#000000" ss:Bold="1"/>
</Style>
<Style ss:ID="s64">
<Alignment ss:Horizontal="Right" ss:Vertical="Bottom" ss:WrapText="1"/>
</Style>
<Style ss:ID="s65">
<Alignment ss:Horizontal="Left" ss:Vertical="Bottom" ss:WrapText="1"/>
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Color="#DD0806"/>
</Style>
<Style ss:ID="s66">
<Alignment ss:Horizontal="Left" ss:Vertical="Bottom" ss:WrapText="1"/>
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Color="#1FB714"/>
</Style>
<Style ss:ID="s67">
<Alignment ss:Horizontal="Right" ss:Vertical="Bottom" ss:WrapText="1"/>
<NumberFormat ss:Format="Standard"/>
</Style>
<Style ss:ID="s68">
<Alignment ss:Horizontal="Right" ss:Vertical="Bottom" ss:WrapText="1"/>
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="12" ss:Color="#DD0806"/>
<NumberFormat ss:Format="Standard"/>
</Style>
<Style ss:ID="s69">
<Alignment ss:Horizontal="Right" ss:Vertical="Bottom" ss:WrapText="1"/>
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="12" ss:Color="#1FB714"/>
<NumberFormat ss:Format="Standard"/>
</Style>
<Style ss:ID="s70">
<Alignment ss:Horizontal="Right" ss:Vertical="Bottom" ss:WrapText="1"/>
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="12" ss:Color="#1FB714"/>
<NumberFormat ss:Format="Percent"/>
</Style>
<Style ss:ID="s71">
<Alignment ss:Horizontal="Right" ss:Vertical="Bottom" ss:WrapText="1"/>
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="12" ss:Color="#DD0806"/>
<NumberFormat ss:Format="Percent"/>
</Style>
</Styles>
<xsl:if test="$pageBreakAfterTable=1">
<xsl:apply-templates select=".//table" />
</xsl:if>
<xsl:if test="$pageBreakAfterTable=0">
<xsl:call-template name="processTables">
<xsl:with-param name="tables" select="//html/body/table"/>
</xsl:call-template>
</xsl:if>
</Workbook>
</xsl:template>
<xsl:template name="processTables">
<xsl:param name="tables"/>
<Worksheet ss:Name="Report Results">
<Table ss:ExpandedColumnCount="{count(.//tr/th)}" ss:ExpandedRowCount="{count(.//tr)}" x:FullColumns="1" x:FullRows="1" ss:DefaultRowHeight="15">
<xsl:for-each select="$tables">
<!-- <Column ss:Width="138"/>
<Column ss:Width="260"/>-->
<xsl:apply-templates select=".//tr" />
</xsl:for-each>
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<PageLayoutZoom>0</PageLayoutZoom>
<TopRowVisible>0</TopRowVisible>
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
</Worksheet>
</xsl:template>
<xsl:template match="table">
<Worksheet ss:Name="Sheet{count(preceding::table) + 1}">
<Table ss:ExpandedColumnCount="{count(.//tr/th)}" ss:ExpandedRowCount="{count(.//tr)}" x:FullColumns="1" x:FullRows="1" ss:DefaultRowHeight="15">
<Column ss:Width="138"/>
<Column ss:Width="260"/>
<xsl:apply-templates select=".//tr" />
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<PageLayoutZoom>0</PageLayoutZoom>
<TopRowVisible>0</TopRowVisible>
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
</Worksheet>
</xsl:template>
<xsl:template match="tr">
<Row>
<xsl:for-each select="./node()">
<xsl:if test="normalize-space(.) != '' or normalize-space(@*) != ''">
<Cell>
<xsl:attribute name="ss:MergeAcross">
<xsl:choose><xsl:when test="@colspan > 1"><xsl:value-of select="@colspan - 1" /></xsl:when><xsl:otherwise>0</xsl:otherwise></xsl:choose>
</xsl:attribute>
<xsl:attribute name="ss:MergeDown">
<xsl:choose><xsl:when test="@rowspan > 1"><xsl:value-of select="@rowspan - 1" /></xsl:when><xsl:otherwise>0</xsl:otherwise></xsl:choose>
</xsl:attribute>
<xsl:attribute name="ss:StyleID">
<xsl:choose>
<xsl:when test="name(.)='th'">s63</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="contains(@class,' green')">
<xsl:choose>
<xsl:when test="contains(text(),'%')">s70</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="contains(@class,' numeric')">s69</xsl:when>
<xsl:otherwise>s66</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="contains(@class,' red')">
<xsl:choose>
<xsl:when test="contains(text(),'%')">s71</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="contains(@class,' numeric')">s68</xsl:when>
<xsl:otherwise>s65</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>s62</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<Data>
<xsl:attribute name="ss:Type">
<xsl:choose>
<xsl:when test="contains(text(),'%')">String</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="contains(@class,' numeric')">Number</xsl:when>
<xsl:otherwise>String</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:value-of select="text()"/>
</Data>
</Cell>
</xsl:if>
</xsl:for-each>
</Row>
</xsl:template>
</xsl:stylesheet>