You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#开发多格式转换工具时Excel数据显示到DataGrid问题求助

问题根因

你代码的核心故障点是 XlsxReaderAndConverter 虽然继承了MainWindow,但你新创建的这个类实例和当前正在运行的主窗口不是同一个对象,它内部的dtGrid、cmbColumn控件都没有初始化,运行到控件操作的代码时会直接抛出空引用异常,导致数据无法正常显示。
同时还存在两个隐性问题:

  • 拼接|再拆分的逻辑如果遇到单元格本身包含|会出现列错位
  • 没有释放Office COM对象,会导致Excel进程残留在系统后台

修复方案

步骤1:重写XlsxReaderAndConverter类,剥离UI操作

这个类只负责读取Excel返回DataTable,不要操作任何UI控件:

using System.Data;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Excel;

class XlsxReaderAndConverter
{
    public string FileName { get; set; }

    public XlsxReaderAndConverter(string fileName)
    {
        FileName = fileName;
    }

    public DataTable ReadExcel()
    {
        DataTable dt = new DataTable();
        Application excelApp = null;
        Workbook excelBook = null;
        Worksheet excelSheet = null;
        Range excelRange = null;

        try
        {
            excelApp = new Application();
            excelBook = excelApp.Workbooks.Open(FileName, 0, true, 5, "", "", true, XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
            excelSheet = (Worksheet)excelBook.Worksheets.Item[1];
            excelRange = excelSheet.UsedRange;

            // 初始化列
            for (int colCnt = 1; colCnt <= excelRange.Columns.Count; colCnt++)
            {
                var cellVal = (excelRange.Cells[1, colCnt] as Range)?.Value2;
                // 处理表头为空的情况
                string columnName = cellVal?.ToString() ?? $"列{colCnt}";
                dt.Columns.Add(columnName, typeof(string));
            }

            // 读取行数据,直接赋值不需要拼接拆分
            for (int rowCnt = 2; rowCnt <= excelRange.Rows.Count; rowCnt++)
            {
                DataRow dr = dt.NewRow();
                for (int colCnt = 1; colCnt <= excelRange.Columns.Count; colCnt++)
                {
                    var cellVal = (excelRange.Cells[rowCnt, colCnt] as Range)?.Value2;
                    dr[colCnt - 1] = cellVal?.ToString() ?? "";
                }
                dt.Rows.Add(dr);
            }
            return dt;
        }
        finally
        {
            // 强制释放COM对象,避免残留Excel进程
            if (excelRange != null) Marshal.ReleaseComObject(excelRange);
            if (excelSheet != null) Marshal.ReleaseComObject(excelSheet);
            if (excelBook != null)
            {
                excelBook.Close(false);
                Marshal.ReleaseComObject(excelBook);
            }
            if (excelApp != null)
            {
                excelApp.Quit();
                Marshal.ReleaseComObject(excelApp);
            }
        }
    }
}

步骤2:修改主窗口调用逻辑

UI操作放回主窗口实例执行,避免空引用:

case ".xlsx":
    XlsxReaderAndConverter xlsxReaderAndConverter = new XlsxReaderAndConverter(fileName);
    DataTable resultDt = xlsxReaderAndConverter.ReadExcel();
    // 绑定数据到当前窗口的控件
    dtGrid.ItemsSource = resultDt.DefaultView;
    cmbColumn.Items.Clear();
    for(int i=1;i<=resultDt.Columns.Count;i++)
    {
        cmbColumn.Items.Add(i);
    }
    break;

额外优化建议

如果不想依赖用户本地安装Excel,可以改用EPPlus、NPOI等开源的xlsx读取库,兼容性更好,也不需要处理复杂的COM对象释放逻辑。

内容的提问来源于stack exchange,提问作者Klaatu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 03:45:03