dotnet OpenXML 利用合并表格单元格在 PPT 文档插入不可见的额外版权信息
本文告诉大家如何利用 Office 对于 OpenXML 支持的特性,在 PPT 的表格里面,通过合并单元格存放一些额外的信息,这些信息对用户来说是不可见的,但是进行拷贝表格等的时候,可以保存此信息内容
在开始之前,期望大家已了解很多 OpenXML 知识,详细请看 Office 使用 OpenXML SDK 解析文档博客目录
在 PPT 的表格里面,采用了 RowSpan 用来表示单元格跨行,对应的在下一行的单元格将会被标记 vMerge="1" 表示此单元格被垂直合并。例如我对第一行第一个单元格设置合并单元格,合并行,那么在第二行的第一列的单元格将被标记 vMerge="1" 表示被合并,如下面表格

在 Office 读取 OpenXML 文档,将无视 vMerge="1" 的存在,也就是此属性只是给开发者看的而已,无论是否存在都不会影响到单元格的合并
但事实上,依然可以在标记了 vMerge="1" 的单元格上面添加内容,例如以下有删减的 OpenXML 文档
<a:tbl>
<a:tr h="370840">
<a:tc rowSpan="2">
<a:txBody>
<a:bodyPr />
<a:lstStyle />
<a:p>
<a:r>
<a:rPr lang="en-US" altLang="zh-CN" dirty="0" smtClean="0" />
<a:t>123123</a:t>
</a:r>
<a:endParaRPr lang="zh-CN" altLang="en-US" dirty="0" />
</a:p>
</a:txBody>
<a:tcPr />
</a:tc>
<a:tc></a:tc>
</a:tr>
<a:tr h="370840">
<a:tc vMerge="1">
<a:txBody>
<a:bodyPr />
<a:lstStyle />
<a:p>
<a:r>
<a:rPr lang="en-US" altLang="zh-CN" smtClean="0" />
<a:t>投毒</a:t>
</a:r>
<a:endParaRPr lang="zh-CN" altLang="en-US" />
</a:p>
</a:txBody>
<a:tcPr />
</a:tc>
<a:tc></a:tc>
</a:tr>
</a:tbl>
如上面文档,给了一个单元格写了“投毒”但在 PPT 打开时,是看不到投毒的,如下面界面

以下是此 Office 文档的页面
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<p:sld xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">
<p:cSld>
<p:spTree>
<p:nvGrpSpPr>
<p:cNvPr id="1" name="" />
<p:cNvGrpSpPr />
<p:nvPr />
</p:nvGrpSpPr>
<p:grpSpPr>
<a:xfrm>
<a:off x="0" y="0" />
<a:ext cx="0" cy="0" />
<a:chOff x="0" y="0" />
<a:chExt cx="0" cy="0" />
</a:xfrm>
</p:grpSpPr>
<p:graphicFrame>
<p:nvGraphicFramePr>
<p:cNvPr id="4" name="表格 3" />
<p:cNvGraphicFramePr>
<a:graphicFrameLocks noGrp="1" />
</p:cNvGraphicFramePr>
<p:nvPr />
</p:nvGraphicFramePr>
<p:xfrm>
<a:off x="838200" y="1825625" />
<a:ext cx="8128000" cy="741680" />
</p:xfrm>
<a:graphic>
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/table">
<a:tbl>
<a:tblPr firstRow="1" bandRow="1">
<a:tableStyleId>{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}</a:tableStyleId>
</a:tblPr>
<a:tblGrid>
<a:gridCol w="4064000">
<a:extLst>
<a:ext uri="{9D8B030D-6E8A-4147-A177-3AD203B41FA5}">
<a16:colId xmlns:a16="http://schemas.microsoft.com/office/drawing/2014/main" val="1394598003" />
</a:ext>
</a:extLst>
</a:gridCol>
<a:gridCol w="4064000">
<a:extLst>
<a:ext uri="{9D8B030D-6E8A-4147-A177-3AD203B41FA5}">
<a16:colId xmlns:a16="http://schemas.microsoft.com/office/drawing/2014/main" val="3643799610" />
</a:ext>
</a:extLst>
</a:gridCol>
</a:tblGrid>
<a:tr h="370840">
<a:tc rowSpan="2">
<a:txBody>
<a:bodyPr />
<a:lstStyle />
<a:p>
<a:r>
<a:rPr lang="en-US" altLang="zh-CN" dirty="0" smtClean="0" />
<a:t>123123</a:t>
</a:r>
<a:endParaRPr lang="zh-CN" altLang="en-US" dirty="0" />
</a:p>
</a:txBody>
<a:tcPr />
</a:tc>
<a:tc>
<a:txBody>
<a:bodyPr />
<a:lstStyle />
<a:p>
<a:endParaRPr lang="zh-CN" altLang="en-US" />
</a:p>
</a:txBody>
<a:tcPr />
</a:tc>
<a:extLst>
<a:ext uri="{0D108BD9-81ED-4DB2-BD59-A6C34878D82A}">
<a16:rowId xmlns:a16="http://schemas.microsoft.com/office/drawing/2014/main" val="3287805416" />
</a:ext>
</a:extLst>
</a:tr>
<a:tr h="370840">
<a:tc vMerge="1">
<a:txBody>
<a:bodyPr />
<a:lstStyle />
<a:p>
<a:r>
<a:rPr lang="en-US" altLang="zh-CN" smtClean="0" />
<a:t>投毒</a:t>
</a:r>
<a:endParaRPr lang="zh-CN" altLang="en-US" />
</a:p>
</a:txBody>
<a:tcPr />
</a:tc>
<a:tc>
<a:txBody>
<a:bodyPr />
<a:lstStyle />
<a:p>
<a:endParaRPr lang="zh-CN" altLang="en-US" dirty="0" />
</a:p>
</a:txBody>
<a:tcPr />
</a:tc>
<a:extLst>
<a:ext uri="{0D108BD9-81ED-4DB2-BD59-A6C34878D82A}">
<a16:rowId xmlns:a16="http://schemas.microsoft.com/office/drawing/2014/main" val="3924701140" />
</a:ext>
</a:extLst>
</a:tr>
</a:tbl>
</a:graphicData>
</a:graphic>
</p:graphicFrame>
</p:spTree>
<p:extLst>
<p:ext uri="{BB962C8B-B14F-4D97-AF65-F5344CB8AC3E}">
<p14:creationId xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" val="840519474" />
</p:ext>
</p:extLst>
</p:cSld>
<p:clrMapOvr>
<a:masterClrMapping />
</p:clrMapOvr>
</p:sld>
此时无论是保存还是拷贝表格,都不会丢失 “投毒” 内容。也就是说可以方便的在合并的单元格里面存放一些版权信息,这些版权信息对于用户来说,除非是特意去更改,否则都会放在文档里面
如果忽略合并单元格,通过 WPF 应用读取文档,使用 DataGrid 在界面显示,那么即可拿到合并单元格的内容
var file = new FileInfo("Test.pptx");
using var presentationDocument = PresentationDocument.Open(file.FullName, false);
var slide = presentationDocument.PresentationPart!.SlideParts.First().Slide;
var graphicFrame = slide.CommonSlideData!.ShapeTree!.GetFirstChild<GraphicFrame>()!;
var graphic = graphicFrame.Graphic!;
var graphicData = graphic.GraphicData!;
var table = graphicData.GetFirstChild<Table>()!; // a:tbl
/*
<a:tbl>
<a:tr h="370840">
<a:tc rowSpan="2">
<a:txBody>
<a:bodyPr />
<a:lstStyle />
<a:p>
<a:r>
<a:rPr lang="en-US" altLang="zh-CN" dirty="0" smtClean="0" />
<a:t>123123</a:t>
</a:r>
<a:endParaRPr lang="zh-CN" altLang="en-US" dirty="0" />
</a:p>
</a:txBody>
<a:tcPr />
</a:tc>
<a:tc></a:tc>
</a:tr>
<a:tr h="370840">
<a:tc vMerge="1">
<a:txBody>
<a:bodyPr />
<a:lstStyle />
<a:p>
<a:r>
<a:rPr lang="en-US" altLang="zh-CN" smtClean="0" />
<a:t>投毒</a:t>
</a:r>
<a:endParaRPr lang="zh-CN" altLang="en-US" />
</a:p>
</a:txBody>
<a:tcPr />
</a:tc>
<a:tc></a:tc>
</a:tr>
</a:tbl>
*/
var dataTable = new DataTable();
DataGrid.DataContext = dataTable;
DataGrid.HeadersVisibility = DataGridHeadersVisibility.None;
var n = 0;
foreach (var gridColumn in table.TableGrid!.Elements<GridColumn>())
{
var emu = new Emu(gridColumn.Width?.Value ?? 95250);
DataGrid.Columns.Add(new DataGridTextColumn()
{
Width = emu.ToPixel().Value,
Binding = new Binding(n.ToString())
});
dataTable.Columns.Add(n.ToString());
n++;
}
foreach (var openXmlElement in table)
{
// a:tr 表格的行
if (openXmlElement is TableRow tableRow)
{
var dataRow = dataTable.NewRow();
dataTable.Rows.Add(dataRow);
var index = 0;
foreach (var tableCell in tableRow.Elements<TableCell>())
{
var text = tableCell.TextBody!.InnerText;
dataRow[index.ToString()] = text;
index++;
}
}
}
执行上面代码的界面如下

本文以上的测试文件和代码放在github 和 gitee 欢迎访问
可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin fd6ad246d15db91342476dae7fc841182179726d
以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
获取代码之后,进入 Pptx 文件夹
更多请看 Office 使用 OpenXML SDK 解析文档博客目录
dotnet OpenXML 利用合并表格单元格在 PPT 文档插入不可见的额外版权信息的更多相关文章
- JQuery合并表格单元格
转:http://www.cnblogs.com/xuguoming/p/3412124.html JQuery合并表格单元格 一.需求 如果存在一个表格,想把其中某一列内容相同的部分合并单元格, ...
- java利用Aspose.slides.jar将本地ppt文档转化成pdf(完美破解版 无水印 无中文乱码)
下载aspose.slides-15.9.0.jar包 http://pan.baidu.com/s/1jH3ZNbK JAVA代码 package webViewer; import java.io ...
- C# 利用Aspose.Slides.dll将本地ppt文档转化成pdf(完美破解版 无水印 无中文乱码)
下载Aspose.Slides.dll http://pan.baidu.com/s/1kVPjnzL 添加引用C#代码. using System; using System.Collectio ...
- 黄聪:phpexcel中文教程-设置表格字体颜色背景样式、数据格式、对齐方式、添加图片、批注、文字块、合并拆分单元格、单元格密码保护
首先到phpexcel官网上下载最新的phpexcel类,下周解压缩一个classes文件夹,里面包含了PHPExcel.php和PHPExcel的文件夹,这个类文件和文件夹是我们需要的,把class ...
- phpexcel中文教程-设置表格字体颜色背景样式、数据格式、对齐方式、添加图片、批注、文字块、合并拆分单元格、单元格密码保护
转:http://www.cnblogs.com/huangcong/p/3687665.html 首先到phpexcel官网上下载最新的phpexcel类,下周解压缩一个classes文件夹,里面包 ...
- PHPExcel-设置表格字体颜色背景样式、数据格式、对齐方式、添加图片、批注、文字块、合并拆分单元格、单元格密码保护
首先到phpexcel官网上下载最新的phpexcel类,下周解压缩一个classes文件夹,里面包含了PHPExcel.php和PHPExcel的文件夹,这个类文件和文件夹是我们需要的,把class ...
- 利用jxl读取excel合并的单元格的一个小样例
工作中我们可能要把Excel文件的记录保存到数据库, 今天我用jxl读取Excel文件时遇到了合并格的问题,记录例如以下: 如Excel文件例如以下: watermark/2/text/aHR0cDo ...
- 关于.net Microsoft.Office.Interop.Word组建操作word的问题,如何控制word表格单元格内部段落的样式。
控制word表格单元格内部文字样式.我要将数据导出到word当中,对于word表格一个单元格中的一段文字,要设置不同的样式,比如第一行文字作为标题要居中,加粗,第二行为正常的正文. 代码如下 publ ...
- 关于html表格单元格宽度的计算规则
* { margin: 0; padding: 0 } body { background: #fafafa } ul,li { list-style: none } h1 { margin: 20p ...
- javascript生成表格增删改查 JavaScript动态改变表格单元格内容 动态生成表格 JS获取表格任意单元格 javascript如何动态删除表格某一行
jsp页面表格布局Html代码 <body onload="show()"> <center> <input type="text" ...
随机推荐
- 记录--工程化第一步这个package.json要真的搞明白才行
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 工程化最开始就是package.json开始的,很多人学了很多年也没搞清楚这个为什么这么神奇,其实有些字段是在特定场景才有效的,那每个属性 ...
- 记录--vue中封装一个右键菜单组件(复制粘贴即可使用)
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 组件介绍 关于web端的右键功能常用的地方有表格的右键,或者tab标签的右键等,本文记录一下封装一个右键菜单组件的思路步骤代码. 程序员除 ...
- WPF MVVM 集合内容更改时如何添加操作,触发通知
用过mvvm设计WFP程序的人都知道,在我们mvvm中有一个非常重要的接口叫做 INotifyPropertyChanged 这个接口的主要作用是用于触发属性更改时向我们xaml中绑定此属性值的控件发 ...
- 神经网络——基于sklearn的参数介绍及应用
一.MLPClassifier&MLPRegressor参数和方法 参数说明(分类和回归参数一致): hidden_layer_sizes :例如hidden_layer_sizes=(50, ...
- 阿里二面:Java中锁的分类有哪些?你能说全吗?
引言 在多线程并发编程场景中,锁作为一种至关重要的同步工具,承担着协调多个线程对共享资源访问秩序的任务.其核心作用在于确保在特定时间段内,仅有一个线程能够对资源进行访问或修改操作,从而有效地保护数据的 ...
- 程序员/后端开发方向Java 跳槽注意事项(简历和面试经验分享)
程序员/后端开发方向Java 跳槽注意事项(简历和面试经验分享) 应届生面试经验参考:https://www.cnblogs.com/rainbow-1/p/16779048.html 简历: 1.个 ...
- .NET Emit 入门教程:第六部分:IL 指令:3:详解 ILGenerator 指令方法:参数加载指令
前言: 在上一篇中,我们介绍了 ILGenerator 辅助方法. 本篇,将详细介绍指令方法,并详细介绍指令的相关用法. 在接下来的教程,关于IL指令部分,会将指令分为以下几个分类进行讲解: 1.参数 ...
- 动图演示步骤 Vmware安装Centos-7 最小安装/图形化界面及常见错误参考,基础配置推荐
程序软件工具安装篇 --[Linux](Vmware/Centos-7) 目录 程序软件工具安装篇 --[Linux](Vmware/Centos-7) ①:文件准备工作 虚拟机工具安装文件 系统镜像 ...
- 驾驭数据的能力,如同使用ChatGPT一样,是现代职场人的必修课
现代职场所比拼的除了聪明才智.过往经验之外,很多软性技能也尤为重要. 现在已经不是像网络游戏开局拿着一根小木棍打天下的时代了,这将是一场武装到牙齿的较量,对于各类"装备"的驾驭能力 ...
- 【FAQ】HarmonyOS SDK 闭源开放能力 —IAP Kit
1.问题描述 根据https://developer.huawei.com/consumer/cn/doc/harmonyos-references/iap-data-model-0000001736 ...