導出數據到Excel算是一個比較成熟的技術點了,現在的方法也比較,比如:可以用微軟的EXCEL組件,第三方開源組件(NPOI,MyXls等等。)
今天我就首先說一下微軟的EXCEL組件
在開發過程中可能出現一系列的問題
(1)Excel行數的限制,office2003的行數為65536行。如果超過這個行數應該再來一個sheet
(2)導出數據慢的問題,如果數據量比較小可能一般的程序邏輯看不出來它的性能問題,當我們導出的數據很多時,應該選擇什么方案解決
(3) 導出的格式問題,一些導出到Excel中的格式可能需要計算,那么它就是數字型的
本例先簡單說一下實現邏輯,不多說,直接上代碼:
(1)添加引用
(2)可以寫代碼了
第一步:創建一個Excel工作薄
Interop.Excel.Application xlApp = new Interop.Excel.Application(); ////建立一個Excel.Application的新進程
Excel.Workbooks workbooks = xlApp.Workbooks; //工作薄的創建
Excel.Workbook workbook = workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet); //工作表sheet的創建
【當然也可以用下面的代碼創建工作表sheet】
object missing = System.Reflection.Missing.Value;
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Worksheets.Add(missing, missing, missing, missing);//添加一個sheet
第二步:插入數據
object[,] dataArray = new object[rowCount, colCount];
for (int j = 0; j < rowCount; j++)
{
for (int k = 0; k < colCount; k++)
{
dataArray[j, k] = drs[j][k].ToString();
}
}
worksheet.get_Range(worksheet.Cells[1, 1], worksheet.Cells[rowCount, colCount]).Value2 = dataArray;
注:這種方式是把一個二維數組的數據插入到Excel的固定區域,不用一個單元格一個單元格的插入,速度快很多。解決了導出數據慢的問題
可能你保存的時候定義Excel的格式,可以用NumberFormat來定義,例如:
worksheet.get_Range(worksheet.Cells[1, 1], worksheet.Cells[rowCount + 1, colCount]).NumberFormat = "@";
第三步:保存Excel
workbook.SaveAs(strFilePath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
workbook.Close(true, Type.Missing, Type.Missing);
workbook = null;
以上是最簡潔的方式,不過第一個問題還沒有給解決,直接上代碼吧。主要是邏輯問題了。沒有什么技術難點。
1 /// <summary> 2 /// 導出Excel文件 3 /// </summary> 4 /// <param name="ds">要導入到Excel的數據</param> 5 public static string DataSetToExcel2(System.Data.DataSet ds) 6 { 7 string strFilePath = System.AppDomain.CurrentDomain.BaseDirectory + DateTime.Now.ToString("yyyyMMddhhmmss") + ".xls"; 8 9 Interop.Excel.Application xlApp = new Interop.Excel.Application(); 10 Interop.Excel.Workbooks workbooks = xlApp.Workbooks; 11 Interop.Excel.Workbook workbook = workbooks.Add(Interop.Excel.XlWBATemplate.xlWBATWorksheet); 12 13 try 14 { 15 if (ds.Tables.Count == 0) 16 { 17 return "沒有數據導出"; 18 } 19 20 int MaxRowCount = 60000; //一個sheet的最大行數限制,主要考慮到office2003的行數有限 21 22 DataTable dt = ds.Tables[0];//數據源 23 24 int rowCount = dt.Rows.Count; 25 int colCount = dt.Columns.Count; 26 27 if (rowCount > 0 && rowCount <= MaxRowCount) 28 { 29 object missing = System.Reflection.Missing.Value; 30 Interop.Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Worksheets.Add(missing, missing, missing, missing);//添加一個sheet 31 //Worksheet worksheet = (Worksheet)workbook.Worksheets[i]; 32 worksheet.Name = "sheet"; 33 34 35 object[,] dataArray = new object[rowCount + 1, colCount]; 36 //表頭導出 37 for (int j = 0; j < colCount; j++) 38 { 39 dataArray[0, j] = dt.Columns[j].ColumnName.ToString(); 40 } 41 //內容導出 42 for (int j = 0; j < rowCount; j++) 43 { 44 for (int k = 0; k < colCount; k++) 45 { 46 dataArray[j + 1, k] = dt.Rows[j][k].ToString(); 47 } 48 } 53 worksheet.get_Range(worksheet.Cells[1, 1], worksheet.Cells[rowCount + 1, colCount]).NumberFormat = "@"; 54 worksheet.get_Range(worksheet.Cells[1, 1], worksheet.Cells[rowCount + 1, colCount]).Value2 = dataArray; 55 } 56 else //超過sheet表單的就再創適sheet表單 57 { 58 int sheetCount = 1; //sheet表單個數 59 if (rowCount % MaxRowCount == 0) 60 { 61 sheetCount = rowCount / MaxRowCount; 62 } 63 else 64 { 65 sheetCount = rowCount / MaxRowCount + 1; 66 } 67 68 int Flag = 1; 69 for (var m = 0; m < sheetCount; m++) 70 { 71 //添加一個sheet表單 72 object missing1 = System.Reflection.Missing.Value; 73 Excel.Worksheet worksheet1 = (Excel.Worksheet)workbook.Worksheets.Add(missing1, missing1, missing1, missing1);//添加一個sheet 74 75 worksheet1.Name = "第" + (m + 1) + "頁sheet"; 76 //如果是最后一個sheet的話 並且最后一個sheet表單數據不等於60000 77 if (Flag == sheetCount && (rowCount % MaxRowCount != 0)) 78 { 79 int newrowCount = rowCount - ((Flag - 1) * MaxRowCount); //最后一個sheet的數據 80 object[,] dataArray = new object[newrowCount + 1, colCount]; 81 82 int RowIndex = 0; 83 84 85 for (int j = 0; j < colCount; j++) 86 { 87 dataArray[0, j] = dt.Columns[j].ColumnName.ToString(); 88 } 89 90 int startIndex = (Flag - 1) * MaxRowCount; 91 for (int n = startIndex; n < startIndex + newrowCount; n++) 92 { 93 for (int t = 0; t < colCount; t++) 94 { 95 dataArray[RowIndex + 1, t] = dt.Rows[n][t].ToString(); 96 } 97 98 RowIndex++; 103 } 104 worksheet1.get_Range(worksheet1.Cells[1, 1], worksheet1.Cells[newrowCount + 1, colCount]).NumberFormat = "@"; 105 worksheet1.get_Range(worksheet1.Cells[1, 1], worksheet1.Cells[newrowCount + 1, colCount]).Value2 = dataArray; 106 107 } 108 else 109 { 110 object[,] dataArray = new object[MaxRowCount + 1, colCount]; 111 112 int RowIndex = 0; 113 for (int j = 0; j < colCount; j++) 114 { 115 dataArray[0, j] = dt.Columns[j].ColumnName.ToString(); 116 } 117 118 int startIndex = (Flag - 1) * MaxRowCount; 119 for (int n = startIndex; n < startIndex + MaxRowCount; n++) 120 { 121 for (int t = 0; t < colCount; t++) 122 { 123 dataArray[RowIndex + 1, t] = dt.Rows[n][t].ToString(); 124 } 125 if (n % 100 == 0) 126 { 127 128 System.Windows.Forms.Application.DoEvents(); 129 } 130 131 RowIndex++; 132 } 133 worksheet1.get_Range(worksheet1.Cells[1, 1], worksheet1.Cells[MaxRowCount + 1, colCount]).NumberFormat = "@"; 134 worksheet1.get_Range(worksheet1.Cells[1, 1], worksheet1.Cells[MaxRowCount + 1, colCount]).Value2 = dataArray; 135 } 136 Flag++; 137 } 138 139 } 140 workbook.SaveAs(strFilePath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); 141 workbook.Close(true, Type.Missing, Type.Missing); 142 workbook = null; 143 } 144 145 146 catch 147 { 148 xlApp.Quit(); 149 xlApp = null; 150 System.Runtime.InteropServices.Marshal.ReleaseComObject(workbooks); 151 System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp); 152 153 GC.Collect(); 154 return "出現異常"; 155 } 156 finally 157 { 158 System.Runtime.InteropServices.Marshal.ReleaseComObject(workbooks); 159 System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp); 160 161 GC.Collect(); 162 } 163 164 return "導出成功,導出文件路徑:" + strFilePath; 165 }
頭一次寫文章,主要記錄自己開發過程的點點滴滴,如果能幫助大家一點最好,哈哈。
轉載的請注原創地址,謝謝。