关于c#:使用NPOI有问题的.xlsx文件损坏 – Excel无法打开文件’file.xlsx’,因为文件格式或文件扩展名无效

Problematic corruption of .xlsx files with NPOI - Excel cannot open the file 'file.xlsx" because the file format or file extension is not valid

在读取或修改某些用户创建的.xlsx文件时,我收到以下错误消息:

1
We found a problem with some content in 'test.xlsx'. Do you want us to try to recover as much as we can? If you trust the source of this workbook, click Yes.

单击"是"会收到另一条消息:

1
Excel cannot open the file 'test.xlsx' because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file.

这里是一个有问题的.xlsx文件的例子(在放入npoi之前)。

这是同一个文件,在这里被iWorkbook.Write(filestream);读取和写回后,文件已经损坏。

使用以下代码创建新的.xlsx文件没有问题:

2

那很好。

即使打开一个有问题的子.xlsx文件,将其设置为iWorkbook并将其写回该文件也可以:

1
2
3
4
5
6
7
8
string newPath = @"C:\MyPath\test.xlsx";

using (FileStream fs = new FileStream(newPath, FileMode.Open, FileAccess.ReadWrite))
{
    IWorkbook wb = new XSSFWorkbook(fs);
    wb.Write(fs);
    fs.Close();
}

但是,在运行了从中读取的代码之后,会得到isheets、irows、icells等。它会损坏.xlsx文件。即使我特别删除了修改工作簿的任何内容。不使用NPOI创建、设置、样式等。

我不能真的包含我的代码,因为它只是令人困惑,但是为了完整性,我在这个测试中实际上只使用了来自NPOI的以下类型和函数:

1
2
3
4
5
6
7
8
9
IWorkbook
XSSFWorkbook
ISheet
IRow
ICell
.GetSheetAt
.GetRow
.GetCell
.LastRowNum

所以其中一个导致了腐败。我希望最终能再次设置值,使其像.xls一样工作。

有人经历过吗?哪些NPOI功能可能导致腐败?如有任何意见,我们将不胜感激。

编辑:使用NPOI v2.2.1。


我认为问题是你读的和写的都是同一个FileStream。您应该使用单独的流进行读写。尝试如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
string newPath = @"C:\MyPath\test.xlsx";

// read the workbook
IWorkbook wb;
using (FileStream fs = new FileStream(newPath, FileMode.Open, FileAccess.Read))
{
    wb = new XSSFWorkbook(fs);
}

// make changes
ISheet s = wb.GetSheetAt(0);
IRow r = s.GetRow(0) ?? s.CreateRow(0);
ICell c = r.GetCell(1) ?? r.CreateCell(1);
c.SetCellValue("test2");

// overwrite the workbook using a new stream
using (FileStream fs = new FileStream(newPath, FileMode.Create, FileAccess.Write))
{
    wb.Write(fs);
}


我也有同样的问题。在我的例子中,问题不在于NPOI本身,而在于它的依赖关系sharpziplib。

我使用了NPOI 2.3.0和SharpZiplib 1.0.0。它的错误与你的情况相同。生成的Excel大小为0字节。在我使用NPOI(一个服务层)的项目和MVC项目(我在这里也有sharpziplib包)中,我将sharpziplib降级为0.86.0。

我还手动删除了web.config中以前为sharpziplib创建的程序集依赖项:

1
2
3
4
5
6
  .......
  <dependentAssembly>
   
    <bindingRedirect oldVersion="0.0.0.0-1.0.0.999" newVersion="1.0.0.999" />
  </dependentAssembly>
</assemblyBinding>

我希望这能帮助别人。