查看: 157|回复: 3

Python+Spire.Doc实现Word修订自动化:开启、接受、提取与文档比较全流程

[复制链接]
发表于 5 小时前 | 显示全部楼层 |阅读模式
在日常办公中,处理Word文档的修订(Track Changes)是合同审核、团队协作、版本管理中的高频需求。如果每次都需要人工逐一开启修订、检查变更、接受或拒绝,效率极低。借助Python的Spire.Doc库,我们可以将这一系列操作完全自动化,从而高效处理大批量文档。本文将从环境搭建出发,逐步演示如何使用Python实现Word修订的完整自动化流程。

## 环境准备
首先通过pip安装Spire.Doc库(注意不是python-docx,它不支持修订操作的高级API):
  1. pip install Spire.Doc
复制代码
该库运行时不依赖本机安装Microsoft Word,适合服务器或无GUI环境。

## 1. 开启修订功能
在文档发送给外部人员审阅前,通常希望默认开启修订。只需将Document对象的TrackChanges属性设置为True:
  1. from spire.doc import *
  2. doc = Document()
  3. doc.LoadFromFile("示例.docx")
  4. doc.TrackChanges = True
  5. doc.SaveToFile("开启修订.docx", FileFormat.Docx2016)
  6. doc.Close()
复制代码
保存后,用Word打开该文件,“审阅”选项卡下的“修订”功能将处于启用状态。注意:这个设置只影响后续的手动编辑,不会追溯标记已有内容。

## 2. 关闭修订功能
关闭修订同样简单,将TrackChanges设为False即可:
  1. from spire.doc import *
  2. doc = Document()
  3. doc.LoadFromFile("开启修订.docx")
  4. doc.TrackChanges = False
  5. doc.SaveToFile("关闭修订.docx", FileFormat.Docx2016)
  6. doc.Close()
复制代码
关闭后,后续编辑不会产生修订记录,但文档中已有的修订仍然保留,需要单独接受或拒绝。

## 3. 以编程方式添加修订(模拟审阅者)
有时我们希望脚本像审阅者一样提出修改建议,而非直接修改最终内容。可以先调用Document.StartTrackRevisions(),编辑后再调用StopTrackRevisions():
  1. from spire.doc import *
  2. document = Document()
  3. document.LoadFromFile("示例.docx")
  4. # 开始记录修订,指定作者和时间为当前
  5. document.StartTrackRevisions("Python用户", DateTime())
  6. # 在第四个段落末尾追加文本
  7. document.Sections[0].Paragraphs[3].AppendText("Python用户添加了新文本!")
  8. # 删除第五个段落
  9. document.Sections[0].Paragraphs.RemoveAt(4)
  10. # 停止记录修订
  11. document.StopTrackRevisions()
  12. document.SaveToFile("添加修订.docx", FileFormat.Docx2016)
  13. document.Close()
复制代码
执行后,添加和删除的内容都会以修订形式呈现,而不是直接生效。

## 4. 检查文档是否存在未处理修订
在决定接受或拒绝之前,最好先判断文档是否包含修订。Document.HasChanges属性可快速检测:
  1. from spire.doc import *
  2. doc = Document()
  3. doc.LoadFromFile("审阅.docx")
  4. if doc.HasChanges:
  5.     print("文档包含待处理修订!")
  6. else:
  7.     print("无待处理修订!")
  8. doc.Close()
复制代码

## 5. 接受或拒绝所有修订
审阅完成后,通常需要批量处理整个文档。Spire.Doc提供了直接的方法:
接受所有修订:
  1. from spire.doc import *
  2. doc = Document()
  3. doc.LoadFromFile("审阅.docx")
  4. if doc.HasChanges:
  5.     doc.AcceptChanges()
  6.     print("已接受所有修订!")
  7. doc.SaveToFile("接受修订.docx", FileFormat.Docx2016)
  8. doc.Close()
复制代码
拒绝所有修订:
  1. from spire.doc import *
  2. doc = Document()
  3. doc.LoadFromFile("审阅.docx")
  4. if doc.HasChanges:
  5.     doc.RejectChanges()
  6.     print("已拒绝所有修订!")
  7. doc.SaveToFile("拒绝修订.docx", FileFormat.Docx2016)
  8. doc.Close()
复制代码

## 6. 提取修订信息(包括格式变更)
如果需要详细了解修改变更,可以使用Document.GetRevisionInfos()获取插入、删除和格式修改三类信息。下面示例分别提取并输出:
  1. from spire.doc import *
  2. doc = Document()
  3. doc.LoadFromFile("添加修订.docx")
  4. # 辅助函数:转换格式属性
  5. from spire.doc.common import *
  6. def value_to_string(value):
  7.     if value is None:
  8.         return ""
  9.     if hasattr(value, "ToString"):
  10.         return value.ToString()
  11.     return str(value)
  12. def bool_to_chinese(value):
  13.     return "是" if value else "否"
  14. def get_character_style(text_range):
  15.     cf = text_range.CharacterFormat
  16.     return {
  17.         "isBold": cf.Bold,
  18.         "TextColor": value_to_string(cf.TextColor),
  19.         "HighlightColor": value_to_string(cf.HighlightColor),
  20.         "FontName": str(cf.FontName),
  21.         "UnderlineStyle": str(cf.UnderlineStyle)
  22.     }
  23. def style_to_string(style):
  24.     return (
  25.         "是否加粗:" + bool_to_chinese(style["isBold"]) + ";"
  26.         "字体颜色:" + style["TextColor"] + ";"
  27.         "高亮颜色:" + style["HighlightColor"] + ";"
  28.         "字体名称:" + style["FontName"] + ";"
  29.         "下划线样式:" + style["UnderlineStyle"]
  30.     )
  31. # 获取修订信息集合
  32. revision_info_collection = doc.GetRevisionInfos()
  33. insert_revisions = []
  34. delete_revisions = []
  35. format_revisions = []
  36. for index in range(revision_info_collection.Count):
  37.     rev = revision_info_collection.get_Item(index)
  38.     author = rev.Author
  39.     obj = rev.OwnerObject
  40.     if rev.RevisionType == RevisionType.Insertion:
  41.         if isinstance(obj, TextRange):
  42.             insert_revisions.append({"author": author, "text": obj.Text})
  43.     elif rev.RevisionType == RevisionType.Deletion:
  44.         if isinstance(obj, TextRange):
  45.             delete_revisions.append({"author": author, "text": obj.Text})
  46.     elif rev.RevisionType == RevisionType.FormatChange:
  47.         if isinstance(obj, TextRange):
  48.             # 获取原始格式和最终格式
  49.             doc.RevisionsView = RevisionsView.Original
  50.             original_style = get_character_style(obj)
  51.             doc.RevisionsView = RevisionsView.Final
  52.             final_style = get_character_style(obj)
  53.             format_revisions.append({"author": author, "text": obj.Text,
  54.                                      "original_style": original_style,
  55.                                      "final_style": final_style})
  56. doc.Close()
  57. print(f"插入修订数量:{len(insert_revisions)}")
  58. for r in insert_revisions:
  59.     print(f"  作者:{r['author']},插入内容:{repr(r['text'])}")
  60. print(f"\n删除修订数量:{len(delete_revisions)}")
  61. for r in delete_revisions:
  62.     print(f"  作者:{r['author']},删除内容:{repr(r['text'])}")
  63. print(f"\n格式修订数量:{len(format_revisions)}")
  64. for r in format_revisions:
  65.     print(f"  作者:{r['author']},修订文本:{repr(r['text'])}")
  66.     print("  原始格式:" + style_to_string(r["original_style"]))
  67.     print("  最终格式:" + style_to_string(r["final_style"]))
复制代码
这个能力可用于生成审阅报告或进行自动化审批前的风险检查。

## 7. 按作者选择性接受/拒绝修订
不同作者可能对应不同的审批策略。AcceptChanges()和RejectChanges()作用于整个文档,若需精细控制,可遍历修订集合,针对指定作者调用Accept()或Reject()。注意使用倒序遍历,避免索引错位:
  1. from spire.doc import *
  2. doc = Document()
  3. doc.LoadFromFile("添加修订.docx")
  4. target_author = "Python用户"
  5. action = "accept"  # 或 "reject"
  6. revision_info_collection = doc.GetRevisionInfos()
  7. for i in range(revision_info_collection.Count - 1, -1, -1):
  8.     rev = revision_info_collection.get_Item(i)
  9.     if rev.Author == target_author:
  10.         if action == "accept":
  11.             rev.Accept()
  12.         elif action == "reject":
  13.             rev.Reject()
  14.         else:
  15.             raise ValueError("操作类型必须是 'accept' 或 'reject'")
  16. output_file = "按作者接受修订.docx" if action == "accept" else "按作者拒绝修订.docx"
  17. doc.SaveToFile(output_file, FileFormat.Docx2016)
  18. doc.Close()
复制代码

## 8. 通过比较两个文档生成修订记录
当协作者返回的文档未开启修订时,可以使用Document.Compare()方法对比原始版本和修改版,差异会自动转换为修订:
  1. from spire.doc import *
  2. original = Document()
  3. original.LoadFromFile("合同_v1.docx")
  4. revised = Document()
  5. revised.LoadFromFile("合同_v2.docx")
  6. original.Compare(revised, "审阅用户")
  7. original.SaveToFile("合同比较结果.docx", FileFormat.Docx2016)
  8. original.Close()
  9. revised.Close()
复制代码
生成的文档可直接在Word中查看差异,并继续接受或拒绝。

## 总结
通过Python与Spire.Doc库结合,我们可以轻松实现对Word修订的自动化控制:开启/关闭修订、模拟审阅者添加修订、批量接受/拒绝、提取详细修订信息、按作者筛选处理,以及文档比较生成修订。这些方法特别适合合同审批、制度文件管理、报告协作等场景,能显著减少人工操作,构建高效文档处理流水线。
回复

使用道具 举报

发表于 5 小时前 | 显示全部楼层

Re: Python+Spire.Doc实现Word修订自动化:开启、接受、提取与文档比较全流程

感谢分享这么详细的教程!Spire.Doc在Word修订自动化方面确实比python-docx强不少,特别是直接支持开启/关闭修订、批量接受拒绝以及提取修订信息,对于处理合同或团队文档审阅场景非常实用。你提到的 `StartTrackRevisions` 模拟审阅者添加修订的功能也很有价值,省去了手动模拟的麻烦。另外,`HasChanges` 做前置判断也很贴心,避免了对无修订文档执行无意义的操作。我正好有个项目需要批量处理审阅文档,准备按你的步骤试试看,谢谢!
回复 支持 反对

使用道具 举报

发表于 5 小时前 | 显示全部楼层

Re: Python+Spire.Doc实现Word修订自动化:开启、接受、提取与文档比较全流程

感谢楼主的详细分享!Spire.Doc 在 Word 修订自动化这块确实比 python-docx 要强大很多,特别是 `StartTrackRevisions` / `StopTrackRevisions` 模拟审阅者操作的功能,之前还不知道有这个方法,非常实用。 有个小建议:第 6 部分提取修订信息的代码似乎没贴完整?`get_character_style` 函数后面好像还有内容,方便补充一下吗?另外想请教一下,如果只想提取某个特定审阅者的修订(比如只提取 “Python用户” 的修改),Spire.Doc 有没有现成的方法,还是需要自己遍历筛选? 再次感谢,收藏了!
回复 支持 反对

使用道具 举报

发表于 5 小时前 | 显示全部楼层

Re: Python+Spire.Doc实现Word修订自动化:开启、接受、提取与文档比较全流程

感谢分享,这篇教程非常详细,把从开启修订到提取信息的流程都讲清楚了。我平时用python-docx处理Word,一直不知道Spire.Doc有这么多针对修订的高阶API,特别是`StartTrackRevisions`模拟审阅者操作和`GetRevisionInfos`提取格式变更这两点,之前手动做非常麻烦。打算照着试试,批量处理合同审核应该能省不少时间。请问这个库在中文文档的修订处理上有没有什么特别需要注意的地方?比如中文标点或者字符编码?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-6-25 14:10 , Processed in 0.045624 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部