在 OpenXML 的颜色画刷填充,有特殊的填充是 GrpFill 属性,对应 OpenXML SDK 定义的 DocumentFormat.OpenXml.Drawing.GroupFill 类型

本文属于 OpenXML 系列博客,前后文请参阅 Office 使用 OpenXML SDK 解析文档博客目录

在颜色画刷的定义,如形状的填充色,在形状放入到组合里面时,可以让形状的颜色继承组合的颜色。根据 ECMA 376 的 20.1.8.35 章文档,通过 grpFill (Group Fill)属性可以让形状等元素的画刷继承组合元素的画刷,如下面文档内容,下面文档忽略很多代码,只是作为例子

      <p:grpsp>
<p:grpsppr>
<a:solidfill>
<a:srgbclr val="565656">
</a:srgbclr></a:solidfill>
</p:grpsppr>
<p:sp>
<p:sppr>
<a:prstgeom prst="rect">
<a:grpfill>
</a:grpfill></a:prstgeom></p:sppr>
</p:sp>
<p:sp>
<p:sppr>
<a:prstgeom prst="rect">
<a:solidfill>
<a:srgbclr val="F6F656">
</a:srgbclr></a:solidfill>
</a:prstgeom></p:sppr>
</p:sp>
</p:grpsp>

可以看到在组合内有两个矩形,其中第一个矩形的填充写的是 <a:grpfill> 采用组合元素的填充。而组合元素的填充如下

          <a:solidfill>
<a:srgbclr val="565656">
</a:srgbclr></a:solidfill>

我以为大家都能看出 RGB 的值,因此就截图此时的文档从 PowerPoint 打开的界面,不标注每个矩形的颜色

可以看到左边的矩形采用了 565656 的颜色,而另一个矩形采用自己定义的 F6F656 颜色。也就是说第一个矩形的颜色是从组合读取的

使用 OpenXML SDK 读取的代码如下

        private static void ReadFill(Shape shape)
{
var shapeProperties = shape.ShapeProperties;
if (shapeProperties == null)
{
return;
} var groupFill = shapeProperties.GetFirstChild<groupfill>();
if (groupFill != null)
{
// 如果是组合的颜色画刷,那需要去获取组合的
var groupShape = shape.Parent as GroupShape;
var solidFill = groupShape?.GroupShapeProperties?.GetFirstChild<solidfill>(); Debug.Assert(solidFill?.RgbColorModelHex?.Val != null, "solidFill.RgbColorModelHex.Val != null");
Console.WriteLine(solidFill.RgbColorModelHex.Val.Value);
}
else
{
var solidFill = shapeProperties.GetFirstChild<solidfill>(); Debug.Assert(solidFill?.RgbColorModelHex?.Val != null, "solidFill.RgbColorModelHex.Val != null");
Console.WriteLine(solidFill.RgbColorModelHex.Val.Value);
}
}

以上的测试文件和代码放在 githubgitee 欢迎访问

可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

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

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源

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

获取代码之后,进入 PptxDemo 文件夹

那如果是放在组合的组合里面的元素呢?规则和 WPF 资源相同,越靠近元素的越优先。如下面文档代码,只有最上层的组合存在组合填充,在第二层组合里面没有组合填充,此时的矩形将会使用最上层的组合的填充

 <p:grpsp>
<p:grpsppr>
<a:solidfill>
<a:srgbclr val="565656">
</a:srgbclr></a:solidfill>
</p:grpsppr>
<p:grpsp>
<p:grpsppr>
<!-- 没有填充 -->
</p:grpsppr>
<p:sp>
<p:sppr>
<a:prstgeom prst="rect">
<a:grpfill>
</a:grpfill></a:prstgeom></p:sppr>
</p:sp>
<p:sp>
<p:sppr>
<a:prstgeom prst="rect">
<a:solidfill>
<a:srgbclr val="F6F656">
</a:srgbclr></a:solidfill>
</a:prstgeom></p:sppr>
</p:sp>
</p:grpsp>
<p:sp>
<!-- 卖萌的 -->
</p:sp>
</p:grpsp>

从 PowerPoint 打开的界面如下

修改一下逻辑,如下

        private static void ReadFill(Shape shape)
{
// 更多读取画刷颜色请看 [dotnet OpenXML 获取颜色方法](https://blog.lindexi.com/post/Office-%E4%BD%BF%E7%94%A8-OpenXML-SDK-%E8%A7%A3%E6%9E%90%E6%96%87%E6%A1%A3%E5%8D%9A%E5%AE%A2%E7%9B%AE%E5%BD%95.html ) var shapeProperties = shape.ShapeProperties;
if (shapeProperties == null)
{
return;
} var groupFill = shapeProperties.GetFirstChild<groupfill>();
if (groupFill != null)
{
// 如果是组合的颜色画刷,那需要去获取组合的
var groupShape = shape.Parent as GroupShape;
var solidFill = groupShape?.GroupShapeProperties?.GetFirstChild<solidfill>(); if (solidFill is null)
{
// 继续获取组合的组合
while (groupShape!=null)
{
groupShape = groupShape.Parent as GroupShape;
solidFill = groupShape?.GroupShapeProperties?.GetFirstChild<solidfill>(); if (solidFill != null)
{
break;
}
}
} Debug.Assert(solidFill?.RgbColorModelHex?.Val != null, "solidFill.RgbColorModelHex.Val != null");
Console.WriteLine(solidFill.RgbColorModelHex.Val.Value);
}
else
{
var solidFill = shapeProperties.GetFirstChild<solidfill>(); Debug.Assert(solidFill?.RgbColorModelHex?.Val != null, "solidFill.RgbColorModelHex.Val != null");
Console.WriteLine(solidFill.RgbColorModelHex.Val.Value);
}
}

上面代码在获取到当前形状的上一层组合,拿不到画刷时,将会继续尝试去找组合的组合

以上代码和测试文件放在 githubgitee 欢迎访问

可以继续在当前代码仓库里面输入以下命令获取

git pull origin f15fb418610fc95ac807289a4ea19343489daa2d

那如果元素没有放入到组合呢?也就是某个形状设置填充色采用继承组合的画刷,但是此形状没有在组合内。在 PowerPoint 的行为是此元素将丢失填充色,相当于没有填充

如以下的文档内容,有一个形状使用了 grpFill 但是没有放在组合里面

  <p:csld>
<p:sptree>
<p:sp>
<p:nvsppr>
<p:cnvpr id="2" name="Rectangle 1">
</p:cnvpr></p:nvsppr>
<p:sppr>
<a:prstgeom prst="rect">
<a:grpfill>
</a:grpfill></a:prstgeom></p:sppr>
</p:sp>
</p:sptree>
</p:csld>

从 PPT 里打开可以看到此形状是不可见的

咱使用代码读取的方法如下

static void ReadFill(Shape shape)
{
// 更多读取画刷颜色请看 [dotnet OpenXML 获取颜色方法](https://blog.lindexi.com/post/Office-%E4%BD%BF%E7%94%A8-OpenXML-SDK-%E8%A7%A3%E6%9E%90%E6%96%87%E6%A1%A3%E5%8D%9A%E5%AE%A2%E7%9B%AE%E5%BD%95.html ) var shapeProperties = shape.ShapeProperties;
if (shapeProperties == null)
{
return;
} var groupFill = shapeProperties.GetFirstChild<groupfill>();
if (groupFill != null)
{
// 如果是组合的颜色画刷,那需要去获取组合的
var groupShape = shape.Parent as GroupShape;
var solidFill = groupShape?.GroupShapeProperties?.GetFirstChild<solidfill>(); if (solidFill is null)
{
// 继续获取组合的组合
while (groupShape != null)
{
groupShape = groupShape.Parent as GroupShape;
solidFill = groupShape?.GroupShapeProperties?.GetFirstChild<solidfill>(); if (solidFill != null)
{
break;
}
}
} if (solidFill is null)
{
Console.WriteLine($"没有颜色");
}
else
{
Debug.Assert(solidFill.RgbColorModelHex?.Val != null, "solidFill.RgbColorModelHex.Val != null");
Console.WriteLine(solidFill.RgbColorModelHex.Val.Value);
}
}
else
{
var solidFill = shapeProperties.GetFirstChild<solidfill>(); Debug.Assert(solidFill?.RgbColorModelHex?.Val != null, "solidFill.RgbColorModelHex.Val != null");
Console.WriteLine(solidFill.RgbColorModelHex.Val.Value);
}
}

以上代码和测试文件放在 githubgitee 欢迎访问

可以继续在当前代码仓库里面输入以下命令获取

git pull origin 20627e0deed86ea300a1c70a0066e7b15d98a9b9

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

dotnet OpenXML 继承组合颜色的 GrpFill 属性的更多相关文章

  1. dotnet OpenXML 转换 PathFillModeValues 为颜色特效

    在 OpenXml 预设形状,有一些形状设置了 PathFillModeValues 枚举,此枚举提供了亮暗的蒙层特效.具体的特效是让形状选择一个画刷,在画刷上加上特效.如立体几何 Cube 形状,在 ...

  2. 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)

    [源码下载] 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...

  3. JavaScript-原型&原型链&原型继承&组合函数

    小小的芝麻之旅: 今天学习了js的原型,要说原型,我们先简单说一下函数创建过程. 原型 每个函数在创建的时候js都自动添加了prototype属性,这就是函数的原型,原型就是函数的一个属性,类似一个指 ...

  4. Python开发基础-Day19继承组合应用、对象序列化和反序列化,选课系统综合示例

    继承+组合应用示例 class Date: #定义时间类,包含姓名.年.月.日,用于返回生日 def __init__(self,name,year,mon,day): self.name = nam ...

  5. python基础之继承组合应用、对象序列化和反序列化,选课系统综合示例

    继承+组合应用示例 1 class Date: #定义时间类,包含姓名.年.月.日,用于返回生日 2 def __init__(self,name,year,mon,day): 3 self.name ...

  6. [BS-03] 统一设置UITabBarController管理的所有VC的tabBarItem图标文字的颜色大小等属性

    1. 统一设置UITabBarController管理的所有VC的tabBarItem图标文字的颜色大小等属性 . 统一设置UITabBarController管理的所有VC的tabBarItem图标 ...

  7. python----类,面向对象(封装、继承、多态)(属性,方法)

    什么是对象? 对象是内存中专门用来存储数据的一块区域 对象中可以存放各种数据(数字.代码等) 对象由三部分组成(1,对象标识(id)2,对象类型(type)3,对象的值(value)) 面向对象编程是 ...

  8. dotnet OpenXML 读取 PPT 内嵌 ole 格式 Excel 表格的信息

    在 Office 中,可以在 PPT 里面插入表格,插入表格有好多不同的方法,对应 OpenXML 文档存储的更多不同的方式.本文来介绍如何读取 PPT 内嵌 ole 格式的 xls+ 表格的方法 在 ...

  9. 简单的继承练习——疑问:私有属性在类的方法内调用时,有必要使用get,set方法嘛?

    要求: 创建一个Circle类,设置半径属性和返回面积的方法,在无参构造器中初始化半径值为1. 创建一个Cylinder类,继承Circle类,设置属性高和返回体积的方法,在无参构造器中初始化长度为1 ...

  10. 第92天:CSS3中颜色和文本属性

    一.颜色的表示方式 1. rgba(255,0,0,0.1)  rgba是代表Red(红色) Green(绿色) Blue(蓝色)和 Alpha透明度.虽然它有的时候被描述为一个颜色空间 新增了RGB ...

随机推荐

  1. 数据好合: Argilla 和 Hugging Face Spaces 携手赋能社区合力构建更好的数据集

    最近,Argilla 和 Hugging Face 共同 推出 了 Data is Better Together 计划,旨在凝聚社区力量协力构建一个对提示进行排名的偏好数据集.仅用几天,我们就吸引了 ...

  2. 记录--不定高度展开收起动画 css/js 实现

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 不定高度展开收起动画 最近在做需求的时候,遇见了元素高度展开收起的动画需求,一开始是想到了使用 transition: all .3s; ...

  3. 从零开始学Spring Boot系列-集成Kafka

    Kafka简介 Apache Kafka是一个开源的分布式流处理平台,由LinkedIn公司开发和维护,后来捐赠给了Apache软件基金会.Kafka主要用于构建实时数据管道和流应用.它类似于一个分布 ...

  4. KingbaseES V8R6集群部署案例之---脚本部署节点环境检查故障

    KingbaseES V8R6集群部署案例之---脚本部署节点环境检查故障 案例说明: KingbaseES V8R6集群在部署前会对集群节点系统环境进行检测,检测失败后,将中断部署:其中一个检测项, ...

  5. .NET Emit 入门教程:第六部分:IL 指令:2:详解 ILGenerator 辅助方法

    前言: 经过前面几大部分的学习,已经掌握了 Emit 的前因后果,今天来详细讲解 Emit 中 IL 的部分内容. 如前文所讲,通过 DynamicMethod(或 MethodBuilder)可获得 ...

  6. sql分页遍历出现重复数据原因与解决方案

    1. 问题描述 有同时反馈,直接通过如下的sql进行分页查询,分页会出现重复数据,于是乎我专门查了相关了资料,整理了一下. -- 根据sort字段对dbname进行排序,每五百条数据一页 SELECT ...

  7. keycloak~在认证的action中自定义重定向地址

    场景与实现逻辑 我的登录接口,在输入账号密码成功后进行中间页 中间页可以通过添加Authenticator的实现类来写逻辑 authenticate方法是渲染页面的,action方法是提交表单后的逻辑 ...

  8. Jetty的模块

    查看模块的列表,执行如下命令: java -jar $JETTY_HOME/start.jar --list-modules 启用模块,比如http模块,执行如下命令: java -jar $JETT ...

  9. 陈海波:OpenHarmony技术领先,产学研深度协同,生态蓬勃发展

      11月4日,以"技术筑生态,智联赢未来"为主题的第二届OpenHarmony技术大会在北京隆重举办.本次大会由OpenAtom OpenHarmony(简称"Open ...

  10. 上新啦KIT

    HMS Core上新啦!分析服务区服分析全新上线:机器学习服务OCR新增手写识别服务:3D建模续扫能力更新:视频编辑服务支持自定义上传素材--更多#HMS Core#能力可点击网页链接了解. 了解更多 ...