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

C#使用NPOI创建/追加.xlsx文件报错、文件损坏问题咨询

C# NPOI操作.xlsx文件异常解决方案

问题现象

  • 基于NPOI开发.xlsx文件写入逻辑时,初期测试抛出MissingMethod异常,尝试删除packages文件夹、重载全部NuGet包等常规方案后问题未解决
  • 代码运行后目标路径会生成指定文件,但文件大小为0字节;偶发无显式报错的场景下,生成的文件也处于损坏状态,Excel打开时提示文件错误,仅能通过修复功能恢复部分数据
  • 当前运行抛出明确异常,核心日志提示无法加载ICSharpCode.SharpZipLib程序集

涉及的业务代码如下:

public void WriteExcel()
{
    System.IO.Directory.CreateDirectory(workingDirectory + @"\Excel");
    var newFile = workingDirectory + @"\Excel\data.xlsx";

    try
    {
        if (Directory.Exists(workingDirectory + @"\Excel"))
        {
            if (!File.Exists(newFile))
            {
                using (var fs = new FileStream(newFile, FileMode.Create, FileAccess.Write))
                {
                    IWorkbook workbook = new XSSFWorkbook();
                    ISheet sheet = workbook.CreateSheet("Data");
                    IRow row = sheet.CreateRow(0);
                    ICell cell1 = row.CreateCell(0);
                    ICell cell2 = row.CreateCell(1);
                    ICell cell3 = row.CreateCell(2);
                    cell1.SetCellValue("Date");
                    cell2.SetCellValue("Value1");
                    cell3.SetCellValue("Value2");

                    for (int i = 0; i <= 20; i++) sheet.AutoSizeColumn(i);

                    workbook.Write(fs);
                }

                Console.WriteLine("File is created");
            }
            else
            {
                IWorkbook workbook;

                using (var outs = new FileStream(newFile, FileMode.Open, FileAccess.Read))
                {
                    workbook = new XSSFWorkbook(outs);
                    outs.Close();
                    Console.WriteLine("Workbook read");
                }

                ISheet sheet = workbook.GetSheetAt(0);
                IRow row = sheet.CreateRow(sheet.LastRowNum+1);
                ICell cell1 = row.CreateCell(0);
                ICell cell2 = row.CreateCell(1);
                ICell cell3 = row.CreateCell(2);
                cell1.SetCellValue(DateTime.Today.Date.ToString("yyyy-MM-dd"));
                cell2.SetCellValue("Some value");
                cell3.SetCellValue("some value 2");
                Console.WriteLine("Values set");

                using (var ins = new FileStream(newFile, FileMode.Open, FileAccess.Write))
                {
                    workbook.Write(ins);
                    ins.Close();
                    Console.WriteLine("Workbook saved");

                }
            }
        }
        else
        {
            // 目录创建失败逻辑预留
        }
    }
    catch (Exception e) { Console.WriteLine(e); }
}

异常日志原文:

Exception thrown: 'System.IO.FileNotFoundException' in NPOI.OpenXml4Net.dll
Exception thrown: 'NPOI.POIXMLException' in NPOI.OOXML.dll
System.IO.FileNotFoundException: Det går inte att läsa in filen eller sammansättningen ICSharpCode.SharpZipLib

日志中瑞典语段含义为:无法加载文件或程序集ICSharpCode.SharpZipLib

根因分析

  1. 直接触发报错的原因:NPOI处理.xlsx(OOXML格式)文件时,强依赖ICSharpCode.SharpZipLib完成OpenXML包的压缩、解压操作。当前项目中该依赖要么未安装,要么安装的版本和NPOI版本不匹配,或生成时未将该dll拷贝到输出目录,直接触发FileNotFoundException,后续连锁抛出POIXMLException,导致文件写入中断出现0字节、损坏问题。最开始出现的MissingMethod异常,本质也是依赖版本冲突导致的方法签名不匹配。
  2. 代码本身存在两个会导致文件损坏的逻辑缺陷:
    • 追加写入已有Excel文件时,保存文件使用FileMode.Open模式打开写流,该模式不会清空原有文件内容,新写入的字节和旧文件内容叠加会直接破坏xlsx的压缩包结构
    • 新建文件时遍历0-20列做自动列宽,但实际仅初始化了前3列的单元格,部分NPOI版本处理未创建单元格的空列自动列宽逻辑时会抛出空引用异常
    • using块会在代码执行离开块作用域时自动释放流资源,手动调用Close()存在流提前释放、写入内容不完整的风险

修复步骤

  1. 修复依赖问题
    • 打开NuGet包管理器,搜索安装SharpZipLib包,注意版本匹配:NPOI 2.5.x及以上版本对应SharpZipLib 1.3.0及以上版本;NPOI 2.4及以下老版本对应SharpZipLib 0.86版本。
    • 安装完成后执行项目清理,再重新生成,确认项目输出目录下存在ICSharpCode.SharpZipLib.dll文件。
  2. 修正代码逻辑
    • 调整自动列宽的循环范围,仅对实际创建了单元格的列执行自动调整
    • 保存已有工作簿时,将写文件流的打开模式改为FileMode.Create,写入前清空旧文件内容避免结构损坏
    • 去掉using块内冗余的手动流Close调用

核心修正点参考:

// 新建文件时的自动列宽逻辑修正
for (int i = 0; i < 3; i++) sheet.AutoSizeColumn(i);

// 读取已有工作簿的逻辑去掉冗余Close
using (var outs = new FileStream(newFile, FileMode.Open, FileAccess.Read))
{
    workbook = new XSSFWorkbook(outs);
    Console.WriteLine("Workbook read");
}

// 保存工作簿的流模式修正
using (var ins = new FileStream(newFile, FileMode.Create, FileAccess.Write))
{
    workbook.Write(ins);
    Console.WriteLine("Workbook saved");
}
  1. 验证:重新运行程序,确认生成的xlsx文件大小不为0,可直接通过Excel正常打开,无修复提示即为修复完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:57:19