C# WinForm通过Office Interop导出Excel:完整代码示例

半杯拿铁
半杯拿铁
发布时间:2026-10-13| 3人浏览过
原创

在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 对象,不要只关闭应用而不释放句柄。
以上就是C# WinForm通过Office Interop导出Excel的详细内容,更多关于C#操作Excel的技巧请关注本站其它相关文章!
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。