從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);
}
}