dotnet OpenXML 解析 WPS 不符合压缩文档规范的文档

我遇到了有老师给我反馈说用我的小工具去辅助编辑课件的时候,遇到了他使用 WPS 制作的文档打开失败,原因是 WPS 制作的一些文档不符合压缩文档规范。而 Office 的基于 ECMA 376 的文档,都是使用标准的 ZIP 压缩规范的文档,因此对于这些不符合压缩文档规范的文件,将会解析失败

如果使用了不符合压缩规范的文件,那么在使用 OpenXML SDK 读取的时候,将会在解压缩的时候炸掉,如下

System.IO.FileFormatException:“File contains corrupted data.”
此异常最初是在此调用堆栈中引发的: 
  System.IO.Packaging.ZipPackage.ZipPackage(System.IO.Stream, System.IO.FileMode, System.IO.FileAccess)
  System.IO.Packaging.Package.Open(System.IO.Stream, System.IO.FileMode, System.IO.FileAccess)
  DocumentFormat.OpenXml.Packaging.OpenXmlPackage.OpenCore(System.IO.Stream, bool)
  DocumentFormat.OpenXml.Packaging.PresentationDocument.Open(System.IO.Stream, bool, DocumentFormat.OpenXml.Packaging.OpenSettings)
  DocumentFormat.OpenXml.Packaging.PresentationDocument.Open(System.IO.Stream, bool)  

或者下面提示

//如果是 InvalidDataException 才是 WPS 的诡异格式,此时才能使用此方法解决
System.IO.InvalidDataException	End of Central Directory record could not be found.	

at System.IO.Compression.ZipArchive.ReadEndOfCentralDirectory()
at System.IO.Compression.ZipArchive.Init(Stream stream, ZipArchiveMode mode, Boolean leaveOpen)
at System.IO.Compression.ZipArchive..ctor(Stream stream, ZipArchiveMode mode, Boolean leaveOpen, Encoding entryNameEncoding)
at System.IO.Packaging.ZipPackage..ctor(String path, FileMode packageFileMode, FileAccess packageFileAccess, FileShare share)
at System.IO.Packaging.Package.Open(String path, FileMode packageMode, FileAccess packageAccess, FileShare packageShare)
at DocumentFormat.OpenXml.Packaging.OpenXmlPackage.OpenCore(String path, Boolean readWriteMode)
at DocumentFormat.OpenXml.Packaging.PresentationDocument.Open(String path, Boolean isEditable, OpenSettings openSettings)
at DocumentFormat.OpenXml.Packaging.PresentationDocument.Open(String path, Boolean isEditable)

在读取到 System.IO.InvalidDataException End of Central Directory record could not be found. 就是因为压缩文档不符合规范,或者文件损坏

而给我反馈的老师的课件其实只是压缩文档不符合规范,我使用 Office 2016 打开,此时会提示文档损坏

当然了,点击修复还是能打开课件的

但是我的工具无法通过 OpenXML SDK 读取

解决方法就是先使用其他压缩库进行解压缩和压缩,这样的文件就符合压缩规范了

如使用 DotNetZip 进行解压缩,在 csproj 上添加下面代码,用来安装 DotNetZip 这个 NuGet 库。当然了,使用 NuGet 安装也可以

    <PackageReference Include="DotNetZip" Version="1.15.0" />

接下来使用下面代码进行解压缩,然后压缩

            var folder = tempFolder;

            using (var zipFile = Ionic.Zip.ZipFile.Read(file))
            {
                zipFile.ExtractAll(folder);
            }

            // 重新压缩回
            System.IO.Compression.ZipFile.CreateFromDirectory(folder, newZipFile);

这样文件就符合压缩规范了,以上代码特别使用运行时提供的压缩方法

本文的代码放在 github 欢迎小伙伴访问

更多请看 Office 使用 OpenXML SDK 解析文档博客目录

我搭建了自己的博客 https://blog.lindexi.com/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新

如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入

如有不方便在博客评论的问题,可以加我 QQ 2844808902 交流

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

lindexi_gd CSDN认证博客专家 C# WPF UWP 微软最具价值专家
我是微软Windows应用开发方向的最具价值专家,欢迎访问我博客blog.lindexi.com里面有大量WPF和UWP博客
已标记关键词 清除标记
【为什么还需要学习C++?】 你是否接触很多语言,但从来没有了解过编程语言的本质? 你是否想成为一名资深开发人员,想开发别人做不了的高性能程序? 你是否经常想要窥探大型企业级开发工程的思路,但苦于没有基础只能望洋兴叹?   那么C++就是你个人能力提升,职业之路进阶的不二之选。 【课程特色】 1.课程共19大章节,239课时内容,涵盖数据结构、函数、类、指针、标准库全部知识体系。 2.带你从知识与思想的层面从0构建C++知识框架,分析大型项目实践思路,为你打下坚实的基础。 3.李宁老师结合4大国外顶级C++著作的精华为大家推出的《征服C++11》课程。 【学完后我将达到什么水平?】 1.对C++的各个知识能够熟练配置、开发、部署; 2.吊打一切关于C++的笔试面试题; 3.面向物联网的“嵌入式”和面向大型化的“分布式”开发,掌握职业钥匙,把握行业先机。 【面向人群】 1.希望一站式快速入门的C++初学者; 2.希望快速学习 C++、掌握编程要义、修炼内功的开发者; 3.有志于挑战更高级的开发项目,成为资深开发的工程师。 【课程设计】 本课程包含3大模块 基础篇 本篇主要讲解c++的基础概念,包含数据类型、运算符等基本语法,数组、指针、字符串等基本词法,循环、函数、类等基本句法等。 进阶篇 本篇主要讲解编程中常用的一些技能,包含类的高级技术、类的继承、编译链接和命名空间等。 提升篇: 本篇可以帮助学员更加高效的进行c++开发,其中包含类型转换、文件操作、异常处理、代码重用等内容。
©️2020 CSDN 皮肤主题: 终极编程指南 设计师:CSDN官方博客 返回首页