當(dāng)前位置:首頁(yè) > IT技術(shù) > Web編程 > 正文

dotnet OpenXML 利用合并表格單元格在 PPT 文檔插入不可見(jiàn)的額外版權(quán)信息
2021-09-10 18:12:00

本文告訴大家如何利用 Office 對(duì)于 OpenXML 支持的特性,在 PPT 的表格里面,通過(guò)合并單元格存放一些額外的信息,這些信息對(duì)用戶來(lái)說(shuō)是不可見(jiàn)的,但是進(jìn)行拷貝表格等的時(shí)候,可以保存此信息內(nèi)容

在開(kāi)始之前,期望大家已了解很多 OpenXML 知識(shí),詳細(xì)請(qǐng)看 Office 使用 OpenXML SDK 解析文檔博客目錄

在 PPT 的表格里面,采用了 RowSpan 用來(lái)表示單元格跨行,對(duì)應(yīng)的在下一行的單元格將會(huì)被標(biāo)記 vMerge="1" 表示此單元格被垂直合并。例如我對(duì)第一行第一個(gè)單元格設(shè)置合并單元格,合并行,那么在第二行的第一列的單元格將被標(biāo)記 vMerge="1" 表示被合并,如下面表格

dotnet OpenXML 利用合并表格單元格在 PPT 文檔插入不可見(jiàn)的額外版權(quán)信息_git

在 Office 讀取 OpenXML 文檔,將無(wú)視 vMerge="1" 的存在,也就是此屬性只是給開(kāi)發(fā)者看的而已,無(wú)論是否存在都不會(huì)影響到單元格的合并

但事實(shí)上,依然可以在標(biāo)記了 vMerge="1" 的單元格上面添加內(nèi)容,例如以下有刪減的 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>

如上面文檔,給了一個(gè)單元格寫(xiě)了“投毒”但在 PPT 打開(kāi)時(shí),是看不到投毒的,如下面界面

dotnet OpenXML 利用合并表格單元格在 PPT 文檔插入不可見(jiàn)的額外版權(quán)信息_openxml_02

以下是此 Office 文檔的頁(yè)面

<?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>

此時(shí)無(wú)論是保存還是拷貝表格,都不會(huì)丟失 “投毒” 內(nèi)容。也就是說(shuō)可以方便的在合并的單元格里面存放一些版權(quán)信息,這些版權(quán)信息對(duì)于用戶來(lái)說(shuō),除非是特意去更改,否則都會(huì)放在文檔里面

如果忽略合并單元格,通過(guò) WPF 應(yīng)用讀取文檔,使用 DataGrid 在界面顯示,那么即可拿到合并單元格的內(nèi)容

            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++;
                    }
                }
            }

執(zhí)行上面代碼的界面如下

dotnet OpenXML 利用合并表格單元格在 PPT 文檔插入不可見(jiàn)的額外版權(quán)信息_wpf_03

本文以上的測(cè)試文件和代碼放在githubgitee 歡迎訪問(wèn)

可以通過(guò)如下方式獲取本文的源代碼,先創(chuàng)建一個(gè)空文件夾,接著使用命令行 cd 命令進(jìn)入此空文件夾,在命令行里面輸入以下代碼,即可獲取到本文的代碼

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin fd6ad246d15db91342476dae7fc841182179726d

以上使用的是 gitee 的源,如果 gitee 不能訪問(wèn),請(qǐng)?zhí)鎿Q為 github 的源

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git

獲取代碼之后,進(jìn)入 Pptx 文件夾

?

dotnet OpenXML 利用合并表格單元格在 PPT 文檔插入不可見(jiàn)的額外版權(quán)信息_openxml_04
本作品采用知識(shí)共享署名-非商業(yè)性使用-相同方式共享 4.0 國(guó)際許可協(xié)議進(jìn)行許可。歡迎轉(zhuǎn)載、使用、重新發(fā)布,但務(wù)必保留文章署名林德熙(包含鏈接:不得用于商業(yè)目的,基于本文修改后的作品務(wù)必以相同的許可發(fā)布。如有任何疑問(wèn),請(qǐng)與我

本文摘自 :https://blog.51cto.com/u

開(kāi)通會(huì)員,享受整站包年服務(wù)立即開(kāi)通 >