学习C#调用OpenXml操作word文档的基本用法(21:学习嵌入对象类)

  OpenXml中使用EmbeddedObjectPart类处理Word文档内嵌入的OLE对象,MainDocumentPart类的EmbeddedObjectParts属性保存所有的OLE对象。以下图为例,向上一篇文章中的word文档中粘贴mp3文件和xml文件,采用解压缩软件打开Word文档,其内的embeddings文件夹中圈红处保存后续插入的两个文件的OLE对象数据,而media文件夹内圈红处则保存每个OLE对象在word文档中的显示图标。


  MainDocumentPart类的EmbeddedObjectParts属性保存OLE对象集合,其类型为IEnumerable <EmbeddedObjectPart>,EmbeddedObjectPart类存储OLE对象数据,命名空间为DocumentFormat. OpenXml. Packaging。
  EmbeddedObjectPart类的RelationshipType属性为固定字符串,值为"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject",ContentType属性保存内容类型,通过Uri属性可以获取ole对象文件的路径及文件名,不过对于OLE对象而言,ContentType的值大部分都是相同的,不像EmbeddedPackagePart类的ContentType值区别较大。下面的代码及截图用于获取word文档的ole对象列表(追加到前一篇文章的嵌入文件列表内)。

csharp 复制代码
if (mainPart.EmbeddedObjectParts != null)
{
    foreach (EmbeddedObjectPart objectPart in mainPart.EmbeddedObjectParts)
    {
        ListViewItem item = new ListViewItem(Convert.ToString(lstPackages.Items.Count + 1));
        item.SubItems.Add(mainPart.GetIdOfPart(objectPart));
        item.SubItems.Add(objectPart.ContentType);
        item.SubItems.Add(objectPart.Uri.IsAbsoluteUri ? objectPart.Uri.AbsoluteUri : objectPart.Uri.OriginalString);

        lstPackages.Items.Add(item);        
    }
}


  通过调用EmbeddedObjectPart类的GetStream函数可以获取文件流,可以将其保存到本地或另做他用,不过文件都是以bin为后缀的ole文件,需要进一步解析文件内容以确定具体的文件类型。示例代码如下所示:

csharp 复制代码
EmbeddedObjectPart oPart=FindOlePart( mainPart.EmbeddedObjectParts);
string ext = System.IO.Path.GetExtension(oPart.Uri.OriginalString);
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = $"{ext} files|*.{ext}";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
    using (Stream embeddedStream = oPart.GetStream())
    {
        // 将流写入新文件
        using (FileStream fileStream = new FileStream(saveFileDialog.FileName, FileMode.Create))
        {
            embeddedStream.CopyTo(fileStream);
        }
    }
}

  EmbeddedPackagePart类和EmbeddedObjectPart类的功能和定位都类似,前者专用于嵌入另一个OpenXML格式的文档,是一个完整的、压缩的OpenXML包,内部结构与主文档相同,而后者则是一个通用容器,嵌入的可以是早期二进制格式(如 .xls)、图表、媒体文件等,数据组织方式各异。通过大模型给出这两者的区别以供参考:

参考文献

1https://github.com/dotnet/Open-XML-SDK

2https://learn.microsoft.com/zh-cn/office/open-xml/open-xml-sdk

3https://learn.microsoft.com/zh-cn/dotnet/api/documentformat.openxml.wordprocessing.style?view=openxml-3.0.1

4https://blog.csdn.net/i042416/article/details/126228816

相关推荐
c#上位机1 小时前
C#上位机项目实战——Task.Run执行带参数的方法
c#·上位机
Lost of 程序猿7 小时前
用 YARP 为 .NET 微服务搭一座“立交桥“:路由转发与生产配置实践
c#·asp.net
点纭10 小时前
C 语言 第七章 常用函数(3)
c语言·开发语言·算法·oracle·c#
用户7884773163411 小时前
用 .NET MAUI 一套 C# 同时出 Windows 和 Android:哪些是真能共享,哪些是 marketing
c#
Lost of 程序猿12 小时前
用 Quartz.NET 优雅地处理 .NET 定时任务:从选型到 Docker 部署全记录
后端·c#·asp.net
林川~011 天前
Unity 万能物理检测工具:射线检测 / 范围检测 / 层级过滤 / 编辑器可视化(可直接拿去用)
游戏·unity·c#·射线检测·通用工具
He BianGu1 天前
【WPF-VisionMaster】机器视觉通用平台V5.0版本发行说明
opencv·c#·wpf·halcon·机器视觉·visionmaster
tang_04271 天前
【Hi.Ltd 专题】第9期:Interop 配置互操作(JSON/INI/XML/YAML/注册表/扫码)
经验分享·c#·hi.ltd系列
tang_04271 天前
【Hi.Ltd 专题】第7期:Threading 采集线程、锁与 LRU 缓存
经验分享·c#·hi.ltd系列
A_nanda1 天前
C# 界面卡顿:从定位到根治
c#