专栏首页林德熙的博客dotnet OpenXML 读取形状轮廓线条样式序号超过主题样式列表数

dotnet OpenXML 读取形状轮廓线条样式序号超过主题样式列表数

在 OpenXML 中,默认的形状可以通过指定 LineReference 让形状使用文档主题里面的样式。文档主题里面包含多个样式,在形状里面指定样式通过的是序号的方法,如果在形状里面指定的序号超过了主题的数量,那么将会使用最后一项样式

开始之前,我准备了这份课件,我将课件和代码都放在 GitHub 上可以在本文最后找到链接

在这份课件中,第一页里面有一个形状元素,在形状元素里面定义了样式使用的是第 5 个样式

<p:sp>
 <p:style>
   <a:lnRef idx="5">
     <a:schemeClr val="accent1">
       <a:shade val="50000" />
     </a:schemeClr>
   </a:lnRef>
 </p:style>
</p:sp>

使用 C# dotnet 使用 OpenXml 解析 PPT 文件 博客的方法打开这份课件,可以使用如下代码读取到使用的 LineReference 样式

            using (var presentationDocument =
                DocumentFormat.OpenXml.Packaging.PresentationDocument.Open("测试.pptx", false))
            {
                var presentationPart = presentationDocument.PresentationPart;
                var slidePart = presentationPart.SlideParts.First();
                var shape = slidePart.Slide.Descendants<Shape>().First();
                var lineReference = shape.Descendants<LineReference>().First();
                /*
       <p:sp>
        <p:style>
          <a:lnRef idx="5">
            <a:schemeClr val="accent1">
              <a:shade val="50000" />
            </a:schemeClr>
          </a:lnRef>
        </p:style>
       </p:sp>
                */
                var lineStyle = lineReference.Index.Value;
                // 这里的值是 5 表示使用主题的第 5 个样式
                // 文档规定,Index是从1开始的
                // https://docs.microsoft.com/en-za/dotnet/api/documentformat.openxml.drawing.linereference?view=openxml-2.8.1
                lineStyle--;
            }

以上的细节是 a:lnRef 指定的 idx 是序号,而序号是从 1 开始的,咱的集合默认使用 0 开始

接下来是获取文档的主题,在 Office 的优先级是 Slide 然后是 SlideLayout 最后才是 SlideMaster 的主题

                // 获取主题
                var themeOverride = slidePart.ThemeOverridePart?.ThemeOverride
                    ?? slidePart.SlideLayoutPart.ThemeOverridePart?.ThemeOverride;
                FormatScheme formatScheme = themeOverride?.FormatScheme;
                if (formatScheme is null)
                {
                    formatScheme = slidePart.SlideLayoutPart.SlideMasterPart.ThemePart.Theme.ThemeElements.FormatScheme;
                }

在这份课件,使用的是放在 Theme1.xml 里面的主题

                  <a:themeElements>
                    <a:fmtScheme name="Office">
                      <a:lnStyleLst>
                        <a:ln w="6350" cap="flat" cmpd="sng" algn="ctr">
                          <a:solidFill>
                            <a:schemeClr val="phClr" />
                          </a:solidFill>
                          <a:prstDash val="solid" />
                          <a:miter lim="800000" />
                        </a:ln>
                        <a:ln w="12700" cap="flat" cmpd="sng" algn="ctr">
                          <a:solidFill>
                            <a:schemeClr val="phClr" />
                          </a:solidFill>
                          <a:prstDash val="solid" />
                          <a:miter lim="800000" />
                        </a:ln>
                        <a:ln w="69050" cap="flat" cmpd="sng" algn="ctr">
                          <a:solidFill>
                            <a:srgbClr val="954F72" />
                          </a:solidFill>
                          <a:prstDash val="solid" />
                          <a:miter lim="800000" />
                        </a:ln>
                      </a:lnStyleLst>
                    </a:fmtScheme>
                  </a:themeElements>

以上的 FormatScheme 类就是存放 a:fmtScheme 的内容

使用下面代码获取线条样式

                var lineStyleList = formatScheme.LineStyleList;
                var outlineList = lineStyleList.Elements<Outline>().ToList();

如果形状的样式序号没有大于主题定义的样式列表数量,那么使用对应的样式。如果定义的序号超过了主题定义的样式列表数量,就需要使用最后一个样式,请看代码

                Outline themeOutline;
                if (lineStyle > outlineList.Count)
                {
                    themeOutline = outlineList[^1];
                }
                else
                {
                    themeOutline = outlineList[(int)lineStyle];
                }

上面代码获取的 Outline 就是形状线条在主题样式的值

本文所有代码放在 githubgitee 欢迎小伙伴访问

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • dotnet OpenXML 解析 PPT 页面元素文档格式

    是否小伙伴还记得如何使用 OpenXML SDK 获取一份 PPTX 文件的某一个页面?如果不记得,请看 C# dotnet 使用 OpenXml 解析 PPT...

    林德熙
  • dotnet OpenXML 简单聊聊 PPT 文本解析

    在 Office 里面的文本解析最全的范围是 Word 文本,就是属性数量本身就特别多。本文只是简单和大家聊聊 Office 里面的 PPT 的文本的解析入门。...

    林德熙
  • dotnet OpenXML 解析 PPT 文本字体获取详解

    在 OpenXML 的 PPT 的文本的字体是一个比较复杂的概念,即使在 OpenXML SDK 的辅助下,也需要自己写很多的逻辑。通过 ECMA 376 文档...

    林德熙
  • OpenCV学习+常用函数记录③:霍夫变换与轮廓提取

    小黑鸭
  • dotnet OpenXML 解析 WPS 不规范的 PPT 文件的 cNvPr 重复 id 问题

    在收到了反馈说有一份课件,打开解析就发现替换的元素不对,原因是这个课件里面的 Slide Master 里面存在一个元素的 id 和某个页面的元素 id 是相同...

    林德熙
  • 基于连通性状态压缩的动态规划问题

    基于连通性状态压缩的动态规划问题 基于状态压缩的动态规划问题是一类以集合信息为状态且状态总数为指数级的特殊的动态规划问题.在状态压缩的基础上,有一类问题的状态中...

    Angel_Kitty
  • 吴文俊先生的思想对我学术研究的影响

    今天(2017年5月7日)惊闻吴文俊先生仙逝,宛若晴天霹雳,令人无限感伤。我虽然从未有幸和吴先生见面,但却多次通过电子邮件得到他亲自教诲。我的学术生涯受到了吴文...

    用户1908973
  • halcon 算子功能查找大全中文版(可直接下载)

    原文链接:https://www.cnblogs.com/DOMLX/p/11543364.html 下载后 可以直接ctrl+f查找 很方便

    徐飞机
  • 数控系统常见术语详解,机加工人士必备资料

    回转式位置测量元件,装于电动机轴或滚珠丝杠上,回转时发出等间隔脉冲表示位移量。由于没有记忆元件,故不能准确代表机床的位置。只有在机床回零,建立了机床坐标系的零点...

    UG数控编程

扫码关注云+社区

领取腾讯云代金券