一键导出Word和Excel文件的简单服务器控件

http://blog.joycode.com/mmkk/archive/2004/09/21/34105.aspx

出于项目的需求,写了这样一个控件,使用起来很简单,只需要3句代码:

    exportExcel.FileType = TSCRMLiteWeb.SC.ExportFileType.Excel;
    exportExcel.ExportFileName = "currencyList";
    exportExcel.TargetControlID = "currencyContianer.gridCurrencyList";

需要说明的只有几点:

1.由于项目中所有需要导出内容的控件都是DataGrid,因此只针对对此控件的测试,满足需求先,其它就没有测试过了:)

2.属性ExportFileName不要扩展名,FileType属性指定以后,控件自身就会得到对应的扩展名了

3.最关键的地方就是TargetControlID,这是需要导出内容的服务器控件的“路径“,通常是DataGrid的ID值,如果你的DataGrid就直接在Page下面,那么TargetControlID的值就直接设为DataGrid的ID,如果DataGrid父亲控件不是Page,那么一直追朔到Page下的一级控件,比如上面的例子,currencyContainer就是一个Page下面的控件,gridCurrencyList的父亲控件是currencyContainer,他们之间用点号分开,看过代码后你就会知道是为什么了,就这些。这里是所有的代码: 

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace TSCRMLiteWeb.SC
{
 /// <summary>
 /// 导出Excel,Word等Office文件的LinkButton服务器控件
 /// </summary>
 public class ExportButton : LinkButton
 {
  public ExportButton()
  {
   //
   // TODO: 在此处添加构造函数逻辑
   //
  }
 
  protected override void OnClick(EventArgs e)
  {
   ExportButton_Click();
  }
  /// <summary>
  /// 扩展名,在设置导出文件类型的时候同时设置
  /// </summary>
  private string ExtensionType
  {
   get
   {
    if(ViewState["ExtensionType"] == null)
     return ".xls";
    return (string)ViewState["ExtensionType"];
   }
   set
   {
    ViewState["ExtensionType"] = value;
   }
  }
 
  /// <summary>
  /// 要导出内容的目标控件ID,如果目标控件的父亲控件不是Page,那么应该从Page下的该控件的根控件开始传入,格式是ParentControlID.ControlID.ControlID...
  /// </summary>
  public string TargetControlID
  {
   get
   {
    if(ViewState["TargetControlID"] == null)
     return String.Empty;
    return (string)ViewState["TargetControlID"];
   }
   set
   {
    ViewState["TargetControlID"] = value;
   }
  }
  /// <summary>
  /// 文件类型
  /// </summary>
  public ExportFileType FileType
  {
   get
   {
    if(ViewState["ExportFileType"] == null)
     return ExportFileType.Excel;
    return (ExportFileType)ViewState["ExportFileType"];
   }
   set
   {
    ViewState["ExportFileType"] = value;
    switch(value)
    {
     case ExportFileType.Excel:
      this.ExtensionType = ".xls";
      break;
     case ExportFileType.Word:
      this.ExtensionType = ".doc";
      break;
     default:
      this.ExtensionType = ".xls";
      break;
    }
   }
  }
  /// <summary>
  /// 导出的文件名
  /// </summary>
  public string ExportFileName
  {
   get
   {
    if(ViewState["ExportFileName"] == null)
     return "ExportFile";
    return (string)ViewState["ExportFileName"];
   }
   set
   {
    ViewState["ExportFileName"] = value;
   }
  }
  protected override void Render(HtmlTextWriter writer)
  {
   if(Page != null)
   {
    Page.VerifyRenderingInServerForm(this);
   }
   this.CausesValidation = false;
   base.Render (writer);
  }

  private void ExportButton_Click()
  {
   //确保找到控件
   Control c = AnalyseControlID();
   if(c == null)
    return;
   HttpResponse response = HttpContext.Current.Response;
   response.Clear();
   response.Buffer= true;
   response.ContentType = SetContentType();
   response.AddHeader("Content-Disposition", "attachment; filename=" + ExportFileName + ExtensionType + "");
   response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312");
   response.Charset = "gb2312";
   EnableViewState = false;
   System.IO.StringWriter oStringWriter = new System.IO.StringWriter();
   System.Web.UI.HtmlTextWriter oHtmlTextWriter = new System.Web.UI.HtmlTextWriter(oStringWriter);
   ClearControls(c);
   c.RenderControl(oHtmlTextWriter);
   response.Write(oStringWriter.ToString());
   response.End();
   //ClearControls(c);
  }
  private string SetContentType()
  {
   string contentType = String.Empty;
   switch(FileType)
   {
    case ExportFileType.Excel:
     contentType = "application/vnd.ms-excel";
     break;
    case ExportFileType.Word:
     contentType = "application/vnd.ms-word";
     break;
   }
   return contentType;
  }
  private Control AnalyseControlID()
  {
   if(Page != null)
   {
    string[] controlIDArray = TargetControlID.Split('.');
    Control c = Page.FindControl(controlIDArray[0]);
//    HttpContext.Current.Response.Write(controlIDArray.Length);
    for(int i = 1;i < controlIDArray.Length;i++)
    {
     HttpContext.Current.Response.Write(controlIDArray[i]);
     c = c.FindControl(controlIDArray[i]);
    }
   
    return c;
   }
   return null;
  }
  /// <summary>
  /// 清除可能产生回发的子控件变成文本控件,如果不这样做的话,调用RenderControl会产生错误
  /// Reference:http://www.c-sharpcorner.com/Code/2003/Sept/ExportASPNetDataGridToExcel.asp
  /// </summary>
  /// <param name="control"></param>
  private void ClearControls(Control control)
  {
   for (int i=control.Controls.Count -1; i>=0; i--)
   {
    ClearControls(control.Controls[i]);
   }
   if(control is TableCell)
   {
    for(int j = 0 ;j < control.Controls.Count;j++)
    {
     if(! (control.Controls[j] is Label || control.Controls[j] is LiteralControl))
     {
      Control c = control.Controls[j];
      if(c.GetType().GetProperty("Text") != null)
      {
       LiteralControl literal = new LiteralControl();
       literal.Text = c.GetType().GetProperty("Text").GetValue(c,null).ToString();
       control.Controls.Add(literal);
      }
      control.Controls.Remove(c);
     }
    }
   }
   return;
  }
 }
 /// <summary>
 /// 导出的文件类型
 /// </summary>
 public enum ExportFileType
 {
  Word = 1,
  Excel = 2
 }
}

ps:更新了一下代码,另外如果DataGrid中包含类似LinkButton这样的控件,绑定值的时候应该使用

 &amp;lt;asp:LinkButton Text='&amp;quot;&amp;lt;%#DataBinder.Eval(Container,&amp;amp;#8220;columnName&amp;amp;#8220;)%&amp;gt;&amp;quot;'&amp;gt;&amp;lt;/asp:LinkButton&amp;gt;

,而不要使用

 &amp;lt;asp:LinkButton&amp;gt;&amp;lt;%#DataBinder.Eval(Container,&amp;amp;#8220;columnName&amp;amp;#8220;)%&amp;gt;&amp;lt;/asp:LinkButton&amp;gt;

这样的形式,因为这样Text将不会被倒入Excel中

* The warnings 'unsafe code', 'unsafe type' and 'unsafe typecast' should be ignored. In Delphi 7, 2005, 2006, Turbo Delphi and 2007 these warnings can be disabled in your project options. -------------------------------------------------------------------------------- Version 1.0 (February 2000) Version 1.2 - Improved connection to Excel Version 1.3 - Added Orientation of titles - Added StyleColumnWidth Version 1.4 - Improved GetColumnCharacters - Added Border properties and background colors for Titles, Data and Summary - Added Summary properties (SummarySelection, SummaryFields, SummaryCalculation) Version 1.5 - Improved speed of exporting data - Improved exporting string-fields - Added ConnectTo property Version 1.6 - Suppression of reference to Dataset.RecordCount (thanks to G閞ard Beneteau) - Added VisibleFieldsOnly property Version 1.7 - Notification when disconnecting dataset - Very fast export by using a variant matrix (thanks to Frank van den Bergh) Version 1.8 - Bug in exporting titles (thanks to Roberto Parola) - Setting format of cells before exporting data (thanks to Asbj鴕n Heggvik) - Added BlockOfRecords property : little bit faster and more control of memory - Added properties to set begin row of titles and data Version 1.9 - Added properties (Orientation, WrapText, Alignment) to font (thanks to David Balick) (property OrientationTitles is removed) - Added HeaderText (thanks to David Balick) - Improved some routines Version 2.0 - Added read only property with row number of last data row - Added property with the Excel tabsheet so after the export it is possible to access the cells in Excel - Added event OnExportRecords Version 2.1 - Bugfixes Version 2.2 - Bugfix when exporting filtered dataset (thanks to Heinz Faerber) - New column width styles : cwFieldDisplayWidth, cwFieldDataSize, cwEnhAutoFit (idea from Scott Stanek) Version 2.3 - Added properties begin column data/titles and header (idea from Knjazev Sergey) - Added property ShowTitles Version 2.4 - Support for Delphi 6.0 Version 2.5 - D6 : problem when using disconnect Version 2.6 - Bugfixes and some improvements - Added method LoadDefaultProperties to reset all properties - Improvement SetFormat (thanks to Enrico Chiaramonte) - Improvements using borders (thanks to Ot醰io) - Added event OnGetCellBackgroundColorEvent (thanks to Yuri Plotnikov) - Added events to export data without using a TDataset and new property DataPipe : dpDataset, dpCustom (thanks to David Balick) - Event OnExportRecords will be triggered after exporting the record Version 2.7 - Some bugfixes - Added new unit scExcelExportReg which contains a component editor - Added exceptions to prevent access violations (EFileNotExists, ENoDatasetConnected, EDatasetNotActive, ENoActiveWorkbook) - Added new property Filename which can be used to add data to existing file - Add data to existing worksheet when name of given worksheet already exists - Added new feature to group rows (thanks to Vadim Mescheryakov & Stijn Vansummeren) - Added new group options properties : ClearContents, BorderRange, IntervalFontSize - New events for exporting without dataset : OnGotoFirstRecord, OnGotoNextRecord Version 2.81 - Created a package for Delphi5 and Delphi6 to make installation easier - Added new public method Connect. Can be used to make a connection to Excel before exporting data. When exporting more datasets at the same time, the Disconnect method should be used after using the ExportDataset method ! - Added new read only property Connected. - Text property of field in stead of Value property is exported so OnGetText events can be used Version 2.91 - Improvements SetFormat (before exporting data) - Added support for fieldtype ftTimeStamp - Added fieldtype ftMemo, ftOraClob, ftFmtMemo, these kinds of fields are exported using AsVariant not the Text property like other fields - Improvement for regional settings of floats (thanks to Jorge Pinetta) - Improvement ShowTitles and BeginRowData properties (thanks to Jordi March i Nogu? - Added FooterText properties - Small changes for Delphi 7.0 Version 3.0 - Bugfix for Delphi 5 (added extra compiler directives) - Improvements constants of Borders, Colors, ... - Use OnGetText event for memo field when it is assigned, otherwise export contents of memo - Improvement exporting string data when DataPipe = dpCustom - New demonstration program Version 3.1 - Bugfix for displayformat (InitFormatNumbers was disabled) - Improvements for exporting currency fields (a kind of curency displayformat is created so that the result in Excel looks the same as in your Delphi program) - Improvement for setting displayformat for cells. This has to be done before exporting. In previous version this was done from row 1 to 9999. When exporting more records they had no displayformat. Now displayformat for each block of rows is set. This will also increase the file size ! - Added resource strings for the exceptions. Now these error messages can be translated. - Added scAVG (average) as new TSummaryCalculation type Version 3.11 - Added support for displayformat of datetime fields Version 3.12 - Bugfix displayformat of time field Version 3.2 (May 2004) - Bugfix displayformat with thousand seperators - Bugfix date time fields with Excel 2003 (internal American datetime format should be used) - Tested with MS Excel 2003 Version 3.3 (February 2005) - Bugfixes : ExcelVersion, Excel 2003, ... - Created 2 packages, a run-time (ExcelExportPack) and a design-time (dclExcelExportPack) - Added package for Delphi (BDS) 2005 - Added new OnCellStyle event which can be used to change the background color and font color, size, name and bold style of a cell - Added new OnFieldCellStyle event which can be used to change the background color and font color, size, name and bold style of a cell when datapipe is set to dpCustom - Added ftBCD and ftFMTBCD datatype in IsValueField function - Added ftFMTBCD datatype to CanConvertFieldToCell function Version 3.31 (February 2005) - Empty datetime fields are exported as '' instead of 31/12/1899 (thanks to Peter Hannah) Version 3.4 (April 2006) - Bugfix Memo fields, maximum length 910 (thanks to Douglas Neckers) - Bugfix set font and style when there are more then 26 columns (thanks to Horst Borscht) - Made properties ExcelApplication and ExcelWorkbook public - Added IsExcelAppActive function - Added ENotSupported exception - Added Quit option for Disconnect method - Added support for ExcelXP type library - Added FileFormat XML (XML spreadsheet, only with ExcelXP type library) - Added scExcelExportConfig.inc unit with compiler directives for choosing Excel type library (97, 2000, XP) - Added package and package group for Delphi (BDS) 2006 Version 3.41 (May 2006) - Bugfix compiler directives in Delphi 5 - Added SummaryDisplayFormat property Version 3.42 (June 2006) - Bugfix BeginRowHeader - Added PropertyGroups parameter to LoadDefaultProperties Now a set of property groups can be given : pgFont, pgPositions, pgSummary, pgGroup, pgText, pgOther - Improvement WorkSheetName. By setting the WorkSheetName property an existing or new worksheet can be focused after the export. Version 3.5 (September 2006) - Bugfix setting column width - Added properties for merging of header and footer cells (MergeHeaderCells, MergeFooterCells) - Added AutoFilter property for titles of dataset - Added support for Excel 2007 (b鑤a) - Added ffXLSX for saving files in Excel 2007 Open XML format - Added support for OnGetText event for numeric fields - Added public property for LCID so it can be used after exporting - Using default font and size of Excel by setting Size = -1 and Font.Name = 'MS Sans Serif' -> Excel97/2003 : Arial size 10, Excel 2007 : Calibri size 11 - Tested with Turbo Delphi Explorer (Win32) Version 3.51 (October 2006) - Added readonly TypeLibrary property Version 3.6 (June 2007) - Added support for Delphi 2007 - Retested support for Excel 2007 - Tested with Windows Vista - Started with converting comments to XML documentation - Added public method FindFirstEmptyRow
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值