OpenXmlSDK 无法读取手动创建的 xlsx 文件:'The specified package is invalid. The main part is missing.'

OpenXmlSDK can't read manualy created xlsx file: 'The specified package is invalid. The main part is missing.'

我有一个创建 xlsx 文件的第三方库。它不使用 OpenXmlSDK,它结合了来自 xml-标记片段的文件。对于压缩,使用 ZipArchive class。 但是当我尝试使用 OpenXmlSDK

var document = SpreadsheetDocument.Open(fileStream, false);

失败并出现错误:

DocumentFormat.OpenXml.Packaging.OpenXmlPackageException: 'The specified package is invalid. The main part is missing.'

MS Excel 正常打开此文件。从 Excel 重新保存有帮助。

另外我解压缩文件,然后再次压缩它们(没有任何更改),尝试再次调用上面的代码并且它有效。

问题出在哪里?如何为 OpenXmlSDK 压缩 xlsx 文件?

解决方案

第三方库保存文件时出现问题。包含在 zip 中的文件的条目名称为 \ 而不是 /。该库的代码已被编辑以修复该问题,一切正常。

经过一些研究,我发现人们在两种情况下抱怨这个异常:

由于您从流中打开文件,因此第二个原因在这种情况下不适用。

如果字体使用不是原因,请尝试在打开 XML 生产力工具 (https://www.microsoft.com/en-us/download/details.aspx?id=30425) 中使用 Excel 手动比较保存前后的文件版本。

如果文档内容没有差异,请尝试比较存档压缩设置。

更新

我似乎找到了有关此问题的更多信息,可以帮助找到解决方案。

我能够重现 缺少主要部分。 通过创建存档的错误:ZipFile.CreateFromDirectory(@"C:\DirToCompress", destFilePath, CompressionLevel.Fastest, false);

然后,我检查了用 Package.Open(destFilePath, FileMode.Open, FileAccess.Read) 打开文件实际上列出了在文件中找到的 0 个部分。

验证一些差异后,我注意到在正确的 xlsx 文件中,嵌套在存档文件夹中的条目具有使用 / 字符表示的 FullName 路径,例如:_rels/.rels .在损坏的文件中,名称以 \ 字符书写,例如:_rels\.rels。 您可以通过使用 ZipArchive class(例如:new ZipArchive(archiveStream, ZipArchiveMode.Read, false, UTF8Encoding.UTF8);)打开文件并检查 Entries 集合来调查它。

需要注意的重要一点是,Office Open XML 规范中描述的部分有命名规则:https://www.ecma-international.org/news/TC45_current_work/Office%20Open%20XML%20Part%202%20-%20Open%20Packaging%20Conventions.pdf

作为测试,我编写了一段代码,使用 ZipArchive class 打开损坏的 xlsx 文件,并通过复制其内容并将 \ 替换为 / 来重写每个条目] 作为重新创建条目的名称。执行此操作后,生成的文件似乎可以通过 SpreadsheetDocument.Open(...) 方法正确打开。

请注意,我使用的名称固定方法非常简单,在某些情况下可能不够用或无法正常工作。但是,这些说明可能有助于找到所需的问题解决方案。