使用XSLT将XML转换为Excel文件

时间:2018-02-22 17:03:38

标签: xml excel xslt

提前致谢, 我是XSLT的新手,如果有任何我正在完全做错的话请告诉我! 我试图使用XSLT将这段XML转换为Excel电子表格

  <MODULO>
    <NAME>ObtemNovoSubsidiarias</NAME>
    <VALUES>
      <ROW>
        <Funcao>Sócio</Funcao>
        <Nome>WURTH INTERNATIONAL AG</Nome>
        <NumeroSine>100088</NumeroSine>
        <pais>PORTUGAL</pais>
      </ROW>
      <ROW>
        <FormacaoAcademica />
        <Funcao>Sócio</Funcao>
        <Nome>WURTH SCHWEIZ AG</Nome>
        <NumeroSine>1394204</NumeroSine>
        <pais />
      </ROW>
    </VALUES>
  </MODULO>

这是XSLT我只有这个,我有其他标签,但这是我遇到的问题。

 <xsl:when test="NAME='ObtemNovoSubsidiarias'">
            <Worksheet ss:Name="Empresas_Soc">
              <Table>
                <ss:Column ss:Width="100"/>
                <ss:Column ss:Width="350"/>
                <xsl:for-each select="VALUES/ROW">
                  <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">
                        <xsl:value-of select="Nome"/>
                      </Data>
                    </Cell>
                  </Row>
                  <Row ss:Index="{position() + 1}">
                    <Cell ss:Index="1" ss:StyleID="header">
                      <Data ss:Type="String">
                        TRUST Nº
                      </Data>
                    </Cell>
                    <Cell ss:Index="2" ss:StyleID="header">
                      <Data ss:Type="String">
                        <xsl:value-of select="NumeroSine"/>
                      </Data>
                    </Cell>
                  </Row>
                 <Row ss:Index="{position() + 2}">
                    <Cell ss:Index="1" ss:StyleID="header">
                      <Data ss:Type="String">
                        FUNÇÃO
                      </Data>
                    </Cell>
                    <Cell ss:Index="2" ss:StyleID="header">
                      <Data ss:Type="String">
                        <xsl:value-of select="Funcao"/>
                      </Data>
                    </Cell>
                  </Row>
                  <xsl:choose>
                    <xsl:when test="pais = ''">
                      <Row ss:Index="{position() + 3}">
                      </Row>
                    </xsl:when>
                    <xsl:otherwise>
                      <Row ss:Index="{position() + 3}">
                        <Cell ss:Index="1" ss:StyleID="header">
                          <Data ss:Type="String">
                            PAÍS
                          </Data>
                        </Cell>
                        <Cell ss:Index="2" ss:StyleID="header">
                          <Data ss:Type="String">
                            <xsl:value-of select="pais"/>
                          </Data>
                        </Cell>
                      </Row>
                    </xsl:otherwise>
                  </xsl:choose>               
                </xsl:for-each>
              </Table>
            </Worksheet>
          </xsl:when>

(注意:标签名为<ROW>,但它不是实际的行,其余的XML是实际的行,但是像这样的一些<MODULO>的组织方式不同,因为它的自动生成它就像那样,在这种情况下每个<ROW>它是一个不同的公司,我必须显示)

问题是,我可以分开展示每个<ROW>(公司),例如

Nome          WURTH
Funcao        Sócio
NumeroSine    100088
pais          PORTUGAL

然后在Excel中的空行和空白行之后显示另一个<ROW>。 我能够显示第一个,但第二个没有显示。 我尝试了几种不同的方法,例如为每个<table>制作另一个<ROW>,但这并不起作用。

如果有人可以帮助我,我会非常感激!

1 个答案:

答案 0 :(得分:1)

我认为您遇到的问题是每个ss:index设置ROW。使用position()给出了每个ROW的位置,因此在您的情况下将为1或2。但是,如果您{position() + 1}获取TRUST Nº行的索引,那么对于第一个ROW,索引将为2(这是正确的),但对于第二个ROW索引设置为3,它应该是7(因为每个ROW有4个excel行加一个空行)。

因此,表达式应该是{(position() - 1) * 5 + 2},它分别返回2和7。因此,您的xsl:for-each可能看起来像这样(我已经删除了填充第二个单元格的代码,只是为了让它更短)。

<xsl:for-each select="VALUES/ROW">
  <Row ss:Index="{(position() - 1) * 5 + 1}">
    <Cell ss:Index="1" ss:StyleID="header">
      <Data ss:Type="String">
        Nome
      </Data>
    </Cell>
  </Row>
  <Row ss:Index="{(position() - 1) * 5 + 2}">
    <Cell ss:Index="1" ss:StyleID="header">
      <Data ss:Type="String">
        TRUST Nº
      </Data>
    </Cell>
  </Row>
 <Row ss:Index="{(position() - 1) * 5 + 3}">
    <Cell ss:Index="1" ss:StyleID="header">
      <Data ss:Type="String">
        FUNÇÃO
      </Data>
    </Cell>
  </Row>
  <xsl:choose>
    <xsl:when test="pais = ''">
      <Row ss:Index="{(position() - 1) * 5 + 4}">
      </Row>
    </xsl:when>
    <xsl:otherwise>
      <Row ss:Index="{(position() - 1) * 5 + 4}">
        <Cell ss:Index="1" ss:StyleID="header">
          <Data ss:Type="String">
            PAÍS
          </Data>
        </Cell>
      </Row>
    </xsl:otherwise>
  </xsl:choose>           
  <Row ss:Index="{(position() - 1) * 5 + 5}">
  </Row>
</xsl:for-each>

但是,当你可能只需要一个pais元素时,这就有了添加两个空白行的问题。如果是这样,请尝试这样做......

<xsl:for-each select="VALUES/ROW">
  <xsl:variable name="base" select="count(preceding-sibling::ROW) * 4 + count(preceding-sibling::ROW[pais != ''])" />
  <Row ss:Index="{$base + 1}">
    <Cell ss:Index="1" ss:StyleID="header">
      <Data ss:Type="String">
        Nome
      </Data>
    </Cell>
  </Row>
  <Row ss:Index="{$base + 2}">
    <Cell ss:Index="1" ss:StyleID="header">
      <Data ss:Type="String">
        TRUST Nº
      </Data>
    </Cell>
  </Row>
 <Row ss:Index="{$base + 3}">
    <Cell ss:Index="1" ss:StyleID="header">
      <Data ss:Type="String">
        FUNÇÃO
      </Data>
    </Cell>
  </Row>
  <xsl:choose>
    <xsl:when test="pais = ''">
      <Row ss:Index="{$base + 4}">
      </Row>
    </xsl:when>
    <xsl:otherwise>
      <Row ss:Index="{$base + 4}">
        <Cell ss:Index="1" ss:StyleID="header">
          <Data ss:Type="String">
            PAÍS
          </Data>
        </Cell>
      </Row>
      <Row ss:Index="{$base + 5}">
      </Row>
    </xsl:otherwise>
  </xsl:choose>           
</xsl:for-each>