剛才准備寫這個文章的時候,看到同事發來的群消息,我邪惡了。 我相信看到這篇文章的人 都比較純,我就跟大家分享一下吧! 主要內容:現在因為需求變化,公司需要一台服務器做中轉,公司一MM 准備了一台普通PC機來做服務器,然后問我一同事看下是否可以。 同事A就回復說:不知道這台PC能不能經得住? MM回復:“呵呵.你覺得它哪個部位經受不住?”同事就回復說:“應該不會是暴露的部位
,怕連續搞受不住,可能會影響使用次數。” ~~ 之后各種聯想。(看到這里,思想邪惡的人請點擊下面的“推薦+1” 消除罪惡感! )
好了, 冷笑話到此為止。直入主題吧 。 最近公司項目涉及到千百萬級別的數據導出問題。 老外(客戶)那邊又需要整理導出的數據,所以指定需要導出Excel格式的。大家都知道Excel格式的文件最大支持數據是65535條,怎么讓千百萬級別的數據量顯示到同一個Excel里面呢? 在網上瀏覽了一下,都不如意,最后聽說office安裝目錄有API,於是整理了下。知道答案的請直接點擊下面的“推薦+1”然后就可以關掉瀏覽器了,不知道答案的我也不繞彎子了,請蛋定的看完下面的code,然后點擊"推薦+1"。 謝謝 ,供上code:
BeginCode
/// <summary> /// 大量數據導出 /// </summary> /// <param name="table"></param> /// <param name="saveFileName"></param> public static void ExportToExcel(System.Data.DataTable table, string saveFileName) { try { if (table == null) { return; } bool fileSaved = false; //ExcelApp xlApp = new ExcelApp(); Application xlApp = new Application(); if (xlApp == null) { return; } Workbooks workbooks = xlApp.Workbooks; Workbook workbook = workbooks.Add(XlWBATemplate.xlWBATWorksheet); Worksheet worksheet = (Worksheet)workbook.Worksheets[1];//取得sheet1 long rows = table.Rows.Count; /*下邊注釋的兩行代碼當數據行數超過行時,出現異常:異常來自HRESULT:0x800A03EC。因為:Excel 2003每個sheet只支持最大行數據 //Range fchR = worksheet.get_Range(worksheet.Cells[1, 1], worksheet.Cells[table.Rows.Count+2, gridview.Columns.View.VisibleColumns.Count+1]); //fchR.Value2 = datas;*/ if (rows > 65535) { long pageRows = 60000;//定義每頁顯示的行數,行數必須小於 int scount = (int)(rows / pageRows); if (scount * pageRows < table.Rows.Count)//當總行數不被pageRows整除時,經過四舍五入可能頁數不准 { scount = scount + 1; } for (int sc = 1; sc <= scount; sc++) { if (sc > 1) { object missing = System.Reflection.Missing.Value; worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets.Add( missing, missing, missing, missing);//添加一個sheet } else { worksheet = (Worksheet)workbook.Worksheets[sc];//取得sheet1 } string[,] datas = new string[pageRows + 1, table.Columns.Count + 1]; for (int i = 0; i < table.Columns.Count; i++) //寫入字段 { datas[0, i] = table.Columns[i].Caption; } Range range = worksheet.get_Range(worksheet.Cells[1, 1], worksheet.Cells[1, table.Columns.Count]); range.Interior.ColorIndex = 15;//15代表灰色 range.Font.Bold = true; range.Font.Size = 9; int init = int.Parse(((sc - 1) * pageRows).ToString()); int r = 0; int index = 0; int result; if (pageRows * sc >= table.Rows.Count) { result = table.Rows.Count; } else { result = int.Parse((pageRows * sc).ToString()); } for (r = init; r < result; r++) { index = index + 1; for (int i = 0; i < table.Columns.Count; i++) { if (table.Columns[i].DataType == typeof(string) || table.Columns[i].DataType == typeof(Decimal) || table.Columns[i].DataType == typeof(DateTime) || table.Columns[i].DataType == typeof(int) || table.Columns[i].DataType == typeof(double)) { object obj = table.Rows[r][table.Columns[i].ColumnName]; datas[index, i] = obj == null ? "" : "'" + obj.ToString().Trim();//在obj.ToString()前加單引號是為了防止自動轉化格式 } } } Range fchR = worksheet.get_Range(worksheet.Cells[1, 1], worksheet.Cells[index + 2, table.Columns.Count + 1]); fchR.Value2 = datas; worksheet.Columns.EntireColumn.AutoFit();//列寬自適應。 range = worksheet.get_Range(worksheet.Cells[1, 1], worksheet.Cells[index + 1, table.Columns.Count]); //15代表灰色 range.Font.Size = 9; range.RowHeight = 14.25; range.Borders.LineStyle = 1; range.HorizontalAlignment = 1; } } else { string[,] datas = new string[table.Rows.Count + 2, table.Columns.Count + 1]; for (int i = 0; i < table.Columns.Count; i++) //寫入字段 { datas[0, i] = table.Columns[i].Caption; } Range range = worksheet.get_Range(worksheet.Cells[1, 1], worksheet.Cells[1, table.Columns.Count]); range.Interior.ColorIndex = 15;//15代表灰色 range.Font.Bold = true; range.Font.Size = 9; int r = 0; for (r = 0; r < table.Rows.Count; r++) { for (int i = 0; i < table.Columns.Count; i++) { if (table.Columns[i].DataType == typeof(string) || table.Columns[i].DataType == typeof(Decimal) || table.Columns[i].DataType == typeof(DateTime)) { object obj = table.Rows[r][table.Columns[i].ColumnName]; datas[r + 1, i] = obj == null ? "" : "'" + obj.ToString().Trim();//在obj.ToString()前加單引號是為了防止自動轉化格式 } } //System.Windows.Forms.Application.DoEvents(); } Range fchR = worksheet.get_Range(worksheet.Cells[1, 1], worksheet.Cells[table.Rows.Count + 2, table.Columns.Count + 1]); fchR.Value2 = datas; worksheet.Columns.EntireColumn.AutoFit();//列寬自適應。 range = worksheet.get_Range(worksheet.Cells[1, 1], worksheet.Cells[table.Rows.Count + 1, table.Columns.Count]); //15代表灰色 range.Font.Size = 9; range.RowHeight = 14.25; range.Borders.LineStyle = 1; range.HorizontalAlignment = 1; } if (saveFileName != "") { try { workbook.Saved = true; workbook.SaveCopyAs(saveFileName); fileSaved = true; } catch (Exception ex) { fileSaved = false; } } else { fileSaved = false; } xlApp.Quit(); GC.Collect();//強行銷毀 //web后台談框框,winform可以使用messagebox.. 大家都懂的 System.Web.HttpContext.Current.Response.Write("<Script Language=JavaScript>...alert('Export Success! File path in D disk root directory.');</Script>"); } catch (Exception) { System.Web.HttpContext.Current.Response.Write("<Script Language=JavaScript>...alert('Export Error! please contact administrator!');</Script>"); } }
EndCode
ok,就這么多了,傳遞一個DataTable 和一個保存文件的路徑即可實現,執行效果如下:(該圖為30W條數據在Office 2007上的測試效果,沒有計量執行時間,不過也就喝完一口水,在蓋上蓋子的時間) :)

圖片二:

為了不想蹲局子,我小心翼翼的把敏感數據A掉,我突然發現QQ截圖功能弱爆了,還是window自帶的截圖爽~~
ok就到這里,有錯誤的地方,敬請拍磚,期待磚磚砸臉 謝謝 再會~~
