PPT 样式差异漏报复盘:实线改虚线为何没有产生 style_changes
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:#eeeeeefill_type:SOLID (1)line_color_hex:#112233line_width_pt:3.0
继续调用比较逻辑时,当前实现返回 base_status: unchanged、style_changes: 0,汇总中的 summary.style_changes 也是 0。
进入完整比较流程后,内容相同的页面还会被标成 moved,但样式差异依旧是 0。也就是说,报告既没有给出线型变化,还会让用户误以为只是页面位置发生变化。
根因PPT 解析模块 的 ShapeStyle 目前只保存四类字段:
fill_color_hexfill_typeline_color_hexline_width_pt
提取时只读取边框颜色和宽度,没有读取 line.dash_style;差异比较模块 的样式差异字段表也自然没有线型项。因此两边的 ShapeStyle.to_dict() 完全一致,后续逻辑不可能报告虚线变化。
这不是 OOXML 没写进去,而是解析模型没有把已经存在的属性带入中间表示。
最小修复思路
- 在
ShapeStyle增加line_dash_style字段,并写入to_dict()。 - 在
_extract_shape_style()中读取shape.line.dash_style;若库层返回值不稳定,再用底层 XML 的prstDash作为兜底证据。 - 在
_diff_shape_styles()的字段表中加入线型,并把None与DASH的差异渲染成“无 -> 虚线”,而不是只比较颜色和宽度。 - 增加一份只改
line.dash_style的回归用例,断言style_changes至少包含一项,且完整报告的summary.style_changes为 1。
验证原则
样式对比不能只依赖对象序列化后的字典。本次复现证明,OOXML 已经发生的视觉变化可能在中间模型里完全消失。对边框类样式,至少应覆盖颜色、宽度和线型三个独立维度;新增字段后再检查旧文件兼容性和报告可读性。
完整复现与修复建议已另案提交。
- 点赞
- 收藏
- 关注作者
评论(0)