Click here to Skip to main content
15,881,938 members
Articles / Web Development / HTML

Generating Word Reports / Documents

Rate me:
Please Sign up or sign in to vote.
4.94/5 (122 votes)
4 Oct 2009CPOL22 min read 702.3K   8K   544  
Generate Word documents by appling XSLT on XML data.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:sl="http://schemas.microsoft.com/schemaLibrary/2003/core" xmlns:aml="http://schemas.microsoft.com/aml/2001/core" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:ns0="http://schemas.microsoft.com/GeneratingWordDocuments/GroupingExample.xsd">
  <xsl:output method="xml" encoding="UTF-8" standalone="yes" />
  <xsl:template match="/">
    <xsl:processing-instruction name="mso-application">
      <xsl:text>progid="Word.Document"</xsl:text>
    </xsl:processing-instruction>
    <w:wordDocument xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:sl="http://schemas.microsoft.com/schemaLibrary/2003/core" xmlns:aml="http://schemas.microsoft.com/aml/2001/core" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:ns0="http://schemas.microsoft.com/GeneratingWordDocuments/GroupingExample.xsd" w:macrosPresent="no" w:embeddedObjPresent="no" w:ocxPresent="no" xml:space="preserve">
      <o:DocumentProperties>
        <o:Author>xxx</o:Author>
        <o:LastAuthor>xxx</o:LastAuthor>
        <o:Revision>2</o:Revision>
        <o:TotalTime>0</o:TotalTime>
        <o:Created>2007-10-17T21:56:00Z</o:Created>
        <o:LastSaved>2007-10-17T21:56:00Z</o:LastSaved>
        <o:Pages>1</o:Pages>
        <o:Words>15</o:Words>
        <o:Characters>89</o:Characters>
        <o:Lines>1</o:Lines>
        <o:Paragraphs>1</o:Paragraphs>
        <o:CharactersWithSpaces>103</o:CharactersWithSpaces>
        <o:Version>11.6568</o:Version>
      </o:DocumentProperties>
      <w:fonts>
        <w:defaultFonts w:ascii="Times New Roman" w:fareast="Times New Roman" w:h-ansi="Times New Roman" w:cs="Times New Roman" />
      </w:fonts>
      <w:lists>
        <w:listDef w:listDefId="0">
          <w:lsid w:val="57522785" />
          <w:plt w:val="HybridMultilevel" />
          <w:tmpl w:val="AF4A5BE4" />
          <w:lvl w:ilvl="0" w:tplc="0409000F">
            <w:start w:val="1" />
            <w:lvlText w:val="%1." />
            <w:lvlJc w:val="left" />
            <w:pPr>
              <w:tabs>
                <w:tab w:val="list" w:pos="720" />
              </w:tabs>
              <w:ind w:left="720" w:hanging="360" />
            </w:pPr>
          </w:lvl>
          <w:lvl w:ilvl="1" w:tplc="04090019">
            <w:start w:val="1" />
            <w:nfc w:val="4" />
            <w:lvlText w:val="%2." />
            <w:lvlJc w:val="left" />
            <w:pPr>
              <w:tabs>
                <w:tab w:val="list" w:pos="1440" />
              </w:tabs>
              <w:ind w:left="1440" w:hanging="360" />
            </w:pPr>
          </w:lvl>
          <w:lvl w:ilvl="2" w:tplc="0409001B">
            <w:start w:val="1" />
            <w:nfc w:val="2" />
            <w:lvlText w:val="%3." />
            <w:lvlJc w:val="right" />
            <w:pPr>
              <w:tabs>
                <w:tab w:val="list" w:pos="2160" />
              </w:tabs>
              <w:ind w:left="2160" w:hanging="180" />
            </w:pPr>
          </w:lvl>
          <w:lvl w:ilvl="3" w:tplc="0409000F" w:tentative="on">
            <w:start w:val="1" />
            <w:lvlText w:val="%4." />
            <w:lvlJc w:val="left" />
            <w:pPr>
              <w:tabs>
                <w:tab w:val="list" w:pos="2880" />
              </w:tabs>
              <w:ind w:left="2880" w:hanging="360" />
            </w:pPr>
          </w:lvl>
          <w:lvl w:ilvl="4" w:tplc="04090019" w:tentative="on">
            <w:start w:val="1" />
            <w:nfc w:val="4" />
            <w:lvlText w:val="%5." />
            <w:lvlJc w:val="left" />
            <w:pPr>
              <w:tabs>
                <w:tab w:val="list" w:pos="3600" />
              </w:tabs>
              <w:ind w:left="3600" w:hanging="360" />
            </w:pPr>
          </w:lvl>
          <w:lvl w:ilvl="5" w:tplc="0409001B" w:tentative="on">
            <w:start w:val="1" />
            <w:nfc w:val="2" />
            <w:lvlText w:val="%6." />
            <w:lvlJc w:val="right" />
            <w:pPr>
              <w:tabs>
                <w:tab w:val="list" w:pos="4320" />
              </w:tabs>
              <w:ind w:left="4320" w:hanging="180" />
            </w:pPr>
          </w:lvl>
          <w:lvl w:ilvl="6" w:tplc="0409000F" w:tentative="on">
            <w:start w:val="1" />
            <w:lvlText w:val="%7." />
            <w:lvlJc w:val="left" />
            <w:pPr>
              <w:tabs>
                <w:tab w:val="list" w:pos="5040" />
              </w:tabs>
              <w:ind w:left="5040" w:hanging="360" />
            </w:pPr>
          </w:lvl>
          <w:lvl w:ilvl="7" w:tplc="04090019" w:tentative="on">
            <w:start w:val="1" />
            <w:nfc w:val="4" />
            <w:lvlText w:val="%8." />
            <w:lvlJc w:val="left" />
            <w:pPr>
              <w:tabs>
                <w:tab w:val="list" w:pos="5760" />
              </w:tabs>
              <w:ind w:left="5760" w:hanging="360" />
            </w:pPr>
          </w:lvl>
          <w:lvl w:ilvl="8" w:tplc="0409001B" w:tentative="on">
            <w:start w:val="1" />
            <w:nfc w:val="2" />
            <w:lvlText w:val="%9." />
            <w:lvlJc w:val="right" />
            <w:pPr>
              <w:tabs>
                <w:tab w:val="list" w:pos="6480" />
              </w:tabs>
              <w:ind w:left="6480" w:hanging="180" />
            </w:pPr>
          </w:lvl>
        </w:listDef>
        <w:list w:ilfo="1">
          <w:ilst w:val="0" />
        </w:list>
      </w:lists>
      <w:styles>
        <w:versionOfBuiltInStylenames w:val="4" />
        <w:latentStyles w:defLockedState="off" w:latentStyleCount="156" />
        <w:style w:type="paragraph" w:default="on" w:styleId="Normal">
          <w:name w:val="Normal" />
          <w:rPr>
            <wx:font wx:val="Times New Roman" />
            <w:sz w:val="24" />
            <w:sz-cs w:val="24" />
            <w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA" />
          </w:rPr>
        </w:style>
        <w:style w:type="character" w:default="on" w:styleId="DefaultParagraphFont">
          <w:name w:val="Default Paragraph Font" />
          <w:semiHidden />
        </w:style>
        <w:style w:type="table" w:default="on" w:styleId="TableNormal">
          <w:name w:val="Normal Table" />
          <wx:uiName wx:val="Table Normal" />
          <w:semiHidden />
          <w:rPr>
            <wx:font wx:val="Times New Roman" />
          </w:rPr>
          <w:tblPr>
            <w:tblInd w:w="0" w:type="dxa" />
            <w:tblCellMar>
              <w:top w:w="0" w:type="dxa" />
              <w:left w:w="108" w:type="dxa" />
              <w:bottom w:w="0" w:type="dxa" />
              <w:right w:w="108" w:type="dxa" />
            </w:tblCellMar>
          </w:tblPr>
        </w:style>
        <w:style w:type="list" w:default="on" w:styleId="NoList">
          <w:name w:val="No List" />
          <w:semiHidden />
        </w:style>
        <w:style w:type="table" w:styleId="TableGrid">
          <w:name w:val="Table Grid" />
          <w:basedOn w:val="TableNormal" />
          <w:rsid w:val="00370ED5" />
          <w:rPr>
            <wx:font wx:val="Times New Roman" />
          </w:rPr>
          <w:tblPr>
            <w:tblInd w:w="0" w:type="dxa" />
            <w:tblBorders>
              <w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" />
              <w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" />
              <w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" />
              <w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" />
              <w:insideH w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" />
              <w:insideV w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" />
            </w:tblBorders>
            <w:tblCellMar>
              <w:top w:w="0" w:type="dxa" />
              <w:left w:w="108" w:type="dxa" />
              <w:bottom w:w="0" w:type="dxa" />
              <w:right w:w="108" w:type="dxa" />
            </w:tblCellMar>
          </w:tblPr>
        </w:style>
      </w:styles>
      <w:docPr>
        <w:view w:val="print" />
        <w:zoom w:percent="70" />
        <w:doNotEmbedSystemFonts />
        <w:proofState w:spelling="clean" w:grammar="clean" />
        <w:attachedTemplate w:val="" />
        <w:defaultTabStop w:val="720" />
        <w:punctuationKerning />
        <w:characterSpacingControl w:val="DontCompress" />
        <w:optimizeForBrowser />
        <w:validateAgainstSchema />
        <w:saveInvalidXML w:val="off" />
        <w:ignoreMixedContent />
        <w:alwaysShowPlaceholderText w:val="off" />
        <w:compat>
          <w:breakWrappedTables />
          <w:snapToGridInCell />
          <w:wrapTextWithPunct />
          <w:useAsianBreakRules />
          <w:dontGrowAutofit />
        </w:compat>
        <w:showXMLTags w:val="off" />
      </w:docPr>
      <w:body>
        <wx:sect>
          <xsl:apply-templates select="ns0:root" />
          <w:sectPr>
            <w:pgSz w:w="12240" w:h="15840" />
            <w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="720" w:footer="720" w:gutter="0" />
            <w:cols w:space="720" />
            <w:docGrid w:line-pitch="360" />
          </w:sectPr>
        </wx:sect>
      </w:body>
      <o:CustomDocumentProperties>
        <o:processingInstructions dt:dt="string"> <xsl:for-each select="processing-instruction()"><xsl:text>&lt;?</xsl:text><xsl:value-of select="name()" /><xsl:text> </xsl:text><xsl:value-of select="." /><xsl:text>?&gt;</xsl:text></xsl:for-each></o:processingInstructions>
      </o:CustomDocumentProperties>
    </w:wordDocument>
  </xsl:template>
  <xsl:template match="/ns0:root">
    <ns0:root>
      <xsl:for-each select="@ns0:*|@*[namespace-uri()='']">
        <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
          <xsl:value-of select="." />
        </xsl:attribute>
      </xsl:for-each>
      <w:p />
      <xsl:apply-templates select="ns0:Group" />
      <w:p />
    </ns0:root>
  </xsl:template>
  <xsl:template match="/ns0:root/ns0:Group">
    <ns0:Group>
      <xsl:for-each select="@ns0:*|@*[namespace-uri()='']">
        <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
          <xsl:value-of select="." />
        </xsl:attribute>
      </xsl:for-each>
      <xsl:apply-templates select="ns0:GroupName" />
      <w:tbl>
        <w:tblPr>
          <w:tblStyle w:val="TableGrid" />
          <w:tblW w:w="9171" w:type="dxa" />
          <w:tblLook w:val="01E0" />
        </w:tblPr>
        <w:tblGrid>
          <w:gridCol w:w="2359" />
          <w:gridCol w:w="2180" />
          <w:gridCol w:w="2316" />
          <w:gridCol w:w="2316" />
        </w:tblGrid>
        <w:tr>
          <w:tc>
            <w:tcPr>
              <w:tcW w:w="2359" w:type="dxa" />
              <w:shd w:val="clear" w:color="auto" w:fill="F3F3F3" />
            </w:tcPr>
            <w:p>
              <w:pPr>
                <w:rPr>
                  <w:b />
                </w:rPr>
              </w:pPr>
              <w:r>
                <w:rPr>
                  <w:b />
                </w:rPr> <w:t><xsl:text>Item name</xsl:text></w:t></w:r>
            </w:p>
          </w:tc>
          <w:tc>
            <w:tcPr>
              <w:tcW w:w="2180" w:type="dxa" />
              <w:shd w:val="clear" w:color="auto" w:fill="F3F3F3" />
            </w:tcPr>
            <w:p>
              <w:pPr>
                <w:rPr>
                  <w:b />
                </w:rPr>
              </w:pPr>
              <w:r>
                <w:rPr>
                  <w:b />
                </w:rPr> <w:t><xsl:text>Price</xsl:text></w:t></w:r>
            </w:p>
          </w:tc>
          <w:tc>
            <w:tcPr>
              <w:tcW w:w="2316" w:type="dxa" />
              <w:shd w:val="clear" w:color="auto" w:fill="F3F3F3" />
            </w:tcPr>
            <w:p>
              <w:pPr>
                <w:rPr>
                  <w:b />
                </w:rPr>
              </w:pPr>
              <w:r>
                <w:rPr>
                  <w:b />
                </w:rPr> <w:t><xsl:text>Quantity</xsl:text></w:t></w:r>
            </w:p>
          </w:tc>
          <w:tc>
            <w:tcPr>
              <w:tcW w:w="2316" w:type="dxa" />
              <w:shd w:val="clear" w:color="auto" w:fill="F3F3F3" />
            </w:tcPr>
            <w:p>
              <w:pPr>
                <w:rPr>
                  <w:b />
                </w:rPr>
              </w:pPr>
              <w:r>
                <w:rPr>
                  <w:b />
                </w:rPr> <w:t><xsl:text>P*Q</xsl:text></w:t></w:r>
            </w:p>
          </w:tc>
        </w:tr>
        <xsl:apply-templates select="ns0:SummaryPrice|ns0:GroupItems" />
      </w:tbl>
      <w:p />
      <w:p />
    </ns0:Group>
  </xsl:template>
  <xsl:template match="/ns0:root/ns0:Group/ns0:SummaryPrice">
    <w:tr>
      <w:tc>
        <w:tcPr>
          <w:tcW w:w="2359" w:type="dxa" />
          <w:shd w:val="clear" w:color="auto" w:fill="F3F3F3" />
        </w:tcPr>
        <w:p>
          <w:pPr>
            <w:rPr>
              <w:b />
            </w:rPr>
          </w:pPr>
          <w:r>
            <w:rPr>
              <w:b />
            </w:rPr> <w:t><xsl:text>Total price:</xsl:text></w:t></w:r>
        </w:p>
      </w:tc>
      <w:tc>
        <w:tcPr>
          <w:tcW w:w="2180" w:type="dxa" />
          <w:shd w:val="clear" w:color="auto" w:fill="F3F3F3" />
        </w:tcPr>
        <w:p>
          <w:pPr>
            <w:rPr>
              <w:b />
            </w:rPr>
          </w:pPr>
        </w:p>
      </w:tc>
      <w:tc>
        <w:tcPr>
          <w:tcW w:w="2316" w:type="dxa" />
          <w:shd w:val="clear" w:color="auto" w:fill="F3F3F3" />
        </w:tcPr>
        <w:p>
          <w:pPr>
            <w:rPr>
              <w:b />
            </w:rPr>
          </w:pPr>
        </w:p>
      </w:tc>
      <w:tc>
        <w:tcPr>
          <w:tcW w:w="2316" w:type="dxa" />
          <w:shd w:val="clear" w:color="auto" w:fill="F3F3F3" />
        </w:tcPr>
        <ns0:SummaryPrice>
          <xsl:for-each select="@ns0:*|@*[namespace-uri()='']">
            <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
              <xsl:value-of select="." />
            </xsl:attribute>
          </xsl:for-each>
          <w:p>
            <w:pPr>
              <w:rPr>
                <w:b />
              </w:rPr>
            </w:pPr>
            <w:r>
              <w:rPr>
                <w:b />
              </w:rPr> <w:t><xsl:value-of select="." /></w:t></w:r>
          </w:p>
        </ns0:SummaryPrice>
      </w:tc>
    </w:tr>
  </xsl:template>
  <xsl:template match="/ns0:root/ns0:Group/ns0:GroupItems">
    <ns0:GroupItems>
      <xsl:for-each select="@ns0:*|@*[namespace-uri()='']">
        <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
          <xsl:value-of select="." />
        </xsl:attribute>
      </xsl:for-each>
      <w:tr>
        <xsl:apply-templates select="ns0:TotalPrice|ns0:ItemQuantity|ns0:ItemName|ns0:ItemPrice" />
      </w:tr>
    </ns0:GroupItems>
  </xsl:template>
  <xsl:template match="/ns0:root/ns0:Group/ns0:GroupItems/ns0:TotalPrice">
    <w:tc>
      <w:tcPr>
        <w:tcW w:w="2316" w:type="dxa" />
      </w:tcPr>
      <ns0:TotalPrice>
        <xsl:for-each select="@ns0:*|@*[namespace-uri()='']">
          <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
            <xsl:value-of select="." />
          </xsl:attribute>
        </xsl:for-each>
        <w:p>
          <w:r> <w:t><xsl:value-of select="." /></w:t></w:r>
        </w:p>
      </ns0:TotalPrice>
    </w:tc>
  </xsl:template>
  <xsl:template match="/ns0:root/ns0:Group/ns0:GroupItems/ns0:ItemName">
    <w:tc>
      <w:tcPr>
        <w:tcW w:w="2359" w:type="dxa" />
      </w:tcPr>
      <ns0:ItemName>
        <xsl:for-each select="@ns0:*|@*[namespace-uri()='']">
          <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
            <xsl:value-of select="." />
          </xsl:attribute>
        </xsl:for-each>
        <w:p>
          <w:r> <w:t><xsl:value-of select="." /></w:t></w:r>
        </w:p>
      </ns0:ItemName>
    </w:tc>
  </xsl:template>
  <xsl:template match="/ns0:root/ns0:Group/ns0:GroupItems/ns0:ItemQuantity">
    <w:tc>
      <w:tcPr>
        <w:tcW w:w="2316" w:type="dxa" />
      </w:tcPr>
      <ns0:ItemQuantity>
        <xsl:for-each select="@ns0:*|@*[namespace-uri()='']">
          <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
            <xsl:value-of select="." />
          </xsl:attribute>
        </xsl:for-each>
        <w:p>
          <w:r> <w:t><xsl:value-of select="." /></w:t></w:r>
        </w:p>
      </ns0:ItemQuantity>
    </w:tc>
  </xsl:template>
  <xsl:template match="/ns0:root/ns0:Group/ns0:GroupItems/ns0:ItemPrice">
    <w:tc>
      <w:tcPr>
        <w:tcW w:w="2180" w:type="dxa" />
      </w:tcPr>
      <ns0:ItemPrice>
        <xsl:for-each select="@ns0:*|@*[namespace-uri()='']">
          <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
            <xsl:value-of select="." />
          </xsl:attribute>
        </xsl:for-each>
        <w:p>
          <w:r> <w:t><xsl:value-of select="." /></w:t></w:r>
        </w:p>
      </ns0:ItemPrice>
    </w:tc>
  </xsl:template>
  <xsl:template match="/ns0:root/ns0:Group/ns0:GroupName">
    <ns0:GroupName>
      <xsl:for-each select="@ns0:*|@*[namespace-uri()='']">
        <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
          <xsl:value-of select="." />
        </xsl:attribute>
      </xsl:for-each>
      <w:p>
        <w:pPr>
          <w:rPr>
            <w:b />
          </w:rPr>
        </w:pPr>
        <w:r>
          <w:rPr>
            <w:b />
          </w:rPr> <w:t><xsl:value-of select="." /></w:t></w:r>
      </w:p>
    </ns0:GroupName>
  </xsl:template>
</xsl:stylesheet>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Chief Technology Officer
United States United States
If you liked this article, consider reading other articles by me. For republishing article on other websites, please contact me by leaving a comment.

Comments and Discussions