0

我有用户使用 PowerPoint 2016 生成的 PPTX 文件。幻灯片中嵌入了我需要访问以进行进一步处理的 excel 工作表。我在我的项目中使用 Open Xml SDK v2.6.1。

在将嵌入对象流传递给 SpreadsheetDocument 时,使用以下代码:

using (PresentationDocument pd = PresentationDocument.Open(pptxFile, true))
{
  foreach (SlidePart slide in pd.PresentationPart.GetPartsOfType<SlidePart>())
  {
    foreach (EmbeddedObjectPart eoPart in slide.EmbeddedObjectParts)
    {
      using (SpreadsheetDocument sd = SpreadsheetDocument.Open(eoPart.GetStream(), true))
      {
        // do some work with worksheets                                
        var count = sd.WorkbookPart.WorksheetParts.Count();
      }
    }
  }
}

我得到以下异常:

System.IO.FileFormatException: File contains corrupted data.
at System.IO.Packaging.ZipPackage..ctor(Stream s, FileMode packageFileMode, FileAccess packageFileAccess)
at System.IO.Packaging.Package.Open(Stream stream, FileMode packageMode, FileAccess packageAccess)
at DocumentFormat.OpenXml.Packaging.OpenXmlPackage.OpenCore(Stream stream, Boolean readWriteMode)
at DocumentFormat.OpenXml.Packaging.SpreadsheetDocument.Open(Stream stream, Boolean isEditable, OpenSettings openSettings)
at...

当我打开 pptx 包并在嵌入文件夹中将 oleObject1.bin 重命名为 oleObject1.zip,然后在 WinRar 中查看文件信息,我看到它是 SFX Zip 卷而不是 ZipArchive。

我可以让 SpreadsheetDocument 打开嵌入对象流的唯一方法是使用 DotNetZip 库将流转换为 System.IO.Compression.ZipArchive。

所以我有以下问题:

  1. 有没有办法让 Open XML SDK 打开嵌入式 excel 工作表流,而无需显式转码(从 SFX Zip 卷到 Zip 存档)?
  2. 将修改后的流写回演示文档的最佳方法是什么?这很重要,因为工作表数据将被更新并且必须写回主文档。
  3. 有没有另一种更优雅的方法来解决这个问题?

注意:当工作表在演示文稿中使用 OpenXml SDK 以编程方式嵌入时,不会发生此问题。

4

1 回答 1

0

我终于发现,虽然像 WinRar 这样的工具显示嵌入的对象是 SFX zip 卷,但它实际上是一个MS-CFB(复合文件二进制)文件。

您可以通过以下方式使用 CFB 文件:

  1. Windows API:ole32.dll 提供读取和写入 CFB 文件的方法。我发现这篇关于这个主题的优秀文章。
  2. 此页面上有一些有用的资源,它们引用了一些开源选项。

底线,为了处理嵌入在其他办公文档中作为嵌入对象的办公文档,以 MS-CFB 格式保存。需要在 Open XML SDK 之外使用 Win API 或任何其他替代方法读取和写入这些文件。

于 2016-11-28T07:00:39.440 回答