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" ...
随机推荐
- AsyncTask异步任务类
目录介绍 01.先看下AsyncTask用法 02.AsyncTask源码深入分析 2.1 构造方法源码分析 2.2 看execute(Params... params)方法 2.3 mWorker和 ...
- 深度解读UUID:结构、原理以及生成机制
What 是 UUID UUID (Universally Unique IDentifier) 通用唯一识别码 ,也称为 GUID (Globally Unique IDentifier) 全球唯一 ...
- 记录--Vue 右键菜单的秘密:自适应位置的实现方法
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 下图这个情景,你是否也遇到过? 当你右键点击网页上的某个元素时,弹出的菜单被屏幕边缘遮挡了,导致你无法看清或选择菜单项? 上图中右键菜单的 ...
- Python 如何发送带Excel附件的邮件
import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart f ...
- java读写txt
/** * 传入txt路径读取txt文件 * * @param txtPath * @return 返回读取到的内容 */ public String readTxt(String txtPath) ...
- ATSS : 目标检测的自适应正负anchor选择,很扎实的trick | CVPR 2020
论文指出one-stage anchor-based和center-based anchor-free检测算法间的差异主要来自于正负样本的选择,基于此提出ATSS(Adaptive Training ...
- Scala 中断循环
一.采用 Scala 自带的函数,退出循环 1 package com.atguigu.break 2 3 object TestBreak { 4 import scala.util.control ...
- #SPFA#洛谷 2384 最短路
题目 给定\(n\)个点的带权有向图,求从\(1\)到\(n\)的路径中边权之积最小的简单路径. 答案对9987取模 分析 此题设了陷阱,如果一边取模一边跑最短路即使最终答案最小也不一定是未取模前的最 ...
- OpenHarmony嵌套类对象属性变化:@Observed装饰器和@ObjectLink装饰器
上文所述的装饰器仅能观察到第一层的变化,但是在实际应用开发中,应用会根据开发需要,封装自己的数据模型.对于多层嵌套的情况,比如二维数组,或者数组项class,或者class的属性是class,他们的第 ...
- 玩转OpenHarmony智能家居:如何实现树莓派“碰一碰”设备控制
一.简介 "碰一碰"设备控制,依托NFC短距通信协议,通过碰一碰的交互方式,将OpenAtom OpenHarmony(简称"OpenHarmony")标准系统 ...