OpenXmlSDK 无法读取手动创建的 xlsx 文件:'指定的包无效。主要部分不见了。

Posted

技术标签:

【中文标题】OpenXmlSDK 无法读取手动创建的 xlsx 文件:\'指定的包无效。主要部分不见了。【英文标题】:OpenXmlSDK can't read manualy created xlsx file: 'The specified package is invalid. The main part is missing.'OpenXmlSDK 无法读取手动创建的 xlsx 文件:'指定的包无效。主要部分不见了。 【发布时间】:2019-02-05 16:32:59 【问题描述】:

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

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

失败并出现错误:

DocumentFormat.OpenXml.Packaging.OpenXmlPackageException: '指定的包无效。缺少主要部分。'

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

我也解压缩文件,然后再次压缩它们(不做任何更改),尝试再次调用上面的代码,它可以工作。

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

解决方案

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

【问题讨论】:

【参考方案1】:

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

文档使用或引用未安装的字体(如此处所述: https://github.com/OfficeDev/Open-XML-SDK/issues/561) 无效的文件扩展名(xlsx 除外,如下所述:https://social.msdn.microsoft.com/Forums/office/en-US/6e7e27d4-cd97-46ae-9eca-bfd618dde301/openxml-sdk20-the-specified-package-is-invalid-the-main-part-is-missing?forum=oxmlsdk)

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

如果字体使用不是原因,请尝试在 Open XML Productivity Tool (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 类(例如: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 类打开损坏的 xlsx 文件,并通过复制其内容并将 \ 替换为 / 作为重新创建的条目的名称来重写每个条目。此操作后,生成的文件似乎可以通过SpreadsheetDocument.Open(...) 方法正确打开。

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

【讨论】:

字体不适用,因为重新打包有帮助。 Open XML Productivity Tool 失败:“无法打开文件。不支持指定的文件类型”。我尝试比较原始存档中的文件并使用 Excel 重新保存:在原始文件中,我看到压缩方法 Deflate,在重新保存时 - Deflate:Fastest(根据 7-Zip 应用程序)。尝试将 ZipArchive 中的压缩选项更改为最快没有效果 - 我仍在观看 Deflate 你说得对,我在你原来的问题中没有注意到这一点。我会尝试做更多的研究。 我使用 windows zip 工具重新压缩而不做任何更改,它也有帮助,OpenXmlSDK 打开重新压缩的文件 好像是嵌套条目的命名引起的。我在回答中添加了更多信息。 是的,在该库的代码中将 '\' 替换为 '/' 解决了问题。非常感谢!

以上是关于OpenXmlSDK 无法读取手动创建的 xlsx 文件:'指定的包无效。主要部分不见了。的主要内容,如果未能解决你的问题,请参考以下文章

使用OPEN XML SDK 读取EXCEL中的超链接Hyperlink

无法在python中读取xlsx文件[重复]

使用 OpenPyXL 读取提取的 XLSX 文件

无法将 xlsx.file 读取到数据框 Pandas

C# 创建/修改/读取 .xlsx 文件

无法使用 read_excel 从 pandas 中的 xlsx 文件中读取日期列?