title: Converting html to xls using xsl
body: <p>I have the following requirement. </p>
  
  <p>input will be </p>
  
  <pre><code>———
  ———
  
  &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;&lt;/th&gt;
              &lt;th&gt;&lt;/th&gt;
              &lt;th&gt;&lt;/th&gt;
              …………..
              …………...
          &lt;/tr&gt;
              …………..
              …………...
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;/td&gt;
              &lt;td&gt;&lt;/td&gt;
              &lt;td&gt;&lt;/td&gt;
              …………..
              …………...
          &lt;/tr&gt;
              …………..
              …………... 
      &lt;/tbody&gt;
  &lt;/table&gt;
  
  ———
  ———
  </code></pre>
  
  <p>like this multiple tables.</p>
  
  <p>Now I need to create different worksheets (for workbook / Excel file) for different tables. no of worksheets depends on no of tables. I need to do this using Xslt.</p>
  
  <p>No of tables are not constant it will differ.</p>
  
  <p>If you have any idea please let me know. I did some research in the Internet, but I couldn’t find anything. </p>
  
  <p>I wrote the following xsl. I was able to generate multiple sheets. But the table is only printed on the first sheet. I want to have the table over all sheets.</p>
  
  <pre><code>&lt;?xml version="1.0"?&gt;
  &lt;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"&gt;
  
      &lt;xsl:output method="html" omit-xml-declaration="yes" /&gt;
  
      &lt;!-- 
          Beginning of template processing, start at document root
      //--&gt;
          &lt;xsl:variable name="pageBreakAfterTable"&gt;false&lt;/xsl:variable&gt;
          &lt;xsl:template match="/"&gt;
  
          &lt;/xsl:template&gt;
      &lt;xsl:template match="/"&gt;  
          &lt;xsl:text disable-output-escaping="yes"&gt;&amp;lt;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"&amp;gt;
              &amp;lt;head&amp;gt;
                  &amp;lt;meta http-equiv=Content-Type content="text/html; charset=windows-1252"&amp;gt;
                  &amp;lt;meta name=ProgId content=Excel.Sheet&amp;gt;
                  &amp;lt;meta name=Generator content="Microsoft Excel 11"&amp;gt;
  
                  &amp;lt;!--[if gte mso 9]&amp;gt;&amp;lt;xml&amp;gt;
                   &amp;lt;x:ExcelWorkbook&amp;gt;
                    &amp;lt;x:ExcelWorksheets&amp;gt;
                  &lt;/xsl:text&gt;
  
              &lt;xsl:for-each select="//html/body/table"&gt;
                                  &lt;xsl:text disable-output-escaping="yes"&gt;
                                  &amp;lt;x:ExcelWorksheet&amp;gt;
                      &amp;lt;x:Name&amp;gt;Report Results&amp;lt;/x:Name&amp;gt;
                      &amp;lt;x:WorksheetOptions&amp;gt;
                       &amp;lt;x:Selected/&amp;gt;
                       &amp;lt;x:ShowGridlines/&amp;gt;
                       &amp;lt;x:ProtectContents&amp;gt;False&amp;lt;/x:ProtectContents&amp;gt;
                       &amp;lt;x:ProtectObjects&amp;gt;False&amp;lt;/x:ProtectObjects&amp;gt;
                       &amp;lt;x:ProtectScenarios&amp;gt;False&amp;lt;/x:ProtectScenarios&amp;gt;
                      &amp;lt;/x:WorksheetOptions&amp;gt;
                                  &lt;/xsl:text&gt; 
                                  &lt;xsl:element name="table"&gt;
                  &lt;xsl:call-template name="processRows"&gt;
                      &lt;xsl:with-param name="rows" select="./thead/tr"/&gt;
                  &lt;/xsl:call-template&gt;
                  &lt;xsl:call-template name="processRows"&gt;
                      &lt;xsl:with-param name="rows" select="./tbody/tr"/&gt;
                  &lt;/xsl:call-template&gt;
                  &lt;xsl:call-template name="processRows"&gt;
                      &lt;xsl:with-param name="rows" select="./tr"/&gt;
                  &lt;/xsl:call-template&gt;
                  &lt;xsl:element name="tr"/&gt;
                                  &lt;/xsl:element&gt;
                         &lt;xsl:text disable-output-escaping="yes"&gt;&amp;lt;/x:ExcelWorksheet&amp;gt;&lt;/xsl:text&gt;
  
              &lt;/xsl:for-each&gt;
                          &lt;xsl:text disable-output-escaping="yes"&gt;
                          &amp;lt;/x:ExcelWorksheets&amp;gt;
                    &amp;lt;x:ProtectStructure&amp;gt;False&amp;lt;/x:ProtectStructure&amp;gt;
                    &amp;lt;x:ProtectWindows&amp;gt;False&amp;lt;/x:ProtectWindows&amp;gt;
                   &amp;lt;/x:ExcelWorkbook&amp;gt;
                  &amp;lt;/xml&amp;gt;&amp;lt;![endif]--&amp;gt;
  
              &amp;lt;/head&amp;gt;
              &amp;lt;body&amp;gt;&lt;/xsl:text&gt;
                          &lt;xsl:text disable-output-escaping="yes"&gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;/xsl:text&gt;
  
          &lt;!-- Translate each table --&gt;
  &lt;!--        &lt;xsl:call-template name="processTables"&gt;
              &lt;xsl:with-param name="tables" select="//html/body/table"/&gt;
          &lt;/xsl:call-template&gt;--&gt;
  
  
      &lt;/xsl:template&gt;
  
  &lt;!--    &lt;xsl:template name="processTables"&gt;  
          &lt;xsl:param name="tables"/&gt;
  
      &lt;/xsl:template&gt;--&gt;
  
      &lt;xsl:template name="processRows"&gt;
          &lt;xsl:param name="rows"/&gt;
  
          &lt;xsl:for-each select="$rows"&gt;
              &lt;xsl:if test="not(contains(@class,'emptyValue'))"&gt;
  
                  &lt;xsl:element name="tr"&gt;
                      &lt;xsl:attribute name="style"&gt;
                          &lt;!-- Do we need to display a drill-down depth? --&gt;
                          &lt;xsl:choose&gt;
                              &lt;xsl:when test="count(./node()[contains(@class,'ds-drilldown-level-6')]) &amp;gt; 0"&gt;
                                  &lt;xsl:text&gt;mso-outline-level:6;&lt;/xsl:text&gt;
                              &lt;/xsl:when&gt;
                              &lt;xsl:when test="count(./node()[contains(@class,'ds-drilldown-level-5')]) &amp;gt; 0"&gt;
                                  &lt;xsl:text&gt;mso-outline-level:5;&lt;/xsl:text&gt;
                              &lt;/xsl:when&gt;
                              &lt;xsl:when test="count(./node()[contains(@class,'ds-drilldown-level-4')]) &amp;gt; 0"&gt;
                                  &lt;xsl:text&gt;mso-outline-level:4;&lt;/xsl:text&gt;
                              &lt;/xsl:when&gt;
                              &lt;xsl:when test="count(./node()[contains(@class,'ds-drilldown-level-3')]) &amp;gt; 0"&gt;
                                  &lt;xsl:text&gt;mso-outline-level:3;&lt;/xsl:text&gt;
                              &lt;/xsl:when&gt;
                              &lt;xsl:when test="count(./node()[contains(@class,'ds-drilldown-level-2')]) &amp;gt; 0"&gt;
                                  &lt;xsl:text&gt;mso-outline-level:2;&lt;/xsl:text&gt;
                              &lt;/xsl:when&gt;
                              &lt;xsl:when test="count(./node()[contains(@class,'ds-drilldown-level-1')]) &amp;gt; 0"&gt;
                                  &lt;xsl:text&gt;mso-outline-level:1;&lt;/xsl:text&gt;
                              &lt;/xsl:when&gt;
                          &lt;/xsl:choose&gt;
                      &lt;/xsl:attribute&gt;
  
                      &lt;xsl:for-each select="./node()"&gt;
                          &lt;xsl:if test="normalize-space(.) != '' or normalize-space(@*) != ''"&gt;
                              &lt;xsl:element name="td"&gt;
                                  &lt;xsl:if test="@colspan"&gt;
                                      &lt;xsl:copy-of select="@colspan"/&gt;
                                  &lt;/xsl:if&gt;
                                  &lt;xsl:if test="@rowspan"&gt;
                                      &lt;xsl:copy-of select="@rowspan"/&gt;
                                  &lt;/xsl:if&gt;
                                  &lt;xsl:if test="name(.)='td'"&gt;
                                      &lt;xsl:attribute name="align"&gt;&lt;xsl:text&gt;right&lt;/xsl:text&gt;&lt;/xsl:attribute&gt;
                                  &lt;/xsl:if&gt;
                                  &lt;xsl:attribute name="style"&gt;
                                      &lt;xsl:if test="name(.)='th'"&gt;
                                          &lt;xsl:text&gt; font-weight:bold;&lt;/xsl:text&gt;
                                      &lt;/xsl:if&gt;
                                      &lt;xsl:if test="contains(@class,' red')"&gt;
                                          &lt;xsl:text&gt; color:red;&lt;/xsl:text&gt;
                                      &lt;/xsl:if&gt;
                                      &lt;xsl:if test="contains(@class,' green')"&gt;
                                          &lt;xsl:text&gt; color:green;&lt;/xsl:text&gt;
                                      &lt;/xsl:if&gt;
                                  &lt;/xsl:attribute&gt;
  
                                  &lt;xsl:value-of select="text()"/&gt;
                              &lt;/xsl:element&gt;
                          &lt;/xsl:if&gt;
                      &lt;/xsl:for-each&gt;
                  &lt;/xsl:element&gt;
              &lt;/xsl:if&gt;
          &lt;/xsl:for-each&gt;
      &lt;/xsl:template&gt;
  &lt;/xsl:stylesheet&gt;
  </code></pre>