Python 操作 Word 修订跟踪(Track Changes)

在团队协作环境中,Word 文档的修订跟踪功能对于文档审查和版本控制至关重要。通过启用修订跟踪,可以记录所有插入、删除和格式更改,并追踪每个修改的作者和时间。本文将介绍如何使用 Python 自动化管理 Word 文档中的修订跟踪功能,包括启用修订、提取修订信息以及接受或拒绝修订。

为什么需要程序化管理修订跟踪

手动处理 Word 文档的修订跟踪存在以下挑战:

  • 批量处理困难:需要同时处理多个文档时,手动操作效率低下
  • 信息提取繁琐:从大量修订中筛选特定作者或类型的修改耗时耗力
  • 自动化需求:在文档工作流中自动接受标准修订或标记异常修改

通过 Python 编程方式管理修订跟踪,可以实现:

  • 批量启用或禁用文档的修订跟踪功能
  • 自动提取所有修订的详细信息(作者、类型、时间)
  • 根据规则批量接受或拒绝特定修订
  • 设置或修改修订的作者信息

环境准备

首先安装 Spire.Doc for Python 库:

bash 复制代码
pip install Spire.Doc

该库提供了完整的 Word 文档操作 API,支持修订跟踪的所有核心功能。

启用和禁用修订跟踪

最基本的操作是启用或禁用文档的修订跟踪功能。当启用修订跟踪后,所有对文档的修改都会被记录下来。

python 复制代码
from spire.doc import *
from spire.doc.common import *

# 创建 Word 文档对象
document = Document()
# 从磁盘加载文件
document.LoadFromFile("Sample.docx")

# 启用修订跟踪
document.TrackChanges = True

# 保存文档
document.SaveToFile("EnableTrackChanges.docx", FileFormat.Docx2013)
document.Close()

通过设置 TrackChanges 属性为 True,即可启用修订跟踪。此后对文档的任何修改(插入文本、删除内容、格式调整等)都会被记录为修订。若要禁用修订跟踪,将该属性设置为 False 即可。

提取修订信息

提取修订信息是修订管理中最常用的功能。可以遍历文档中的所有段落和文本范围,获取每个修订的详细信息,包括修订类型、作者、时间等。

python 复制代码
from spire.doc import *
from spire.doc.common import *

def write_revisions_to_file(filename, content):
    """将修订信息写入文本文件"""
    with open(filename, "w", encoding="utf-8") as fp:
        for line in content:
            fp.write(line + "\n")

# 加载包含修订的文档
document = Document()
document.LoadFromFile("GetRevisions.docx")

insert_revisions = ["插入修订:"]
delete_revisions = ["删除修订:"]
insert_index = 0
delete_index = 0

# 遍历文档中的所有节
for section_idx in range(document.Sections.Count):
    section = document.Sections.get_Item(section_idx)
    
    # 遍历节正文中的所有子对象
    for body_idx in range(section.Body.ChildObjects.Count):
        doc_item = section.Body.ChildObjects.get_Item(body_idx)
        
        # 处理段落级别的修订
        if isinstance(doc_item, Paragraph):
            paragraph = doc_item
            
            # 检查是否为插入修订
            if paragraph.IsInsertRevision:
                insert_index += 1
                insert_revisions.append(f"索引: {insert_index}")
                
                revision = paragraph.InsertRevision
                insert_revisions.append(f"类型: {revision.Type.name}")
                insert_revisions.append(f"作者: {revision.Author}")
                insert_revisions.append("")
            
            # 检查是否为删除修订
            elif paragraph.IsDeleteRevision:
                delete_index += 1
                delete_revisions.append(f"索引: {delete_index}")
                
                revision = paragraph.DeleteRevision
                delete_revisions.append(f"类型: {revision.Type.name}")
                delete_revisions.append(f"作者: {revision.Author}")
                delete_revisions.append("")
            
            # 遍历段落中的所有子对象(文本范围)
            for text_idx in range(paragraph.ChildObjects.Count):
                obj = paragraph.ChildObjects.get_Item(text_idx)
                
                if isinstance(obj, TextRange):
                    text_range = obj
                    
                    # 检查文本范围的插入修订
                    if text_range.IsInsertRevision:
                        insert_index += 1
                        insert_revisions.append(f"索引: {insert_index}")
                        
                        revision = text_range.InsertRevision
                        insert_revisions.append(f"类型: {revision.Type.name}")
                        insert_revisions.append(f"作者: {revision.Author}")
                        insert_revisions.append("")
                    
                    # 检查文本范围的删除修订
                    elif text_range.IsDeleteRevision:
                        delete_index += 1
                        delete_revisions.append(f"索引: {delete_index}")
                        
                        revision = text_range.DeleteRevision
                        delete_revisions.append(f"类型: {revision.Type.name}")
                        delete_revisions.append(f"作者: {revision.Author}")
                        delete_revisions.append("")

# 将修订信息保存到文件
write_revisions_to_file("insert_revisions.txt", insert_revisions)
write_revisions_to_file("delete_revisions.txt", delete_revisions)

这段代码展示了如何系统地提取文档中的所有修订信息:

  1. 遍历文档结构:依次访问每个节(Section)、段落(Paragraph)和文本范围(TextRange)
  2. 识别修订类型 :通过 IsInsertRevisionIsDeleteRevision 属性判断修订类型
  3. 获取修订详情 :使用 InsertRevisionDeleteRevision 属性获取修订对象,从中提取类型和作者信息
  4. 分类存储:将插入修订和删除修订分别保存到不同的列表中

这种方法可以用于生成修订报告、筛选特定作者的修改,或者统计文档的变更情况。

设置修订作者信息

在某些场景下,可能需要统一设置或修改修订的作者信息。例如,当合并多个作者的文档时,可以将所有修订的作者设置为统一的标识。

python 复制代码
from spire.doc import *
from spire.doc.common import *

# 加载文档
document = Document()
document.LoadFromFile("GetRevisions.docx")

# 遍历文档中的所有节
for i in range(document.Sections.Count):
    section = document.Sections.get_Item(i)
    
    # 遍历节正文中的所有子对象
    for j in range(section.Body.ChildObjects.Count):
        doc_item = section.Body.ChildObjects.get_Item(j)
        
        if isinstance(doc_item, Paragraph):
            paragraph = doc_item
            
            # 设置段落级别插入修订的作者
            if paragraph.IsInsertRevision:
                paragraph.InsertRevision.Author = "E-iceblue"
            
            # 设置段落级别删除修订的作者
            elif paragraph.IsDeleteRevision:
                paragraph.DeleteRevision.Author = "E-iceblue"
            
            # 遍历段落中的文本范围
            for k in range(paragraph.ChildObjects.Count):
                text_range = paragraph.ChildObjects.get_Item(k)
                
                if isinstance(text_range, TextRange):
                    # 设置文本范围插入修订的作者
                    if text_range.IsInsertRevision:
                        text_range.InsertRevision.Author = "E-iceblue"
                    
                    # 设置文本范围删除修订的作者
                    elif text_range.IsDeleteRevision:
                        text_range.DeleteRevision.Author = "E-iceblue"

# 保存修改后的文档
document.SaveToFile("SetRevisionAuthor.docx", FileFormat.Docx2013)
document.Close()

通过修改 Revision.Author 属性,可以统一设置修订的作者名称。这在文档标准化处理或匿名化审查场景中非常有用。

接受或拒绝修订

完成文档审查后,通常需要接受或拒绝特定的修订。可以针对整个文档、特定节或特定段落执行此操作。

python 复制代码
from spire.doc import *
from spire.doc.common import *

# 加载包含修订的文档
document = Document()
document.LoadFromFile("AcceptOrRejectTrackedChanges.docx")

# 获取第一个节和要处理的段落
section = document.Sections[0]
paragraph = section.Paragraphs[0]

# 接受所有修订
paragraph.Document.AcceptChanges()

# 或者拒绝所有修订
# paragraph.Document.RejectChanges()

# 保存处理后的文档
document.SaveToFile("AcceptOrRejectTrackedChanges_out.docx", FileFormat.Docx2013)
document.Close()

AcceptChanges() 方法会应用所有修订,使文档内容反映最终的修改结果。相反,RejectChanges() 方法会撤销所有修订,恢复文档到修订前的状态。

如果需要更精细的控制,可以结合前面的修订提取功能,先筛选出特定的修订,然后有选择地接受或拒绝。例如,只接受某个特定作者的修订,或者只接受插入类型的修订而拒绝删除操作。

实际应用技巧

批量处理多个文档

在实际工作中,经常需要批量处理多个文档的修订跟踪。可以结合 Python 的文件操作功能实现自动化:

python 复制代码
import os
from spire.doc import *

def batch_enable_track_changes(folder_path):
    """批量为文件夹中的所有 Word 文档启用修订跟踪"""
    for filename in os.listdir(folder_path):
        if filename.endswith(".docx"):
            filepath = os.path.join(folder_path, filename)
            
            document = Document()
            document.LoadFromFile(filepath)
            document.TrackChanges = True
            
            output_path = os.path.join(folder_path, f"tracked_{filename}")
            document.SaveToFile(output_path, FileFormat.Docx2013)
            document.Close()
            
            print(f"已处理: {filename}")

筛选特定作者的修订

通过扩展修订提取功能,可以筛选出特定作者的修订:

python 复制代码
def filter_revisions_by_author(document, author_name):
    """筛选特定作者的修订"""
    filtered_revisions = []
    
    for section in document.Sections:
        for body_item in section.Body.ChildObjects:
            if isinstance(body_item, Paragraph):
                if body_item.IsInsertRevision and body_item.InsertRevision.Author == author_name:
                    filtered_revisions.append(body_item)
                
                for child in body_item.ChildObjects:
                    if isinstance(child, TextRange):
                        if child.IsInsertRevision and child.InsertRevision.Author == author_name:
                            filtered_revisions.append(child)
    
    return filtered_revisions

生成修订统计报告

可以统计文档中各类修订的数量,生成简要报告:

python 复制代码
def generate_revision_report(document):
    """生成修订统计报告"""
    stats = {
        "insert_count": 0,
        "delete_count": 0,
        "authors": set()
    }
    
    for section in document.Sections:
        for body_item in section.Body.ChildObjects:
            if isinstance(body_item, Paragraph):
                if body_item.IsInsertRevision:
                    stats["insert_count"] += 1
                    stats["authors"].add(body_item.InsertRevision.Author)
                elif body_item.IsDeleteRevision:
                    stats["delete_count"] += 1
                    stats["authors"].add(body_item.DeleteRevision.Author)
                
                for child in body_item.ChildObjects:
                    if isinstance(child, TextRange):
                        if child.IsInsertRevision:
                            stats["insert_count"] += 1
                            stats["authors"].add(child.InsertRevision.Author)
                        elif child.IsDeleteRevision:
                            stats["delete_count"] += 1
                            stats["authors"].add(child.DeleteRevision.Author)
    
    return stats

总结

本文介绍了使用 Python 管理 Word 文档修订跟踪的核心技术,包括启用修订跟踪、提取修订信息、设置修订作者以及接受或拒绝修订。通过这些功能,可以实现文档审查流程的自动化,提高团队协作效率。

实际应用中,可以根据具体需求组合使用这些功能,例如批量处理文档、筛选特定修订、生成审查报告等。Spire.Doc for Python 提供的完整 API 支持使得这些任务变得简单高效,适合集成到各种文档管理工作流中。

相关推荐
电商API_180079052471 小时前
Python 实现闲鱼商品列表批量采集,接口异常重试机制搭建
大数据·开发语言·数据库·爬虫·python
放下华子我只抽RuiKe51 小时前
FastAPI 全栈后端(四):认证与授权
开发语言·前端·javascript·python·深度学习·react.js·fastapi
記億揺晃着的那天1 小时前
告别误操作!Spring Boot 多环境配置隔离与启动守卫实战
java·spring boot·后端·环境隔离
YuePeng2 小时前
凌晨 3 点告警群炸了,我用浏览器干了原本 XShell 才能干的事
后端·github
染翰2 小时前
Nacos 切换 Namespace 后配置不生效、占位符报错终极复盘
java·后端·spring·nacos
量化君也2 小时前
从回测到全自动实盘交易,全天候策略需要经历哪些改造?
大数据·人工智能·python·算法·金融
装不满的克莱因瓶2 小时前
自然语言处理发展历史——从规则系统到大语言模型的演进之路
网络·人工智能·python·深度学习·语言模型·自然语言处理
2601_951645783 小时前
Linux 编程语言全解析:C、C++、Python、Go、Rust 谁更强?
linux·python·go·c·编程语言
themingyi3 小时前
Abaqus2024安装python包pandas
开发语言·python·pandas