大量數據導出Excel 之 多重影分身之術


      剛才准備寫這個文章的時候,看到同事發來的群消息,我邪惡了。 我相信看到這篇文章的人 都比較純,我就跟大家分享一下吧! 主要內容:現在因為需求變化,公司需要一台服務器做中轉,公司一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就到這里,有錯誤的地方,敬請拍磚,期待磚磚砸臉  謝謝  再會~~


免責聲明!

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



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