使用 Python 自动处理 Word 修订:开启、关闭、接受、拒绝及提取等(详解)

目录

    • [安装所需 Python 库](#安装所需 Python 库)
    • [1. 使用 Python 开启 Word 修订功能](#1. 使用 Python 开启 Word 修订功能)
    • [2. 使用 Python 关闭 Word 修订功能](#2. 使用 Python 关闭 Word 修订功能)
    • [3. 通过 Python 向 Word 文档中添加修订记录](#3. 通过 Python 向 Word 文档中添加修订记录)
    • [4. 检查 Word 文档是否存在待处理修订](#4. 检查 Word 文档是否存在待处理修订)
    • [5. 使用 Python 接受或拒绝 Word 中的所有修订](#5. 使用 Python 接受或拒绝 Word 中的所有修订)
    • [6. 使用 Python 提取 Word 修订信息,包括格式变更](#6. 使用 Python 提取 Word 修订信息,包括格式变更)
    • [7. 按作者选择性接受或拒绝 Word 修订](#7. 按作者选择性接受或拒绝 Word 修订)
    • [8. 通过比较两个 Word 文档生成修订记录](#8. 通过比较两个 Word 文档生成修订记录)
    • 总结

Microsoft Word 的修订功能,是文档审阅、协作编辑和审批流程中非常常用的一项功能。无论是合同、报告、制度文件,还是多人协作编写的技术文档,修订功能都可以帮助我们清晰地看到:谁修改了什么、什么时候修改的,以及这些修改最终是否被接受。

不过,当你需要批量处理大量 Word 文件时,如果仍然依赖人工逐个打开文档、开启修订、检查修改、接受或拒绝变更,整个过程就会变得非常低效且重复。

借助 Python,我们可以将 Word 修订相关的操作自动化,从而更高效地处理大规模文档审阅任务。

本文将介绍如何使用 Python 操作 Word 文档中的修订功能,主要包括以下内容:

  • 安装所需 Python 库
  • 使用 Python 开启 Word 修订功能
  • 使用 Python 关闭 Word 修订功能
  • 通过 Python 向 Word 文档中添加修订记录
  • 检查 Word 文档是否存在待处理修订
  • 使用 Python 接受或拒绝所有修订
  • 提取 Word 文档中的修订信息,包括格式变更
  • 按作者选择性接受或拒绝修订
  • 通过比较两个 Word 文档生成修订记录

安装所需 Python 库

如果要在 Python 中处理 Word 的修订功能,需要使用支持修订操作的文档处理库。

常见的 python-docx 适合完成基础的 Word 文档创建、读取和编辑任务,但它并没有提供面向 Word 修订功能的高级 API。因此,如果你需要开启修订、读取修订记录、接受或拒绝变更,就需要选择支持这些能力的库。

本文将使用 Spire.Doc for Python。它提供了专门用于处理 Word 修订的 API,并且不要求本机安装 Microsoft Word。

你可以通过 pip 进行安装:

bash 复制代码
pip install Spire.Doc

1. 使用 Python 开启 Word 修订功能

在将合同模板、标准操作流程、制度文件或法律协议发送给外部人员审阅之前,我们通常希望文档默认开启修订功能。这样,对方打开文档后所做的任何修改,都会被记录为可审阅的修订内容,方便后续统一检查和确认。

要为 Word 文档开启修订功能,可以将 Document.TrackChanges 属性设置为 True

python 复制代码
from spire.doc import *

# 加载 Word 文档
doc = Document()
doc.LoadFromFile("示例.docx")

# 开启修订功能
doc.TrackChanges = True

# 另存为新文件
doc.SaveToFile("开启修订.docx", FileFormat.Docx2016)
doc.Close()

保存后,用 Microsoft Word 打开生成的文件,进入"审阅"选项卡,可以看到"修订"功能已经处于开启状态。此后如果在 Word 中修改文档内容,相关编辑就会被记录为修订。

注意:

设置 TrackChanges = True 的作用,是让 Word 从当前时间点开始记录后续的人工交互式编辑。它不会把文档中已经存在的内容追溯标记为修订内容。

2. 使用 Python 关闭 Word 修订功能

关闭修订功能也非常简单,只需要将 Document.TrackChanges 属性设置为 False

python 复制代码
from spire.doc import *

# 加载已经开启修订功能的 Word 文档
doc = Document()
doc.LoadFromFile("开启修订.docx")

# 关闭修订功能
doc.TrackChanges = False

# 保存修改后的文档
doc.SaveToFile("关闭修订.docx", FileFormat.Docx2016)

# 关闭文档
doc.Close()

注意:

关闭修订功能只会阻止新的修改继续被记录为修订。它不会删除、接受或拒绝文档中已经存在的修订内容。

也就是说,如果文档中已经有待处理的修订,这些修订仍然会保留在文档中,直到你手动或通过程序接受、拒绝它们。

3. 通过 Python 向 Word 文档中添加修订记录

在某些场景下,我们希望 Python 脚本像"审阅者"一样工作:它不是直接永久修改文档,而是以修订的形式提出修改建议,等待人工审阅和确认。

这种方式非常适合合同审查自动化、AI 辅助文档编辑、批量文档规范检查等场景。

要实现这一点,可以在进行程序化编辑之前调用 Document.StartTrackRevisions(),编辑完成后再调用 Document.StopTrackRevisions()

python 复制代码
from spire.doc import *

# 创建 Document 对象
document = Document()

# 从指定路径加载文档
document.LoadFromFile("示例.docx")

# 开始记录修订,并指定修订作者和时间
document.StartTrackRevisions("Python用户", DateTime())

# 获取第四个段落并追加文本
document.Sections[0].Paragraphs[3].AppendText("Python用户添加了新文本!")

# 删除第五个段落
document.Sections[0].Paragraphs.RemoveAt(4)

# 停止记录修订
document.StopTrackRevisions()

# 保存文件
document.SaveToFile("添加修订.docx", FileFormat.Docx2016)

# 关闭文档
document.Close()

执行后,程序添加的文本和删除的段落都会以修订形式显示在 Word 文档中,而不是直接变成最终内容。

4. 检查 Word 文档是否存在待处理修订

在执行接受或拒绝修订之前,通常建议先检查文档中是否真的存在待处理的修订内容。

Document.HasChanges 属性可以用于判断当前文档中是否包含插入、删除或格式变更等修订信息。如果返回 True,说明文档中存在尚未处理的修订;如果返回 False,则说明当前文档没有待处理的修订内容:

python 复制代码
from spire.doc import *

doc = Document()
doc.LoadFromFile("审阅.docx")

if doc.HasChanges:
    print("文档包含待处理修订!")
else:
    print("无待处理修订!")

doc.Close()

5. 使用 Python 接受或拒绝 Word 中的所有修订

当文档审阅完成后,通常需要对修订内容做最终处理:接受全部修订,或拒绝全部修订。

接受修订意味着将所有修改合并进最终文档中:新增内容会变成普通正文,被删除的内容会从文档中移除。

拒绝修订则相反:被删除的内容会恢复,新增内容会被移除,从而尽量回到审阅前的状态。

Spire.Doc 提供了两个非常直接的方法:

  • AcceptChanges():接受所有修订
  • RejectChanges():拒绝所有修订

接受所有修订

python 复制代码
from spire.doc import *

doc = Document()
doc.LoadFromFile("审阅.docx")

if doc.HasChanges:
    doc.AcceptChanges()
    print("已接受所有修订!")

doc.SaveToFile("接受修订.docx", FileFormat.Docx2016)
doc.Close()

拒绝所有修订

python 复制代码
from spire.doc import *

doc = Document()
doc.LoadFromFile("审阅.docx")

if doc.HasChanges:
    doc.RejectChanges()
    print("已拒绝所有修订!")

doc.SaveToFile("拒绝修订.docx", FileFormat.Docx2016)
doc.Close()

这类批量处理方式非常适合用于文档审批流的最后一步,例如自动生成"已定稿版本"或"回退版本"。

6. 使用 Python 提取 Word 修订信息,包括格式变更

在接受或拒绝修订之前,你可能需要先了解修订的具体内容,例如:

  • 谁做了修改
  • 修改了哪些文字
  • 删除了哪些内容
  • 是否存在加粗、字体颜色、高亮、下划线等格式变更

Spire.Doc 提供了 Document.GetRevisionInfos() 方法,可以获取 Word 文档中的修订信息,包括插入、删除和格式变更。

下面的示例会分别提取三类修订信息:

  • 插入内容
  • 删除内容
  • 格式修改
python 复制代码
from spire.doc import *

# 加载包含修订记录的 Word 文档
doc = Document()
doc.LoadFromFile("添加修订.docx")

# 分别存储不同类型的修订
insert_revisions = []
delete_revisions = []
format_revisions = []

def value_to_string(value):
    if value is None:
        return ""

    if hasattr(value, "ToString"):
        return value.ToString()

    return str(value)

def bool_to_chinese(value):
    return "是" if value else "否"

def get_character_style(text_range):
    char_format = text_range.CharacterFormat

    return {
        "isBold": char_format.Bold,
        "TextColor": value_to_string(char_format.TextColor),
        "HighlightColor": value_to_string(char_format.HighlightColor),
        "FontName": str(char_format.FontName),
        "UnderlineStyle": str(char_format.UnderlineStyle)
    }

def style_to_string(style):
    return (
        "是否加粗:" + bool_to_chinese(style["isBold"]) + ";"
        "字体颜色:" + style["TextColor"] + ";"
        "高亮颜色:" + style["HighlightColor"] + ";"
        "字体名称:" + style["FontName"] + ";"
        "下划线样式:" + style["UnderlineStyle"]
    )

# 获取文档中的所有修订信息
revision_info_collection = doc.GetRevisionInfos()

for revision_index in range(revision_info_collection.Count):
    revision_info = revision_info_collection.get_Item(revision_index)

    revision_type = revision_info.RevisionType
    author = revision_info.Author
    owner_object = revision_info.OwnerObject

    # 获取插入的文本
    if revision_type == RevisionType.Insertion:
        if isinstance(owner_object, TextRange):
            text_range = owner_object

            insert_revisions.append({
                "author": author,
                "text": text_range.Text
            })

    # 获取删除的文本
    elif revision_type == RevisionType.Deletion:
        if isinstance(owner_object, TextRange):
            text_range = owner_object

            delete_revisions.append({
                "author": author,
                "text": text_range.Text
            })

    # 获取格式变更,例如加粗、字体颜色、高亮颜色、字体名称和下划线样式
    elif revision_type == RevisionType.FormatChange:
        if isinstance(owner_object, TextRange):
            text_range = owner_object

            # 读取原始格式
            doc.RevisionsView = RevisionsView.Original
            original_style = get_character_style(text_range)

            # 读取最终格式
            doc.RevisionsView = RevisionsView.Final
            final_style = get_character_style(text_range)

            format_revisions.append({
                "author": author,
                "text": text_range.Text,
                "original_style": original_style,
                "final_style": final_style
            })

doc.Close()

print(f"插入修订数量:{len(insert_revisions)}")
for revision in insert_revisions:
    print(
        f"  修订作者:{revision['author']},"
        f"插入内容:{repr(revision['text'])}"
    )

print(f"\n删除修订数量:{len(delete_revisions)}")
for revision in delete_revisions:
    print(
        f"  修订作者:{revision['author']},"
        f"删除内容:{repr(revision['text'])}"
    )

print(f"\n格式修订数量:{len(format_revisions)}")
for revision in format_revisions:
    print(
        f"  修订作者:{revision['author']},"
        f"修订文本:{repr(revision['text'])}"
    )
    print("    原始格式:" + style_to_string(revision["original_style"]))
    print("    最终格式:" + style_to_string(revision["final_style"]))

这个示例不仅可以提取文本层面的新增和删除,还可以对格式修订进行分析。例如你可以知道某段文本是否从普通字体变成了加粗,是否修改了字体颜色,或者是否添加了高亮。

在实际业务中,这类能力可以用于生成审阅报告、统计不同作者的修改内容,或者在自动审批前进行风险检查。

7. 按作者选择性接受或拒绝 Word 修订

在真实的文档审阅流程中,我们并不总是希望一次性接受或拒绝所有修订。

例如,你可能希望:

  • 自动接受内部审阅人的修改
  • 保留外部律师或客户的修改,等待人工复核
  • 只处理某个指定作者的修订
  • 对不同作者设置不同的审批策略

AcceptChanges()RejectChanges() 会作用于整个文档。如果需要更精细的控制,可以先通过 GetRevisionInfos() 获取每一条修订记录,然后根据作者、修订类型或其他条件进行筛选,再对匹配的修订调用 Accept()Reject()

下面的示例演示了如何按指定作者接受或拒绝修订:

python 复制代码
from spire.doc import *

# 加载包含修订记录的 Word 文档
doc = Document()
doc.LoadFromFile("添加修订.docx")

# 指定要处理的修订作者
target_author = "Python用户"

# 设置操作类型:"accept" 表示接受,"reject" 表示拒绝
action = "accept"

# 获取文档中的所有修订信息
revision_info_collection = doc.GetRevisionInfos()

# 倒序遍历,因为接受或拒绝修订可能会更新修订集合
for i in range(revision_info_collection.Count - 1, -1, -1):
    revision_info = revision_info_collection.get_Item(i)

    # 只处理指定作者的修订
    if revision_info.Author == target_author:
        if action == "accept":
            revision_info.Accept()
        elif action == "reject":
            revision_info.Reject()
        else:
            raise ValueError("操作类型只能是 'accept' 或 'reject'")

# 根据操作类型设置输出文件名
if action == "accept":
    output_file = "按作者接受修订.docx"
else:
    output_file = "按作者拒绝修订.docx"

# 保存修改后的文档
doc.SaveToFile(output_file, FileFormat.Docx2016)
doc.Close()

需要注意的是,这里使用倒序遍历修订集合,是因为在接受或拒绝某条修订后,文档中的修订集合可能会发生变化。如果正序遍历,可能会出现索引错位或跳过某些修订的问题。

8. 通过比较两个 Word 文档生成修订记录

有时候,协作者返回的文档并没有提前开启修订功能。此时,如果你想知道他们到底修改了哪些内容,通常需要将原始版本和修改后的版本进行对比。

相比人工逐页查看两个文档,使用程序进行文档比较会更高效。

Document.Compare() 方法可以比较两个 Word 文档,并将差异记录为修订内容。它的作用类似于 Microsoft Word 内置的"比较"功能:对比结果会以修订形式展示,后续仍然可以继续接受或拒绝这些修改。

python 复制代码
from spire.doc import *

# 加载原始文档
original = Document()
original.LoadFromFile("合同_v1.docx")

# 加载修改后的文档
revised = Document()
revised.LoadFromFile("合同_v2.docx")

# 比较两个文档,所有差异都会以修订形式记录,并归属于 "审阅用户"
original.Compare(revised, "审阅用户")

# 保存比较结果
original.SaveToFile("合同比较结果.docx", FileFormat.Docx2016)
original.Close()
revised.Close()

生成的 合同比较结果.docx 可以直接在 Word 中打开。你会看到两个版本之间的差异已经被转换为修订记录,之后就可以像处理普通修订一样,对这些差异进行审阅、接受或拒绝。

总结

使用 Python 自动处理 Word 修订,是提升文档审阅、版本管理和审批效率的一种实用方式。

本文介绍了如何使用 Python 开启和关闭 Word 修订功能,也演示了如何以程序化方式添加修订、检查文档中是否存在待处理变更、接受或拒绝修订、提取修订明细、按作者选择性处理修订,以及通过比较两个 Word 文档生成修订记录。

借助这些方法,你可以更高效地处理合同、报告、制度文件、政策文档以及其他需要频繁审阅和修改的 Word 文件,减少重复性人工操作,并构建更加自动化的文档处理流程。