OpenXmlSDK无法读取手动创建的xlsx文件:'指定的程序包无效。主要部分缺失。

时间:2019-02-05 16:32:59

标签: c# openxml-sdk

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

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

它失败并出现错误:

  

DocumentFormat.OpenXml.Packaging.OpenXmlPackageException:'指定的程序包无效。主要部分丢失了。'

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

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

问题出在哪里?如何压缩可用于OpenXmlSDK的xlsx文件?

解决方案

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

1 个答案:

答案 0 :(得分:1)

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

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

如果不是字体使用的原因,请尝试在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(...)方法正确打开生成的文件。

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