- A+
所属分类:.NET技术
在 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 就是形状线条在主题样式的值