DataGridView如何快速導出Excel

從DataGridView或DataTable導出Excel文件,爲了按照數據類型設置單元格格式,導出Excel時速度都比較慢,一直找不到好的辦法。

最後從外文網站上找到解決辦法,使用ws.get_Range(excelRange, Type.Missing).Value2方法批量設置單元格的值。詳細代碼如下:

public void DataToExcelFast(DataGridView dgv, string fName)
{
    try
    {
        Excel.Application excel = new Excel.Application();
        Excel.Workbook wb = excel.Workbooks.Add(true);
        Excel.Worksheet ws = (Excel.Worksheet)wb.ActiveSheet;
        ws.Name = fName;
        string sFile = string.Empty;
        SaveFileDialog dialog = new SaveFileDialog();
        dialog.Title = "Save export file";
        dialog.Filter = "EXECL File(*.xlsx) |.xlsx";
        dialog.FileName = fName;
        dialog.FilterIndex = 1;
        if (dialog.ShowDialog() == DialogResult.OK)
        {
            string FileName = dialog.FileName;
            if (File.Exists(FileName))
                File.Delete(FileName);
            sFile = FileName;
            excel.Visible = false;
            excel.DisplayAlerts = false;
            excel.Calculation = Excel.XlCalculation.xlCalculationManual;
            ArrayList cols = new ArrayList();
            #region 列標題,並根據列的數據類型設置Excel列的格式
            int visibleColumnCount = 0;
            foreach (DataGridViewColumn col in dgv.Columns)
            {
                if (col.Visible)
                {
                    visibleColumnCount++;
                    ws.Cells[1, visibleColumnCount].Value2 = col.HeaderText.ToString();
                    ws.Cells[1, visibleColumnCount].Font.Bold = true;
                    cols.Add(col.Name);
                    if (col.ValueType != null)
                    {
                        if (col.ValueType.Name.Equals("DateTime"))
                        {
                            ws.Columns[visibleColumnCount].NumberFormatLocal = @"yyyy-mm-dd HH:mm";
                            ws.Columns[visibleColumnCount].Font.Color 
                                = System.Drawing.ColorTranslator.ToOle(Color.Blue);
                        }
                        else if (col.ValueType.Name.Equals("Decimal") 
                            || col.ValueType.Name.Equals("Double"))
                        {
                            ws.Columns[visibleColumnCount].NumberFormat = "0.00";
                        }
                        else if (col.ValueType.Name.Equals("Int32"))
                        {
                            ws.Columns[visibleColumnCount].NumberFormat = "0";
                        }
                        else
                        {
                            ws.Columns[visibleColumnCount].NumberFormatLocal = @"@";
                        }
                    }
                    else
                        ws.Columns[visibleColumnCount].NumberFormatLocal = @"@";
                }
            }
            #endregion
            #region 寫入行
            // Copy each DataTable
            // Copy the DataTable to an object array
            object[,] rawData = new object[dgv.Rows.Count, cols.Count];
            // Copy the column names to the first row of the object array
            for (int col = 0; col < cols.Count; col++)
            {
                rawData[0, col] = cols[col];
            }
            // Copy the values to the object array
            for (int col = 0; col < cols.Count; col++)
            {
                for (int row = 0; row < dgv.Rows.Count; row++)
                {
                    rawData[row, col] = dgv.Rows[row].Cells[cols[col].ToString()].Value;
                }
            }
            // Calculate the final column letter
            string finalColLetter = string.Empty;
            string colCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            int colCharsetLen = colCharset.Length;
            if (cols.Count > colCharsetLen)
            {
                finalColLetter = colCharset.Substring(
                    (cols.Count - 1) / colCharsetLen - 1, 1);
            }
            finalColLetter += colCharset.Substring(
                    (cols.Count - 1) % colCharsetLen, 1);
            // Fast data export to Excel
            string excelRange = string.Format("A2:{0}{1}",
                finalColLetter, dgv.Rows.Count + 1);
            ws.get_Range(excelRange, Type.Missing).Value2 = rawData;
            #endregion
            excel.Calculation = Excel.XlCalculation.xlCalculationAutomatic;
            // 51表示2007-2010格式的xlsx
            ws.SaveAs(FileName, 51, Type.Missing, Type.Missing, 
                Type.Missing, Type.Missing, 
                Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, 
                Type.Missing, Type.Missing, Type.Missing);
            wb.Close(true, Type.Missing, Type.Missing);
            excel.Quit();
            // 安全回收進程
            System.GC.GetGeneration(excel);
            if (MessageBox.Show("已經導出Excel,您是否要打開?", "提示",
                 MessageBoxButtons.YesNo) == DialogResult.Yes)
                System.Diagnostics.Process.Start(FileName);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("導出Excel時遇到錯誤\r\n" + ex.Message,
        "Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章