Xml+Xslt導出Excel實例


 

  最近研究了一下基於xml+Xslt的統計報表導出Excel功能,原有的設計是用JS實現,優點是實現起來比較簡單,缺點同樣很明顯,對導出復雜的表格無能為力,而且需要客戶端安裝Excel,另一種辦法是在服務器端實現,調用office的DLL直接操作Excel,可控范圍較廣,但是遇到大數據量的統計報表則響應較慢,這對於客戶來說是無法忍受的。於是,就有了基於xml+xslt的解決方案。由於Excel可另存為后綴名為.xml的數據格式,這就為這種解決方案提供了實現的可能性。
  實現原理:由於統計報表是基於xml+xslt實現,從數據庫取出的數據已保存在xml中,我們只需要將這xml暫存下來,然后用導出Excel所用的xslt文件轉換即可。
  實現過程:
      用於導出Excel所用的DepositExcel.xslt
  

xslt
<?xml version="1.0" encoding="gb2312" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="zkSuperMap">
    <?mso-application progid="Excel.Sheet"?>
    <Workbook 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">

      <Styles>
        <Style ss:ID="Default" ss:Name="Normal">
          <Alignment ss:Vertical="Center"/>
          <Borders/>
          <Font ss:FontName="宋體" x:CharSet="134" ss:Size="11" ss:Color="#000000"/>
          <Interior/>
          <NumberFormat/>
          <Protection/>
        </Style>
        <Style ss:ID="s10">
          <Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
        </Style>
        <Style ss:ID="s11">
          <Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
          <Borders>
            <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
            <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
            <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
            <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
          </Borders>
        </Style>
      </Styles>
      <Worksheet ss:Name="Sheet1">
        <Table ss:ExpandedColumnCount="9"  x:FullColumns="1"
   x:FullRows="1" ss:DefaultColumnWidth="54" ss:DefaultRowHeight="13.5">
          <Row ss:AutoFitHeight="0">
            <Cell ss:MergeAcross="8" ss:StyleID="s10">
              <Data ss:Type="String">商品房專項維修資金繳存、使用、變更周報表</Data>
            </Cell>
          </Row>
          <Row ss:AutoFitHeight="0">
            <Cell ss:MergeAcross="8" ss:StyleID="s10">
              <Data ss:Type="String">
                <xsl:value-of select="BEGINTEIM" /><xsl:value-of select="ENDTIME" />
              </Data>
            </Cell>
          </Row>
          <Row ss:AutoFitHeight="0">
            <Cell ss:MergeDown="1" ss:StyleID="s11">
              <Data ss:Type="String">序號</Data>
            </Cell>
            <Cell ss:MergeDown="1" ss:StyleID="s11">
              <Data ss:Type="String">小區名稱</Data>
            </Cell>
            <Cell ss:MergeAcross="1" ss:StyleID="s11">
              <Data ss:Type="String">繳   存</Data>
            </Cell>
            <Cell ss:MergeAcross="1" ss:StyleID="s11">
              <Data ss:Type="String">使   用</Data>
            </Cell>
            <Cell ss:StyleID="s11">
              <Data ss:Type="String">變 更</Data>
            </Cell>
            <Cell ss:MergeAcross="1" ss:MergeDown="1" ss:StyleID="s11">
              <Data ss:Type="String">備   注</Data>
            </Cell>
          </Row>
          <Row ss:AutoFitHeight="0">
            <Cell ss:StyleID="s11" ss:Index="3">
              <Data ss:Type="String">戶 數</Data>
            </Cell>
            <Cell ss:StyleID="s11">
              <Data ss:Type="String">金 額(元)</Data>
            </Cell>
            <Cell ss:StyleID="s11">
              <Data ss:Type="String">戶 數</Data>
            </Cell>
            <Cell ss:StyleID="s11">
              <Data ss:Type="String">金 額(元)</Data>
            </Cell>
            <Cell ss:StyleID="s11">
              <Data ss:Type="String">戶 數</Data>
            </Cell>
          </Row>
          <xsl:for-each select="FUNDINFO">
            <Row ss:AutoFitHeight="0">
              <Cell ss:StyleID="s11">
                <Data ss:Type="String">
                  <xsl:value-of select="position()" />
                </Data>
              </Cell>
              <Cell ss:StyleID="s11">
                <Data ss:Type="String">
                  <xsl:value-of select="DISTRICT_NAME" />
                </Data>
              </Cell>
              <Cell ss:StyleID="s11">
                <Data ss:Type="String">
                  <xsl:value-of select="HOUSEFUND_COUNT" />
                </Data>
              </Cell>
              <Cell ss:StyleID="s11">
                <Data ss:Type="String">
                  <xsl:value-of select="HOUSEFUND_MONEY" />
                </Data>
              </Cell>
              <Cell ss:StyleID="s11">
                <Data ss:Type="String">
                  <xsl:value-of select="FUNDUSE_COUNT" />
                </Data>
              </Cell>
              <Cell ss:StyleID="s11">
                <Data ss:Type="String">
                  <xsl:value-of select="FUNDUSE_MONEY" />
                </Data>
              </Cell >
              <Cell ss:StyleID="s11">
                <Data ss:Type="String">
                  <xsl:value-of select="FUNDMODIFY_COUNT" />
                </Data>
              </Cell>
              <Cell ss:MergeAcross="1" ss:StyleID="s11">
                <Data ss:Type="String">
                </Data>
              </Cell>
            </Row>
          </xsl:for-each>
          <Row ss:AutoFitHeight="0">
            <Cell ss:StyleID="s11">
              <Data ss:Type="String">
                總計:
              </Data>
            </Cell>
            <Cell ss:StyleID="s11">
              <Data ss:Type="String">
              </Data>
            </Cell>
            <Cell ss:StyleID="s11">
              <Data ss:Type="String">
                <xsl:value-of select="SUM_HOUSEFUND_COUNT" />
              </Data>
            </Cell>
            <Cell ss:StyleID="s11">
              <Data ss:Type="String">
                <xsl:value-of select="SUM_HOUSEFUND_MONEY" />
              </Data>
            </Cell>
            <Cell ss:StyleID="s11">
              <Data ss:Type="String">
                <xsl:value-of select="SUM_FUNDUSE_COUNT" />
              </Data>
            </Cell>
            <Cell ss:StyleID="s11">
              <Data ss:Type="String">
                <xsl:value-of select="SUM_FUNDUSE_MONEY" />
              </Data>
            </Cell>
            <Cell ss:StyleID="s11">
              <Data ss:Type="String">
                <xsl:value-of select="SUM_FUNDMODIFY_COUNT" />
              </Data>
            </Cell>
            <Cell ss:MergeAcross="1" ss:StyleID="s11">
              <Data ss:Type="String">
              </Data>
            </Cell>
          </Row>
          <Row ss:AutoFitHeight="0">
            <Cell ss:MergeAcross="2" >
              <Data ss:Type="String">負責人:</Data>
            </Cell>
            <Cell ss:MergeAcross="2" >
              <Data ss:Type="String">復核人:</Data>
            </Cell>
            <Cell ss:MergeAcross="2" >
              <Data ss:Type="String">填表:</Data>
            </Cell>
          </Row>
        </Table>
      </Worksheet>
    </Workbook>
  </xsl:template>
</xsl:stylesheet>

  數據文件DepositStatistic.xml

XML
<?xml version="1.0" encoding="gb2312"?>
<?xml-stylesheet type='text/xsl' href=''?>
<zkSuperMap>
  <BEGINTEIM>2012/7/1</BEGINTEIM>
  <ENDTIME>2012/8/3</ENDTIME>
  <FUNDINFO>
    <DISTRICT_NAME>安順家園</DISTRICT_NAME>
    <HOUSEFUND_COUNT>22</HOUSEFUND_COUNT>
    <HOUSEFUND_MONEY>541519</HOUSEFUND_MONEY>
    <FUNDUSE_COUNT>0</FUNDUSE_COUNT>
    <FUNDUSE_MONEY>0</FUNDUSE_MONEY>
    <FUNDMODIFY_COUNT>0</FUNDMODIFY_COUNT>
  </FUNDINFO>
  <SUM_HOUSEFUND_COUNT>22</SUM_HOUSEFUND_COUNT>
  <SUM_HOUSEFUND_MONEY>541519</SUM_HOUSEFUND_MONEY>
  <SUM_FUNDUSE_COUNT>0</SUM_FUNDUSE_COUNT>
  <SUM_FUNDUSE_MONEY>0</SUM_FUNDUSE_MONEY>
  <SUM_FUNDMODIFY_COUNT>0</SUM_FUNDMODIFY_COUNT>
</zkSuperMap>

  呈現統計報表的DepositStatistic.xslt

xslt
<?xml version="1.0" encoding="gb2312" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="zkSuperMap">
    <xsl:call-template name="DepositStatistic"></xsl:call-template>
  </xsl:template>
  <xsl:template name="DepositStatistic">
    <xsl:element name="style">
      <![CDATA[
        .AcceptTable
        {
            border-collapse:collapse;
            table-layout:fixed;
        }
        .AcceptTable td
        {
            border: solid black 1px;
            font-family: 宋體;
            padding: 5px;
            vertical-align: middle;
            font-size: 10pt;
            font-weight: 600;
        }
        .AcceptTable td.AcceptTitle
        {
            text-align:center;
            font-weight: 900;
            font-size: 18pt;
            border: none;
        }
        .AcceptTable td.AcceptHeader
        {
            font-weight: 900;
            font-size:10pt;
            padding: 2px;
            border: none;
        }
        .AcceptTable tr
        {
            height:35px;
        }
        .AcceptTable td.AcceptFooter
        {
            border:none;
            vertical-align:middle;
        }
        .AcceptTable td p
        {
            margin-top:5px;
            margin-bottom:10px;
        }
        .AcceptTable td p.AcceptMater
        {
            margin-left:20px;
            margin-right:20px;
            margin-top:5px;
            margin-bottom:3px;
            border-bottom:1px dashed #dcdcdc;
            word-break: break-all;
        }
        .pageSplit{PAGE-BREAK-AFTER:always;}
        ]]>
    </xsl:element>
    <table cellSpacing="0" cellPadding="0" border="0" class="AcceptTable" align="center">
      <tr style="height:0;">
        <td style="width:80px;border:none;"></td>
        <td style="width:130px;border:none;"></td>
        <td style="width:80px;border:none;"></td>
        <td style="width:100px;border:none;"></td>
        <td style="width:80px;border:none;"></td>
        <td style="width:90px;border:none;"></td>
        <td style="width:80px;border:none;"></td>
        <td style="width:120px;border:none;"></td>
        <td style="width:80px;border:none;"></td>
      </tr>
      <tr>
        <td colspan="9" class="AcceptTitle">商品房專項維修資金繳存、使用、變更周報表</td>
      </tr>
      <tr>
        <td colspan="9" style="text-align:center;border:none;">
          <xsl:value-of select="BEGINTEIM" /><xsl:value-of select="ENDTIME" />
        </td>
      </tr>
      <tr>
        <td rowspan="2" style="text-align:center;">序號</td>
        <td rowspan="2" style="text-align:center;">小區名稱</td>
        <td colspan="2" style="text-align:center;">繳   存</td>
        <td colspan="2" style="text-align:center;">使   用</td>
        <td style="text-align:center;">變 更</td>
        <td rowspan="2" colspan="2" style="text-align:center;">備   注</td>
      </tr>
      <tr>
        <td style="text-align:center;">戶 數</td>
        <td style="text-align:center;">金 額(元)</td>
        <td style="text-align:center;">戶 數</td>
        <td style="text-align:center;">金 額(元)</td>
        <td style="text-align:center;">戶 數</td>
      </tr>
      <xsl:for-each select="FUNDINFO">
        <xsl:if test="position() mod 16=0">
          <tr style="height:0;">
            <td colspan="8" style="border:0px;">
              <div class="pageSplit"></div>
            </td>
          </tr>
        </xsl:if>
        <tr>
          <td style="text-align:center;">
            <xsl:value-of select="position()" />
          </td>
          <td style="text-align:center;" >
            <xsl:value-of select="DISTRICT_NAME" />
          </td>
          <td style="text-align:center;" >
            <xsl:value-of select="HOUSEFUND_COUNT" />
          </td>
          <td style="text-align:center;" >
            <xsl:value-of select="HOUSEFUND_MONEY" />
          </td>
          <td style="text-align:center;" >
            <xsl:value-of select="FUNDUSE_COUNT" />
          </td>
          <td style="text-align:center;" >
            <xsl:value-of select="FUNDUSE_MONEY" />
          </td>
          <td style="text-align:center;" >
            <xsl:value-of select="FUNDMODIFY_COUNT" />
          </td>
          <td style="text-align:center;" colspan="2">
            
          </td>
        </tr>
      </xsl:for-each>
      <tr>
        <td style="text-align:center;">總 計:</td>
        <td></td>
        <td style="text-align:center;">
          <xsl:value-of select="SUM_HOUSEFUND_COUNT" />
        </td>
        <td style="text-align:center;">
          <xsl:value-of select="SUM_HOUSEFUND_MONEY" />
        </td>
        <td style="text-align:center;">
          <xsl:value-of select="SUM_FUNDUSE_COUNT" />
        </td>
        <td style="text-align:center;">
          <xsl:value-of select="SUM_FUNDUSE_MONEY" />
        </td>
        <td style="text-align:center;">
          <xsl:value-of select="SUM_FUNDMODIFY_COUNT" />
        </td>
        <td style="text-align:center;" colspan="2"></td>
      </tr>
      <tr >
        <td colspan="3" style="text-align:left;border:none;">
          負責人:
          
        </td>
        <td colspan="3" style="text-align:left;border:none;">
          復核人:
         
        </td>
        <td colspan="3" style="text-align:left;border:none;">
          填表:
          
        </td>
      </tr>
    </table>
  </xsl:template>
</xsl:stylesheet>

  這里有個小竅門,一般我們設計統計報表,都是先制作完成DepositStatistic.xslt,與xml結合后的報表呈現無誤后,即可在頁面上復制報表,粘貼到Excel,再在Excel里另存為xml 電子表格格式,再打開這個文件,去掉冗余的代碼,即可得到DepositExcel.xslt.
  

導出Excel
#region ButtonExportExcel_Click
        protected void ButtonExportExcel_Click(object sender, EventArgs e)
        {
            XmlDocument _XmlDocument = new XmlDocument();
            System.Xml.Xsl.XslCompiledTransform xslt = new System.Xml.Xsl.XslCompiledTransform();

            string _BuildPath = zkSuperMap.Web.Configuration.PathSetting.TemporaryPath + "WeekStatisticXML\\";
            if (!Directory.Exists(_BuildPath))
                Directory.CreateDirectory(_BuildPath);
            _BuildPath += "WeekStatistic_" + BeginTime.Text + ".xml";
            if (File.Exists(_BuildPath))
            {
                StringWriter stringWrite = new System.IO.StringWriter();

                xslt.Load(Server.MapPath("Xsl/DepositExcel.xslt"));
                xslt.Transform(_BuildPath, null, stringWrite);
                //清除客戶端當前顯示
                HttpContext.Current.Response.Clear();
                HttpContext.Current.Response.Buffer = true;
                HttpContext.Current.Response.Charset = "gb2312";
                HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}.xls", HttpUtility.UrlEncode(BeginTime.Date.ToShortDateString(), System.Text.Encoding.UTF8)));
                HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
                HttpContext.Current.Response.ContentType = "application/ms-excel";//設置輸出文件類型為excel文件。

                HttpContext.Current.Response.Write(stringWrite.ToString());

                HttpContext.Current.Response.End();
                HttpContext.Current.Response.Close();
                stringWrite.Close();
            }
        }
        #endregion

  最后呈現出來的報表:
     


  基於xml+xslt的導出Excel解決方案,整合了JS跟office組件等解決方案的優點,實乃一大殺器,哈哈^_^


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM