欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-11-01 18:53:30
在 OpenXML 中,默认的形状可以通过指定 LineReference 让形状使用文档主题里面的样式。文档主题里面包含多个样式,在形状里面指定样式通过的是序号的方法,如果在形状里面指定的序号超过了主题的数量,那么将会使用最后一项样式 ......

在 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 解析文档博客目录