PPT 样式差异漏报复盘:实线改虚线为何没有产生 style_changes

举报
yd_267833669 发表于 2026/10/22 14:46:33 2026/10/22
【摘要】 用一组仅改变形状轮廓线型的合成 PPTX 复现 ShapeStyle 漏报:OOXML 已出现 prstDash,但序列化后的样式字典仍完全相同。

PPT 样式差异漏报复盘:实线改虚线为何没有产生 style_changes

摘要:用一组仅改变形状轮廓线型的合成 PPTX 复现 ShapeStyle 漏报:OOXML 已出现 prstDash,但序列化后的样式字典仍完全相同。

问题背景

做 PPT 修改前后对比时,文字、位置和图片差异通常比较容易发现,形状样式却容易被漏掉。我用 python-pptx 1.0.2 构造了两份最小 PPTX:形状尺寸、位置、填充色、边框颜色和边框宽度都相同,唯一变化是把边框从实线改成虚线。

肉眼和 OOXML 都能确认两份文件不同,但当前 PPT-diff 的样式比较没有报告这项变化。

最小复现

两份文件位于同一复现目录:

  • old.pptx:轮廓为实线,slide XML 中没有 prstDash。
  • new.pptx:轮廓为虚线,slide1.xml 中出现 <a:prstDash val="dash"/>。

随后分别调用 shape.style.to_dict() 读取第一个形状的 ShapeStyle。实际得到的对象完全相同:

  • fill_color_hex: #eeeeee
  • fill_type: SOLID (1)
  • line_color_hex: #112233
  • line_width_pt: 3.0

继续调用比较逻辑时,当前实现返回 base_status: unchanged、style_changes: 0,汇总中的 summary.style_changes 也是 0。

进入完整比较流程后,内容相同的页面还会被标成 moved,但样式差异依旧是 0。也就是说,报告既没有给出线型变化,还会让用户误以为只是页面位置发生变化。

根因PPT 解析模块 的 ShapeStyle 目前只保存四类字段:

  • fill_color_hex
  • fill_type
  • line_color_hex
  • line_width_pt

提取时只读取边框颜色和宽度,没有读取 line.dash_style;差异比较模块 的样式差异字段表也自然没有线型项。因此两边的 ShapeStyle.to_dict() 完全一致,后续逻辑不可能报告虚线变化。

这不是 OOXML 没写进去,而是解析模型没有把已经存在的属性带入中间表示。

最小修复思路

  1. 在 ShapeStyle 增加 line_dash_style 字段,并写入 to_dict()。
  2. 在 _extract_shape_style() 中读取 shape.line.dash_style;若库层返回值不稳定,再用底层 XML 的 prstDash 作为兜底证据。
  3. 在 _diff_shape_styles() 的字段表中加入线型,并把 None 与 DASH 的差异渲染成“无 -> 虚线”,而不是只比较颜色和宽度。
  4. 增加一份只改 line.dash_style 的回归用例,断言 style_changes 至少包含一项,且完整报告的 summary.style_changes 为 1。

验证原则

样式对比不能只依赖对象序列化后的字典。本次复现证明,OOXML 已经发生的视觉变化可能在中间模型里完全消失。对边框类样式,至少应覆盖颜色、宽度和线型三个独立维度;新增字段后再检查旧文件兼容性和报告可读性。

完整复现与修复建议已另案提交。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。