使用XSLT将XML转换为Excel文件

时间:2018-02-22 10:33:37

标签: xml excel xslt

在我不熟悉XSLT之前,我被要求将XML文件转换为Excel文件。

经过几个小时玩xslt后,我想出了这个。

这是我的XML样本,我用***模糊了一些信息,因为它是重要的东西!

<RELATORIO>
  <LANG>PT</LANG>
  <MODULO>
    <NAME>ObtemIdentificacao_P</NAME>
    <VALUES>
      <ROW>
        <Cae1>46740</Cae1>
        <Cae2 />
        <Cae3 />
        <CodCP>***</CodCP>
        <Concelho>SINTRA</Concelho>
        <DataInvestigacao>20160418</DataInvestigacao>
        <DescricaoCP>SINTRA</DescricaoCP>
        <Distrito>LISBOA</Distrito>
        <Email>info@wurth.pt</Email>
        <Fax1>*****</Fax1>
        <Fax2>****</Fax2>
        <Fax3 />
        <Internet>www.wurth.pt</Internet>
        <Localidade />
        <Moeda>EURO</Moeda>
        <Morada>Estrada Nacional - 249-4 - Abrunheira</Morada>
        <Nome>WURTH (PORTUGAL)-TECNICA DE MONTAGEM LDA</Nome>
        <NumeroContribuinte>****</NumeroContribuinte>
        <NumeroSine>38358</NumeroSine>
        <pais>174</pais>
        <Telefone1>***</Telefone1>
      </ROW>
    </VALUES>
  </MODULO>
</RELATORIO>

这是我提出的XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output omit-xml-declaration="no"/>
  <xsl:template match="/">
    <xsl:processing-instruction name="mso-application">progid="Excel.Sheet"</xsl:processing-instruction>
    <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
      <Styles>
        <Style ss:ID="header" ss:Name="Normal">
          <Font ss:FontName="Verdana" ss:Bold="1" />
        </Style>
      </Styles>
      <Worksheet ss:Name="Identificacao">
        <Table>
          <Row ss:Index="1">
            <Cell ss:Index="1" ss:StyleID="header">
              <Data ss:Type="String">Nome</Data>
            </Cell>
            <Cell ss:Index="2" ss:StyleID="header">
              <Data ss:Type="String">Nº Sine</Data>
            </Cell>
            <Cell ss:Index="3" ss:StyleID="header">
              <Data ss:Type="String">Nº Contribuinte</Data>
            </Cell>
            <Cell ss:Index="4" ss:StyleID="header">
              <Data ss:Type="String">Distrito</Data>
            </Cell>
            <Cell ss:Index="5" ss:StyleID="header">
              <Data ss:Type="String">Concelho</Data>
            </Cell>
            <Cell ss:Index="6" ss:StyleID="header">
              <Data ss:Type="String">Código Postal</Data>
            </Cell>
            <Cell ss:Index="7" ss:StyleID="header">
              <Data ss:Type="String">Morada</Data>
            </Cell>
            <Cell ss:Index="8" ss:StyleID="header">
              <Data ss:Type="String">Telefone</Data>
            </Cell>
            <Cell ss:Index="9" ss:StyleID="header">
              <Data ss:Type="String">Email</Data>
            </Cell>
            <Cell ss:Index="10" ss:StyleID="header">
              <Data ss:Type="String">Fax</Data>
            </Cell>
            <Cell ss:Index="11" ss:StyleID="header">
              <Data ss:Type="String">Pais</Data>
            </Cell>
          </Row>
          <Row ss:Index="{position()}">
            <Cell ss:Index="1">
              <Data ss:Type="String">
                <xsl:value-of select="VALUES/ROW/Nome"/>
              </Data>
            </Cell>
            <Cell ss:Index="2">
              <Data ss:Type="String">
                <xsl:value-of select="VALUES/ROW/NumeroSine"/>
              </Data>
            </Cell>
            <Cell ss:Index="3">
              <Data ss:Type="String">
                <xsl:value-of select="VALUES/ROW/NumeroContribuinte"/>
              </Data>
            </Cell>
            <Cell ss:Index="4">
              <Data ss:Type="String">
                <xsl:value-of select="VALUES/ROW/Distrito"/>
              </Data>
            </Cell>
            <Cell ss:Index="5">
              <Data ss:Type="String">
                <xsl:value-of select="VALUES/ROW/Concelho"/>
              </Data>
            </Cell>
            <Cell ss:Index="6">
              <Data ss:Type="String">
                <xsl:value-of select="VALUES/ROW/CodCP"/>
              </Data>
            </Cell>
            <Cell ss:Index="7">
              <Data ss:Type="String">
                <xsl:value-of select="VALUES/ROW/Morada"/>
              </Data>
            </Cell>
            <Cell ss:Index="8">
              <Data ss:Type="String">
                <xsl:value-of select="VALUES/ROW/Telefone1"/>
              </Data>
            </Cell>
            <Cell ss:Index="9">
              <Data ss:Type="String">
                <xsl:value-of select="VALUES/ROW/Email"/>
              </Data>
            </Cell>
            <Cell ss:Index="10">
              <Data ss:Type="String">
                <xsl:value-of select="VALUES/ROW/Fax1"/>
              </Data>
            </Cell>
            <Cell ss:Index="11">
              <Data ss:Type="String">
                <xsl:value-of select="VALUES/ROW/pais"/>
              </Data>
            </Cell>
          </Row>
        </Table>
      </Worksheet>
    </Workbook>
  </xsl:template>
</xsl:stylesheet>

此XSLT确实生成了一个Excel文件,但Excel中显示的唯一内容是字段的名称,例如

Nome | NºSine| NºContribuinte|等等..

但是字段下方没有显示任何值。

如何获取要在Excel文件中显示的节点内的文本值?

如果可能的话,我希望每个字段都有自己的行而不是列。

1 个答案:

答案 0 :(得分:1)

您想要每MODULO行一行吗?如果是这样,您应该使用xsl:for-eachxsl:apply-templates

选择这些元素

试试这个XSLT(我为了便于阅读而缩短了)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output omit-xml-declaration="no" indent="yes"/>

  <xsl:template match="/">
    <xsl:processing-instruction name="mso-application">progid="Excel.Sheet"</xsl:processing-instruction>
    <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
      <Styles>
        <Style ss:ID="header" ss:Name="Normal">
          <Font ss:FontName="Verdana" ss:Bold="1" />
        </Style>
      </Styles>
      <Worksheet ss:Name="Identificacao">
        <Table>
          <Row ss:Index="1">
            <Cell ss:Index="1" ss:StyleID="header">
              <Data ss:Type="String">Nome</Data>
            </Cell>
            <Cell ss:Index="2" ss:StyleID="header">
              <Data ss:Type="String">Nº Sine</Data>
            </Cell>
          </Row>
          <xsl:for-each select="RELATORIO/MODULO">
            <Row ss:Index="{position() + 1}">
              <Cell ss:Index="1">
                <Data ss:Type="String">
                  <xsl:value-of select="VALUES/ROW/Nome"/>
                </Data>
              </Cell>
              <Cell ss:Index="2">
                <Data ss:Type="String">
                  <xsl:value-of select="VALUES/ROW/NumeroSine"/>
                </Data>
              </Cell>
            </Row>   
          </xsl:for-each>
        </Table>
      </Worksheet>
    </Workbook>
  </xsl:template>
</xsl:stylesheet>

请注意它如何选择RELATORIO/MODULO而非MODULO。这是因为代码位于与/匹配的模板中,RELATORIO是文档节点,Trim是文档节点的子节点。