C# WinForm通过Office Interop导出Excel:完整代码示例
在C#开发中,利用Microsoft.Office.Interop.Excel库可以将数据库或界面数据直接转换为Excel格式,这种方式依赖于本地安装的Excel软件,适合内网或特定环境下的轻量级导出需求。
准备工作
在使用Interpro进行Excel操作前,需确保运行环境中已安装 Microsoft Excel,且项目中引用了相应的程序集。通常需要在项目添加对 Microsoft.Office.Interop.Excel.dll 的引用。
第1步:定义导出逻辑与异常处理
首先创建一个事件处理程序来触发导出动作。核心思路是将界面的数据源(如 DataGridView)转换为 DataTable,并进行非空检查。
private void btnExportExcel_Click(object sender, EventArgs e)
{
// 获取数据源
DataTable dt = this.dgvWaterTicket.DataSource;
// 安全检查:判断是否存在数据
if (dt == null || dt.Rows.Count == 0)
{
return;
}
// 初始化Excel应用实例
Excel.Application xlApp = new Excel.Application();
if (xlApp == null)
{
MessageBox.Show("请确保您的电脑已经安装Excel", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
xlApp.UserControl = true; // 允许用户后续手动操作生成的Excel文件
Excel.Workbooks workbooks = xlApp.Workbooks;
第2步:创建工作簿与设置标题
新建一个工作表作为模板,并设置第一行作为合并后的标题栏,同时调整列宽和对齐方式以美化报表。
Excel.Workbook workbook = workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Worksheets[1];
if (worksheet == null)
{
MessageBox.Show("工作表创建失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
try
{
// 设置主标题
worksheet.Cells[1, 1] = frm.Text; // 假设frm为当前窗体实例
// 合并标题单元格(示例中假设需要合并多列)
worksheet.get_Range(worksheet.Cells[1, 1], worksheet.Cells[1, dt.Columns.Count]).MergeCells = true;
// 设置居中对齐
worksheet.get_Range(worksheet.Cells[1, 1], worksheet.Cells[1, dt.Columns.Count]).HorizontalAlignment = Excel.XlVAlign.xlVAlignCenter;
// 调整列宽,例如第一列设为20,其余设为15
worksheet.get_Range(worksheet.Cells[1, 1], worksheet.Cells[1, 1]).ColumnWidth = 20;
for(int i=2; i<=dt.Columns.Count; i++)
{
worksheet.get_Range(worksheet.Cells[1, i], worksheet.Cells[1, i]).ColumnWidth = 15;
}
第3步:写入字段名与数据内容
遍历 DataTable 的列集合写入表头,并标记背景色与加粗字体;随后嵌套循环写入具体行数据。可加入自动换行和行高自适应逻辑以适应长文本。
long totalCount = dt.Rows.Count;
long rowRead = 0;
float percent = 0;
// 写入表头字段
for (int i = 0; i < dt.Columns.Count; i++)
{
worksheet.Cells[2, i + 1] = dt.Columns[i].ColumnName;
var range = (Excel.Range)worksheet.Cells[2, i + 1];
range.Interior.ColorIndex = 15; // 灰色背景
range.Font.Bold = true;
}
// 写入数据行
for (int r = 0; r < dt.Rows.Count; r++)
{
for (int i = 0; i < dt.Columns.Count; i++)
{
// 防止null值报错
worksheet.Cells[r + 3, i + 1] = dt.Rows[r][i] ?? "";
}
rowRead++;
percent = ((float)(100 * rowRead)) / totalCount;
// 设置第四列自动换行(示例固定列,可根据实际情况调整)
if (dt.Columns.Count >= 4)
{
worksheet.get_Range(worksheet.Cells[r + 3, 4], worksheet.Cells[r + 3, 4]).Columns.WrapText = true;
worksheet.get_Range(worksheet.Cells[r + 3, 4], worksheet.Cells[r + 3, 4]).Rows.AutoFit();
}
}
第4步:添加边框并可见化结果
选中数据区域应用外框线和内部网格线,最后将Excel设置为可见状态,以便用户查看。
// 选取数据区域:从第二行开始到最后一行,所有列
var range = worksheet.get_Range(worksheet.Cells[2, 1], worksheet.Cells[dt.Rows.Count + 2, dt.Columns.Count]);
// 外部边框
range.BorderAround(Excel.XlLineStyle.xlContinuous, Excel.XlBorderWeight.xlThin, Excel.XlColorIndex.xlColorIndexAutomatic, null);
// 内部横向边框
range.Borders[Excel.XlBordersIndex.xlInsideHorizontal].ColorIndex = Excel.XlColorIndex.xlColorIndexAutomatic;
range.Borders[Excel.XlBordersIndex.xlInsideHorizontal].LineStyle = Excel.XlLineStyle.xlContinuous;
range.Borders[Excel.XlBordersIndex.xlInsideHorizontal].Weight = Excel.XlBorderWeight.xlThin;
// 内部纵向边框
if (dt.Columns.Count > 1)
{
range.Borders[Excel.XlBordersIndex.xlInsideVertical].ColorIndex = Excel.XlColorIndex.xlColorIndexAutomatic;
range.Borders[Excel.XlBordersIndex.xlInsideVertical].LineStyle = Excel.XlLineStyle.xlContinuous;
range.Borders[Excel.XlBordersIndex.xlInsideVertical].Weight = Excel.XlBorderWeight.xlThin;
}
xlApp.Visible = true;
}
第5步:释放COM对象资源
这是最关键的一步。必须手动释放COM组件,否则会导致后台残留大量Excel进程,造成内存泄漏。顺序应从最内层对象到最外层应用实例。
catch
{
MessageBox.Show("导出Excel失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
// 强制释放COM对象
System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(workbooks);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
// 回收垃圾
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
完成判断与注意事项
当程序执行完毕,本地会弹出一个包含格式化数据的Excel窗口。此时可以正常保存或打印。
- 依赖环境:此方法要求服务器或客户端必须安装 Microsoft Office Excel。
- 性能考量:对于几十万行以上的大数据量,直接使用 Interop 速度较慢且易卡顿,建议考虑使用 NPOI 或 EPPlus 等纯代码库方案。
- 资源泄漏:务必在
finally块中正确释放每一个 Excel COM 对象,不要只关闭应用而不释放句柄。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









