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

C# WinForm使用OfficeOpenXML写入XLSX文件遇IO错误求助

问题分析与修复方案

核心问题梳理

你的代码存在几个关键问题,直接导致了这两类IO错误:

  • 重复锁定文件:同时用FileStream和ExcelPackage打开同一个文件,两个流同时占用文件,即便没有外部程序打开,自身代码也会把文件锁死,引发“被另一个进程占用”的错误。
  • 文件不存在时的模式错误:用FileMode.Open打开文件时要求文件必须存在,不存在就会直接抛出找不到文件的错误;同时ExcelPackage直接传入不存在的FileInfo也无法自动创建新文件。
  • 语法错误:PullRecord的初始化代码缺少开头的{,还有多余的嵌套大括号,会导致编译或运行时异常。

修复后的完整代码

private void saveButton_Click(object sender, EventArgs e)
{
    // 修正PullRecord初始化的语法错误
    PullRecord record = new PullRecord
    {
        WellName = wellNametextBox.Text,
        dateFinished = dateFinishedTimePicker.Value.ToShortDateString()
    };

    string filePath = @"C:\Users\4ndrocles\Desktop\Pulling Reports\output.xlsx";
    FileInfo fileInfo = new FileInfo(filePath);

    try
    {
        ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
        
        // 让ExcelPackage自动处理文件的创建或打开:文件不存在则创建新的,存在则打开
        using (ExcelPackage package = new ExcelPackage(fileInfo))
        {
            // 添加新工作表
            ExcelWorksheet worksheet = package.Workbook.Worksheets.Add($"{record.WellName} - {record.dateFinished}");
            
            // 写入表头和数据
            worksheet.Cells[1, 1].Value = "Well Name";
            worksheet.Cells[1, 3].Value = record.WellName;
            worksheet.Cells[6, 1].Value = "Date Finished";
            worksheet.Cells[6, 3].Value = record.dateFinished;
            
            // 保存文件:新文件自动创建,已有文件覆盖更新
            package.Save();
            MessageBox.Show("File Saved");
        }
    }
    catch (IOException ex)
    {
        MessageBox.Show("文件访问错误:" + ex.Message);
    }
    catch (FileNotFoundException)
    {
        MessageBox.Show("File does not exist.");
    }
    catch (Exception ex)
    {
        MessageBox.Show("未知错误:" + ex.Message);
    }
}

关键修复点说明

  1. 移除重复的FileStream:直接用ExcelPackage传入FileInfo,它会自行处理文件的打开/创建逻辑,避免重复占用文件。
  2. 自动处理文件创建:ExcelPackage构造函数传入FileInfo时,若文件不存在会自动创建空工作簿,无需手动处理文件创建流程。
  3. 修正语法错误:补全PullRecord初始化的{,移除多余嵌套大括号,确保代码结构合法。
  4. 优化异常处理:拆分不同类型的异常,让错误提示更精准。

另外注意:你的方法标记了async但未使用await,如果不需要异步操作可直接去掉async;若要实现异步,需将package.Save()替换为await package.SaveAsync(),同时保留async void(事件处理方法允许此写法)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 08:14:56