C#讀取Excel 幾種方法的體會


(1) OleDb: 用這種方法讀取Excel速度還是非常的快的,但這種方式讀取數據的時候不太靈活,不過可以在 DataTable 中對數據進行一些刪減修改

這種方式將Excel作為一個數據源,直接用Sql語句獲取數據了。所以讀取之前要知道此次要讀取的Sheet(當然也可以用序號,類似dt.Row[0][0]。這樣倒是不需要知道Sheet)

if  (fileType == ".xls" )
    connStr = "Provider=Microsoft.Jet.OLEDB.4.0;"  + "Data Source="  + fileName + ";"  + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1\"" ;
else
    connStr = "Provider=Microsoft.ACE.OLEDB.12.0;"  + "Data Source="  + fileName + ";"  + ";Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"" ;
 
OleDbConnection conn new  OleDbConnection(connStr);
DataTable dtSheetName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new  object [] { null , null , null , "TABLE"  });

以上是讀取Excel的Sheet名,xls和xlsx的連接字符串也不一樣的,可以根據文件的后綴來區別。這里需要注意的一點,Excel里面只有一個Sheet,但通過這種方式讀取Sheet可能會大於一個。原因已經有人在別的網站說過了,偷一下懶O(∩_∩)O,下面文段來自【cdwolfling

【在使用過程中發現取出的Sheet和實際excel不一致, 會多出不少。目前總結后有兩種情況:

1. 取出的名稱中,包括了XL命名管理器中的名稱(參見XL2007的公式--命名管理器, 快捷鍵Crtl+F3);

2. 取出的名稱中,包括了FilterDatabase后綴的, 這是XL用來記錄Filter范圍的, 參見http://www.mrexcel.com/forum/showthread.php?t=27225

對於第一點比較簡單, 刪除已有命名管理器中的內容即可;第二點處理起來比較麻煩, Filter刪除后這些名稱依然保留着,簡單的做法是新增sheet然后將原sheet Copy進去】

---------------------------------

但實際情況並不能為每個Excel做以上檢查,【cdwolfling】也給出了過濾的方案,當時還是有點問題,本來補充了一點。總之先看代碼吧

for (int i = 0; i < dtSheetName.Rows.Count; i++)

{

SheetName = ( string )dtSheetName.Rows[i][ "TABLE_NAME" ];
 
if  (SheetName .Contains( "$" ) && !SheetName .Replace( "'" , "" ).EndsWith( "$" )) continue ; //過濾無效SheetName完畢....

da.SelectCommand = new OleDbCommand(String.Format(sql_F, tblName), conn);
DataSet dsItem = new DataSet();
da.Fill(dsItem, tblName);

}

因為讀取出來無效SheetName一般情況最后一個字符都不會是$。如果SheetName有一些特殊符號,讀取出來的SheetName會自動加上單引號,比如在Excel中將SheetName編輯成:MySheet(1),此時讀取出來的SheetName就為:'MySheet(1)$',所以判斷最后一個字符是不是$之前最好過濾一下單引號。

優點:讀取方式簡單、讀取速度快

缺點:除了讀取過程不太靈活之外,這種讀取方式還有個弊端就是,當Excel數據量很大時。會非常占用內存,當內存不夠時會拋出內存溢出的異常。

不過一般情況下還是非常不錯的

 讀取Excel完整代碼:

/// <summary>
         /// 讀取Excel文件到DataSet中
         /// </summary>
         /// <param name="filePath">文件路徑</param>
         /// <returns></returns>
         public  static  DataSet ToDataTable( string  filePath)
         {
             string  connStr = "" ;           
             string  fileType = System.IO.Path.GetExtension(fileName);
             if  ( string .IsNullOrEmpty(fileType)) return  null ;
 
             if  (fileType == ".xls" )
                 connStr = "Provider=Microsoft.Jet.OLEDB.4.0;"  + "Data Source="  + filePath+ ";"  + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1\"" ;
             else
                 connStr = "Provider=Microsoft.ACE.OLEDB.12.0;"  + "Data Source="  + filePath+ ";"  + ";Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1\"" ;
             string  sql_F = "Select * FROM [{0}]" ;
 
             OleDbConnection conn = null ;
             OleDbDataAdapter da = null ;
             DataTable dtSheetName= null ;
 
             DataSet ds = new  DataSet();
             try
             {
                 // 初始化連接,並打開
                 conn = new  OleDbConnection(connStr);
                 conn.Open();
 
                 // 獲取數據源的表定義元數據                       
                 string  SheetName = "" ;
                 dtSheetName= conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new  object [] { null , null , null , "TABLE"  });
 
                 // 初始化適配器
                 da = new  OleDbDataAdapter();
                 for  ( int  i = 0; i < dtSheetName.Rows.Count; i++)
                 {
                     SheetName = ( string )dtSheetName.Rows[i][ "TABLE_NAME" ];
 
                     if  (SheetName .Contains( "$" ) && !SheetName .Replace( "'" , "" ).EndsWith( "$" ))
                     {
                         continue ;
                     }
 
                     da.SelectCommand = new  OleDbCommand(String.Format(sql_F, SheetName ), conn);
                     DataSet dsItem = new  DataSet();
                     da.Fill(dsItem, tblName);
 
                     ds.Tables.Add(dsItem.Tables[0].Copy());
                 }
             }
             catch  (Exception ex)
             {
             }
             finally
             {
                 // 關閉連接
                 if  (conn.State == ConnectionState.Open)
                 {
                     conn.Close();
                     da.Dispose();
                     conn.Dispose();
                 }
             }
             return  ds;
         }

  

(2):Com組件的方式讀取Excel

這種方式需要先引用 Microsoft.Office.Interop.Excel 。首選說下這種方式的優缺點

優點:可以非常靈活的讀取Excel中的數據

缺點:如果是Web站點部署在IIS上時,還需要服務器機子已安裝了Excel,有時候還需要為配置IIS權限。最重要的一點因為是基於單元格方式讀取的,所以數據很慢(曾做過試驗,直接讀取千行、200多列的文件,直接讀取耗時15分鍾。即使采用多線程分段讀取來提高CPU的利用率也需要8分鍾。PS:CPU I3)

需要讀取大文件的的童鞋們慎重。。。

附上單線程和多線程讀取類:

public  class  ExcelOptions
     {
         private  Stopwatch wath = new  Stopwatch();
 
         /// <summary>
         /// 使用COM讀取Excel
         /// </summary>
         /// <param name="excelFilePath">路徑</param>
         /// <returns>DataTabel</returns>
         public  System.Data.DataTable GetExcelData( string  excelFilePath)
         {
             Excel.Application app = new  Excel.Application();
             Excel.Sheets sheets;
             Excel.Workbook workbook = null ;
             object  oMissiong = System.Reflection.Missing.Value;
             System.Data.DataTable dt = new  System.Data.DataTable();
 
             wath.Start();
 
             try
             {
                 if  (app == null )
                 {
                     return  null ;
                 }
 
                 workbook = app.Workbooks.Open(excelFilePath, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong);
 
                 //將數據讀入到DataTable中——Start  
 
                 sheets = workbook.Worksheets;
                 Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1); //讀取第一張表
                 if  (worksheet == null )
                     return  null ;
 
                 string  cellContent;
                 int  iRowCount = worksheet.UsedRange.Rows.Count;
                 int  iColCount = worksheet.UsedRange.Columns.Count;
                 Excel.Range range;
 
                 //負責列頭Start
                 DataColumn dc;
                 int  ColumnID = 1;
                 range = (Excel.Range)worksheet.Cells[1, 1];
                 while  (range.Text.ToString().Trim() != "" )
                 {
                     dc = new  DataColumn();
                     dc.DataType = System.Type.GetType( "System.String" );
                     dc.ColumnName = range.Text.ToString().Trim();
                     dt.Columns.Add(dc);
 
                     range = (Excel.Range)worksheet.Cells[1, ++ColumnID];
                 }
                 //End
 
                 for  ( int  iRow = 2; iRow <= iRowCount; iRow++)
                 {
                     DataRow dr = dt.NewRow();
 
                     for  ( int  iCol = 1; iCol <= iColCount; iCol++)
                     {
                         range = (Excel.Range)worksheet.Cells[iRow, iCol];
 
                         cellContent = (range.Value2 == null ) ? ""  : range.Text.ToString();
 
                         //if (iRow == 1)
                         //{
                         //    dt.Columns.Add(cellContent);
                         //}
                         //else
                         //{
                             dr[iCol - 1] = cellContent;
                         //}
                     }
 
                     //if (iRow != 1)
                     dt.Rows.Add(dr);
                 }
 
                 wath.Stop();
                 TimeSpan ts = wath.Elapsed;
 
                 //將數據讀入到DataTable中——End
                 return  dt;
             }
             catch
             {
                 
                 return  null ;
             }
             finally
             {
                 workbook.Close( false , oMissiong, oMissiong);
                 System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
                 workbook = null ;
                 app.Workbooks.Close();
                 app.Quit();
                 System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
                 app = null ;
                 GC.Collect();
                 GC.WaitForPendingFinalizers();
             }
         }
 
 
         /// <summary>
         /// 使用COM,多線程讀取Excel(1 主線程、4 副線程)
         /// </summary>
         /// <param name="excelFilePath">路徑</param>
         /// <returns>DataTabel</returns>
         public  System.Data.DataTable ThreadReadExcel( string  excelFilePath)
         {
             Excel.Application app = new  Excel.Application();
             Excel.Sheets sheets = null ;
             Excel.Workbook workbook = null ;
             object  oMissiong = System.Reflection.Missing.Value;
             System.Data.DataTable dt = new  System.Data.DataTable();
 
             wath.Start();
 
             try
             {
                 if  (app == null )
                 {
                     return  null ;
                 }
 
                 workbook = app.Workbooks.Open(excelFilePath, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong);
 
                 //將數據讀入到DataTable中——Start  
                 sheets = workbook.Worksheets;
                 Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1); //讀取第一張表
                 if  (worksheet == null )
                     return  null ;
 
                 string  cellContent;
                 int  iRowCount = worksheet.UsedRange.Rows.Count;
                 int  iColCount = worksheet.UsedRange.Columns.Count;
                 Excel.Range range;
 
                 //負責列頭Start
                 DataColumn dc;
                 int  ColumnID = 1;
                 range = (Excel.Range)worksheet.Cells[1, 1];
                 //while (range.Text.ToString().Trim() != "")
                 while  (iColCount >= ColumnID)
                 {
                     dc = new  DataColumn();
                     dc.DataType = System.Type.GetType( "System.String" );
 
                     string  strNewColumnName = range.Text.ToString().Trim();
                     if  (strNewColumnName.Length == 0) strNewColumnName = "_1" ;
                     //判斷列名是否重復
                     for  ( int  i = 1; i < ColumnID; i++)
                     {
                         if  (dt.Columns[i - 1].ColumnName == strNewColumnName)
                             strNewColumnName = strNewColumnName + "_1" ;
                     }
 
                     dc.ColumnName = strNewColumnName;
                     dt.Columns.Add(dc);
 
                     range = (Excel.Range)worksheet.Cells[1, ++ColumnID];
                 }
                 //End
 
                 //數據大於500條,使用多進程進行讀取數據
                 if  (iRowCount - 1 > 500)
                 {
                     //開始多線程讀取數據
                     //新建線程
                     int  b2 = (iRowCount - 1) / 10;
                     DataTable dt1 = new  DataTable( "dt1" );
                     dt1 = dt.Clone();
                     SheetOptions sheet1thread = new  SheetOptions(worksheet, iColCount, 2, b2 + 1, dt1);
                     Thread othread1 = new  Thread( new  ThreadStart(sheet1thread.SheetToDataTable));
                     othread1.Start();
 
                     //阻塞 1 毫秒,保證第一個讀取 dt1
                     Thread.Sleep(1);
 
                     DataTable dt2 = new  DataTable( "dt2" );
                     dt2 = dt.Clone();
                     SheetOptions sheet2thread = new  SheetOptions(worksheet, iColCount, b2 + 2, b2 * 2 + 1, dt2);
                     Thread othread2 = new  Thread( new  ThreadStart(sheet2thread.SheetToDataTable));
                     othread2.Start();
 
                     DataTable dt3 = new  DataTable( "dt3" );
                     dt3 = dt.Clone();
                     SheetOptions sheet3thread = new  SheetOptions(worksheet, iColCount, b2 * 2 + 2, b2 * 3 + 1, dt3);
                     Thread othread3 = new  Thread( new  ThreadStart(sheet3thread.SheetToDataTable));
                     othread3.Start();
 
                     DataTable dt4 = new  DataTable( "dt4" );
                     dt4 = dt.Clone();
                     SheetOptions sheet4thread = new  SheetOptions(worksheet, iColCount, b2 * 3 + 2, b2 * 4 + 1, dt4);
                     Thread othread4 = new  Thread( new  ThreadStart(sheet4thread.SheetToDataTable));
                     othread4.Start();
 
                     //主線程讀取剩余數據
                     for  ( int  iRow = b2 * 4 + 2; iRow <= iRowCount; iRow++)
                     {
                         DataRow dr = dt.NewRow();
                         for  ( int  iCol = 1; iCol <= iColCount; iCol++)
                         {
                             range = (Excel.Range)worksheet.Cells[iRow, iCol];
                             cellContent = (range.Value2 == null ) ? ""  : range.Text.ToString();
                             dr[iCol - 1] = cellContent;
                         }
                         dt.Rows.Add(dr);
                     }
 
                     othread1.Join();
                     othread2.Join();
                     othread3.Join();
                     othread4.Join();
 
                     //將多個線程讀取出來的數據追加至 dt1 后面
                     foreach  (DataRow dr in  dt.Rows)
                         dt1.Rows.Add(dr.ItemArray);
                     dt.Clear();
                     dt.Dispose();
 
                     foreach  (DataRow dr in  dt2.Rows)
                         dt1.Rows.Add(dr.ItemArray);
                     dt2.Clear();
                     dt2.Dispose();
 
                     foreach  (DataRow dr in  dt3.Rows)
                         dt1.Rows.Add(dr.ItemArray);
                     dt3.Clear();
                     dt3.Dispose();
 
                     foreach  (DataRow dr in  dt4.Rows)
                         dt1.Rows.Add(dr.ItemArray);
                     dt4.Clear();
                     dt4.Dispose();
 
                     return  dt1;
                 }
                 else
                 {
                     for  ( int  iRow = 2; iRow <= iRowCount; iRow++)
                     {
                         DataRow dr = dt.NewRow();
                         for  ( int  iCol = 1; iCol <= iColCount; iCol++)
                         {
                             range = (Excel.Range)worksheet.Cells[iRow, iCol];
                             cellContent = (range.Value2 == null ) ? ""  : range.Text.ToString();
                             dr[iCol - 1] = cellContent;
                         }
                         dt.Rows.Add(dr);
                     }
                 }
 
                 wath.Stop();
                 TimeSpan ts = wath.Elapsed;
                 //將數據讀入到DataTable中——End
                 return  dt;
             }
             catch
             {
 
                 return  null ;
             }
             finally
             {
                 workbook.Close( false , oMissiong, oMissiong);
                 System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
                 System.Runtime.InteropServices.Marshal.ReleaseComObject(sheets);
                 workbook = null ;
                 app.Workbooks.Close();
                 app.Quit();
                 System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
                 app = null ;
                 GC.Collect();
                 GC.WaitForPendingFinalizers();
                 
                 /*
                 object objmissing = System.Reflection.Missing.Value;
 
Excel.ApplicationClass application = new ApplicationClass();
Excel.Workbook book = application.Workbooks.Add(objmissing);
Excel.Worksheet sheet = (Excel.Worksheet)book.Worksheets.Add(objmissing,objmissing,objmissing,objmissing);
 
//操作過程 ^&%&×&……&%&&……
 
//釋放
sheet.SaveAs(path,objmissing,objmissing,objmissing,objmissing,objmissing,objmissing,objmissing,objmissing);
System.Runtime.InteropServices.Marshal.ReleaseComObject((object)sheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject((object)book);
application.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject((object)application);
System.GC.Collect();
                  */
             }
         }
 
 
         /// <summary>
         /// 刪除Excel行
         /// </summary>
         /// <param name="excelFilePath">Excel路徑</param>
         /// <param name="rowStart">開始行</param>
         /// <param name="rowEnd">結束行</param>
         /// <param name="designationRow">指定行</param>
         /// <returns></returns>
         public  string  DeleteRows( string  excelFilePath, int  rowStart, int  rowEnd, int  designationRow)
         {
             string  result = "" ;
             Excel.Application app = new  Excel.Application();
             Excel.Sheets sheets;
             Excel.Workbook workbook = null ;
             object  oMissiong = System.Reflection.Missing.Value;
             try
             {
                 if  (app == null )
                 {
                     return  "分段讀取Excel失敗" ;
                 }
 
                 workbook = app.Workbooks.Open(excelFilePath, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong);
                 sheets = workbook.Worksheets;
                 Excel.Worksheet worksheet = (Excel.Worksheet)sheets.get_Item(1); //讀取第一張表
                 if  (worksheet == null )
                     return  result;
                 Excel.Range range;
 
                 //先刪除指定行,一般為列描述
                 if  (designationRow != -1)
                 {
                     range = (Excel.Range)worksheet.Rows[designationRow, oMissiong];
                     range.Delete(Excel.XlDeleteShiftDirection.xlShiftUp);
                 }
                 Stopwatch sw = new  Stopwatch();
                 sw.Start();
 
                 int  i = rowStart;
                 for  ( int  iRow = rowStart; iRow <= rowEnd; iRow++, i++)
                 {
                     range = (Excel.Range)worksheet.Rows[rowStart, oMissiong];
                     range.Delete(Excel.XlDeleteShiftDirection.xlShiftUp);
                 }
 
                 sw.Stop();
                 TimeSpan ts = sw.Elapsed;
                 workbook.Save();
 
                 //將數據讀入到DataTable中——End
                 return  result;
             }
             catch
             {
 
                 return  "分段讀取Excel失敗" ;
             }
             finally
             {
                 workbook.Close( false , oMissiong, oMissiong);
                 System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
                 workbook = null ;
                 app.Workbooks.Close();
                 app.Quit();
                 System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
                 app = null ;
                 GC.Collect();
                 GC.WaitForPendingFinalizers();
             }
         }
 
         public  void  ToExcelSheet(DataSet ds, string  fileName)
         {
             Excel.Application appExcel = new  Excel.Application();
             Excel.Workbook workbookData = null ;
             Excel.Worksheet worksheetData;
             Excel.Range range;
             try
             {
                 workbookData = appExcel.Workbooks.Add(System.Reflection.Missing.Value);
                 appExcel.DisplayAlerts = false ; //不顯示警告
                 //xlApp.Visible = true;//excel是否可見
                 //
                 //for (int i = workbookData.Worksheets.Count; i > 0; i--)
                 //{
                 //    Microsoft.Office.Interop.Excel.Worksheet oWorksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbookData.Worksheets.get_Item(i);
                 //    oWorksheet.Select();
                 //    oWorksheet.Delete();
                 //}
 
                 for  ( int  k = 0; k < ds.Tables.Count; k++)
                 {
                     worksheetData = (Excel.Worksheet)workbookData.Worksheets.Add(System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value);
                     // testnum--;
                     if  (ds.Tables[k] != null )
                     {
                         worksheetData.Name = ds.Tables[k].TableName;
                         //寫入標題
                         for  ( int  i = 0; i < ds.Tables[k].Columns.Count; i++)
                         {
                             worksheetData.Cells[1, i + 1] = ds.Tables[k].Columns[i].ColumnName;
                             range = (Excel.Range)worksheetData.Cells[1, i + 1];
                             //range.Interior.ColorIndex = 15;
                             range.Font.Bold = true ;
                             range.NumberFormatLocal = "@" ; //文本格式
                             range.EntireColumn.AutoFit(); //自動調整列寬
                             // range.WrapText = true; //文本自動換行  
                             range.ColumnWidth = 15;
                         }
                         //寫入數值
                         for  ( int  r = 0; r < ds.Tables[k].Rows.Count; r++)
                         {
                             for  ( int  i = 0; i < ds.Tables[k].Columns.Count; i++)
                             {
                                 worksheetData.Cells[r + 2, i + 1] = ds.Tables[k].Rows[r][i];
                                 //Range myrange = worksheetData.get_Range(worksheetData.Cells[r + 2, i + 1], worksheetData.Cells[r + 3, i + 2]);
                                 //myrange.NumberFormatLocal = "@";//文本格式
                                 //// myrange.EntireColumn.AutoFit();//自動調整列寬
                                 ////   myrange.WrapText = true; //文本自動換行  
                                 //myrange.ColumnWidth = 15;
                             }
                             //  rowRead++;
                             //System.Windows.Forms.Application.DoEvents();
                         }
                     }
                     worksheetData.Columns.EntireColumn.AutoFit();
                     workbookData.Saved = true ;
                 }
             }
             catch  (Exception ex) { }
             finally
             {
                 workbookData.SaveCopyAs(fileName);
                 workbookData.Close( false , System.Reflection.Missing.Value, System.Reflection.Missing.Value);
                 appExcel.Quit();
                 GC.Collect();
             }
         }
     
     }

  

(3)NPOI方式讀取Excel,NPOI是一組開源的組件,類似Java的 POI。包括:NPOI、NPOI.HPSF、NPOI.HSSF、NPOI.HSSF.UserModel、NPOI.POIFS、NPOI.Util,下載的時候別只下一個噢

 

優點:讀取Excel速度較快,讀取方式操作靈活性

缺點:只支持03的Excel,xlsx的無法讀取。由於這點,使用這種方式的人不多啊,沒理由要求客戶使用03版Excel吧,再說03版Excel對於行數還有限制,只支持65536行。

(聽他們的開發人員說會在2012年底推出新版,支持xlsx的讀取。但一直很忙沒時間去關注這個事情,有興趣的同學可以瞧瞧去)

NPOI讀取Excel類:

using  System;
using  System.Data;
using  System.IO;
using  System.Web;
using  NPOI;
using  NPOI.HPSF;
using  NPOI.HSSF;
using  NPOI.HSSF.UserModel;
using  NPOI.POIFS;
using  NPOI.Util;
using  System.Text;
using  System.Configuration;
 
public  class  NPOIHelper
{
     private  static  int  ExcelMaxRow = Convert.ToInt32(ConfigurationManager.AppSettings[ "ExcelMaxRow" ]);
     /// <summary>
     /// 由DataSet導出Excel
     /// </summary>
     /// <param name="sourceTable">要導出數據的DataTable</param>   
     /// <param name="sheetName">工作表名稱</param>
     /// <returns>Excel工作表</returns>   
     private  static  Stream ExportDataSetToExcel(DataSet sourceDs)
     {
         HSSFWorkbook workbook = new  HSSFWorkbook();
         MemoryStream ms = new  MemoryStream();
 
         for  ( int  i = 0; i < sourceDs.Tables.Count; i++)
         {
             HSSFSheet sheet = (HSSFSheet)workbook.CreateSheet(sourceDs.Tables[i].TableName);
             HSSFRow headerRow = (HSSFRow)sheet.CreateRow(0);
             // handling header.           
             foreach  (DataColumn column in  sourceDs.Tables[i].Columns)
                 headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
             // handling value.           
             int  rowIndex = 1;
             foreach  (DataRow row in  sourceDs.Tables[i].Rows)
             {
                 HSSFRow dataRow = (HSSFRow)sheet.CreateRow(rowIndex);
                 foreach  (DataColumn column in  sourceDs.Tables[i].Columns)
                 {
                     dataRow.CreateCell(column.Ordinal).SetCellValue(row[column].ToString());
                 }
                 rowIndex++;
             }
         }
         workbook.Write(ms);
         ms.Flush();
         ms.Position = 0;
         workbook = null ;
         return  ms;
     }
     /// <summary>
     /// 由DataSet導出Excel
     /// </summary>  
     /// <param name="sourceTable">要導出數據的DataTable</param>
     /// <param name="fileName">指定Excel工作表名稱</param>
     /// <returns>Excel工作表</returns>   
     public  static  void  ExportDataSetToExcel(DataSet sourceDs, string  fileName)
     {
         //檢查是否有Table數量超過65325
         for  ( int  t = 0; t < sourceDs.Tables.Count; t++)
         {
             if  (sourceDs.Tables[t].Rows.Count > ExcelMaxRow)
             {
                 DataSet ds = GetdtGroup(sourceDs.Tables[t].Copy());
                 sourceDs.Tables.RemoveAt(t);
                 //將得到的ds插入 sourceDs中
                 for  ( int  g = 0; g < ds.Tables.Count; g++)
                 {
                     DataTable dt = ds.Tables[g].Copy();
                     sourceDs.Tables.Add(dt);
                 }
                 t--;
             }
         }
 
         MemoryStream ms = ExportDataSetToExcel(sourceDs) as  MemoryStream;
         HttpContext.Current.Response.AppendHeader( "Content-Disposition" , "attachment;filename="  + fileName);
         HttpContext.Current.Response.BinaryWrite(ms.ToArray());
         HttpContext.Current.ApplicationInstance.CompleteRequest();
         //HttpContext.Current.Response.End();
         ms.Close();
         ms = null ;
     }
     /// <summary>
     /// 由DataTable導出Excel
     /// </summary>
     /// <param name="sourceTable">要導出數據的DataTable</param>
     /// <returns>Excel工作表</returns>   
     private  static  Stream ExportDataTableToExcel(DataTable sourceTable)
     {
         HSSFWorkbook workbook = new  HSSFWorkbook();
         MemoryStream ms = new  MemoryStream();
         HSSFSheet sheet = (HSSFSheet)workbook.CreateSheet(sourceTable.TableName);
         HSSFRow headerRow = (HSSFRow)sheet.CreateRow(0);
         // handling header.     
         foreach  (DataColumn column in  sourceTable.Columns)
             headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
         // handling value.     
         int  rowIndex = 1;
         foreach  (DataRow row in  sourceTable.Rows)
         {
             HSSFRow dataRow = (HSSFRow)sheet.CreateRow(rowIndex);
             foreach  (DataColumn column in  sourceTable.Columns)
             {
                 dataRow.CreateCell(column.Ordinal).SetCellValue(row[column].ToString());
             }
             rowIndex++;
         }
         workbook.Write(ms);
         ms.Flush();
         ms.Position = 0;
         sheet = null ;
         headerRow = null ;
         workbook = null ;
         return  ms;
     }
     /// <summary>
     /// 由DataTable導出Excel
     /// </summary>
     /// <param name="sourceTable">要導出數據的DataTable</param>
     /// <param name="fileName">指定Excel工作表名稱</param>
     /// <returns>Excel工作表</returns>
     public  static  void  ExportDataTableToExcel(DataTable sourceTable, string  fileName)
     {
         //如數據超過65325則分成多個Table導出
         if  (sourceTable.Rows.Count > ExcelMaxRow)
         {
             DataSet ds = GetdtGroup(sourceTable);
             //導出DataSet
             ExportDataSetToExcel(ds, fileName);
         }
         else
         {
             MemoryStream ms = ExportDataTableToExcel(sourceTable) as  MemoryStream;
             HttpContext.Current.Response.AppendHeader( "Content-Disposition" , "attachment;filename="  + fileName);
             HttpContext.Current.Response.BinaryWrite(ms.ToArray());
             HttpContext.Current.ApplicationInstance.CompleteRequest();
             //HttpContext.Current.Response.End();
             ms.Close();
             ms = null ;
         }
     }
 
     /// <summary>
     /// 傳入行數超過65325的Table,返回DataSet
     /// </summary>
     /// <param name="dt"></param>
     /// <returns></returns>
     public  static  DataSet GetdtGroup(DataTable dt)
     {
         string  tablename = dt.TableName;
 
         DataSet ds = new  DataSet();
         ds.Tables.Add(dt);
 
         double  n = dt.Rows.Count / Convert.ToDouble(ExcelMaxRow);
 
         //創建表
         for  ( int  i = 1; i < n; i++)
         {
             DataTable dtAdd = dt.Clone();
             dtAdd.TableName = tablename + "_"  + i.ToString();
             ds.Tables.Add(dtAdd);
         }
 
         //分解數據
         for  ( int  i = 1; i < ds.Tables.Count; i++)
         {
             //新表行數達到最大 或 基表數量不足
             while  (ds.Tables[i].Rows.Count != ExcelMaxRow && ds.Tables[0].Rows.Count != ExcelMaxRow)
             {
                 ds.Tables[i].Rows.Add(ds.Tables[0].Rows[ExcelMaxRow].ItemArray);
                 ds.Tables[0].Rows.RemoveAt(ExcelMaxRow);
 
             }
         }
 
         return  ds;
     }
 
     /// <summary>
     /// 由DataTable導出Excel
     /// </summary>
     /// <param name="sourceTable">要導出數據的DataTable</param>
     /// <param name="fileName">指定Excel工作表名稱</param>
     /// <returns>Excel工作表</returns>
     public  static  void  ExportDataTableToExcelModel(DataTable sourceTable, string  modelpath, string  modelName, string  fileName, string  sheetName)
     {
         int  rowIndex = 2; //從第二行開始,因為前兩行是模板里面的內容
         int  colIndex = 0;
         FileStream file = new  FileStream(modelpath + modelName + ".xls" , FileMode.Open, FileAccess.Read); //讀入excel模板
         HSSFWorkbook hssfworkbook = new  HSSFWorkbook(file);
         HSSFSheet sheet1 = (HSSFSheet)hssfworkbook.GetSheet( "Sheet1" );
         sheet1.GetRow(0).GetCell(0).SetCellValue( "excelTitle" );      //設置表頭
         foreach  (DataRow row in  sourceTable.Rows)
         {   //雙循環寫入sourceTable中的數據
             rowIndex++;
             colIndex = 0;
             HSSFRow xlsrow = (HSSFRow)sheet1.CreateRow(rowIndex);
             foreach  (DataColumn col in  sourceTable.Columns)
             {
                 xlsrow.CreateCell(colIndex).SetCellValue(row[col.ColumnName].ToString());
                 colIndex++;
             }
         }
         sheet1.ForceFormulaRecalculation = true ;
         FileStream fileS = new  FileStream(modelpath + fileName + ".xls" , FileMode.Create); //保存
         hssfworkbook.Write(fileS);
         fileS.Close();
         file.Close();
     }
}


免責聲明!

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



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