當您比較兩個 Word 檔案,而唯一的差異僅在於清單的編號方式,例如原本的 1. 和 2. 現在變成 a. 和 b.,或是編號清單變成了項目符號清單,Aspose.Words 預設不會報告任何差異。本教學說明如何在 Python 中比較 Word 檔案時偵測編號變更,並解釋如何審閱、接受或拒絕它找到的變更。
主要要點
- 預設情況下,當您比較 Word 檔案時,列表的編號樣式或項目符號字元的變更不會產生任何修訂。
- 設定
options.advanced_options.compare_list_definitions = True會將每個受影響的列表段落報告為FORMAT_CHANGE修訂。 - 列表項目內的文字變更無論如何都會被報告。此選項僅在此基礎上加入編號和項目符號的變更。
ignore_formatting=True即使在啟用此選項時也會隱藏編號變更。
為什麼編號變更預設不會顯示
Word 中的編號和項目符號來自清單定義。它描述每個清單層級的外觀:編號樣式(1.、a.、i.)、項目符號字元以及相關格式設定。當您比較文件時,Aspose.Words 會預設遵循 Microsoft Word,並在比較中省略清單定義。因此,如果僅更改了編號,比較結果將不會顯示任何變更。
compare_list_definitions 選項在 Word 中沒有對應項。它告訴 Aspose.Words 在比較時包含清單定義。以下是我們在版本 26.9 中比較兩項清單時看到的情況:
| 原始清單 | 編輯後清單 | 關閉選項 | 開啟選項 |
|---|---|---|---|
編號 1. 2. | 項目符號 | 0 次修訂 | 2 FORMAT_CHANGE |
編號 1. 2. | 字母 a. b. | 0 次修訂 | 2 FORMAT_CHANGE |
| 編號, “Item 2” | 項目符號, “Item two” | 2 (DELETION, INSERTION) | 4(新增 2 FORMAT_CHANGE) |
| 編號 | 相同的編號列表 | 0 次修訂 | 0 次修訂 |
在實務上,最後一行很重要。啟用此選項不會為兩個檔案中相同的清單產生額外的修訂。
先決條件
您需要 Aspose.Words for Python via .NET 26.9 或更高版本。從 PyPI 安裝或升級它:
pip install --upgrade "aspose-words>=26.9"
如果沒有授權,Aspose.Words 會在評估模式下運行,並受到限制。一個臨時授權可在測試期間移除這些限制。
看看差異:有無選項時編號的變化
以下腳本會建立兩個包含相同兩個項目的文件。第一個使用編號清單,第二個使用項目符號清單。它會比較兩次,一次在關閉選項時,另一次在開啟選項時,讓您能精確看到選項的變化。
import datetime
import aspose.words as aw
def build_list_document(bulleted: bool) -> aw.Document:
"""Create a two-item list, either numbered or bulleted."""
doc = aw.Document()
builder = aw.DocumentBuilder(doc=doc)
if bulleted:
builder.list_format.apply_bullet_default()
else:
builder.list_format.apply_number_default()
builder.writeln("Item 1")
builder.writeln("Item 2")
builder.list_format.remove_numbers()
return doc
def compare_lists(compare_list_definitions: bool) -> aw.Document:
original = build_list_document(bulleted=False)
edited = build_list_document(bulleted=True)
options = aw.comparing.CompareOptions()
options.advanced_options.compare_list_definitions = compare_list_definitions
# compare() writes revisions into `original`; it returns nothing.
original.compare(
document=edited,
author="Reviewer",
date_time=datetime.datetime.now(),
options=options,
)
return original
for flag in (False, True):
result = compare_lists(flag)
print(f"compare_list_definitions={flag}: {result.revisions.count} revision(s)")
for revision in result.revisions:
revision_type = aw.RevisionType(revision.revision_type).name
text = revision.parent_node.get_text().strip()
print(f" {revision_type}: {text}")
result.save("compared-lists.docx")
執行腳本會印出:
compare_list_definitions=False: 0 revision(s)
compare_list_definitions=True: 2 revision(s)
FORMAT_CHANGE: Item 1
FORMAT_CHANGE: Item 2
程式碼運作方式
build_list_document使用DocumentBuilder.list_format來開始一個預設的編號或項目符號清單,寫入兩個項目,然後呼叫remove_numbers(),使之後的段落不再屬於該清單。CompareOptions.advanced_options會公開compare_list_definitions,其預設值為False。original.compare(...)將original與edited進行比較,並將差異記錄為original內的修訂。此方法回傳None,因此請始終從呼叫該方法的文件中讀取結果。- 每個修訂的
parent_node為格式變更的清單段落。revision_type為RevisionType.FORMAT_CHANGE,表示編號與項目符號的變更。
偵測兩個 Word 檔案之間的編號變更
在實際工作流程中,您會比較兩個現有檔案,例如合約的兩個版本。這些比較通常還包含其他修訂,因此下面的腳本僅保留位於清單段落上的格式變更。
import datetime
import aspose.words as aw
original = aw.Document("contract-v1.docx")
edited = aw.Document("contract-v2.docx")
options = aw.comparing.CompareOptions()
options.advanced_options.compare_list_definitions = True
original.compare(edited, "Reviewer", datetime.datetime.now(), options)
# Keep only formatting revisions that sit on list paragraphs.
list_changes = [
rev for rev in original.revisions
if rev.revision_type == aw.RevisionType.FORMAT_CHANGE
and rev.parent_node is not None
and rev.parent_node.node_type == aw.NodeType.PARAGRAPH
and rev.parent_node.as_paragraph().list_format.is_list_item
]
print(f"Total revisions: {original.revisions.count}")
print(f"Formatting changes on list paragraphs: {len(list_changes)}")
for rev in list_changes:
print(f" {rev.parent_node.get_text().strip()}")
original.save("contract-compared.docx")
在我們的測試中,合約的第 2 版將編號列表更改為項目符號,並且還將一個不相關的句子加粗。輸出是:
Total revisions: 5
Formatting changes on list paragraphs: 2
Invoices are due in 30 days.
Late fees apply after 45 days.
此過濾器會挑選出兩個清單項目,並跳過粗體變更,因為該修訂作用於文字而非清單段落。請記住,它會匹配清單項目上任何段落層級的格式變更,例如縮排變更,而不僅僅是編號。若需要將它們區分開來,請檢查已儲存的文件。
審閱、接受或拒絕編號變更
因為編號變更屬於普通的格式修訂,您應該以與其他修訂相同的方式處理它們:
revisions.accept_all()應用編輯後的清單格式。在第一個範例中,兩個項目都會變成項目符號。revisions.reject_all()保持原始格式,因此項目仍保持編號1.和2.。- 儲存文件會將修訂寫入為追蹤變更,讓審閱者可以在 Microsoft Word 中開啟檔案,自行決定每項變更。
您也可以對單個 Revision 物件呼叫 accept() 或 reject(),例如僅對前一節中 list_changes 清單中的項目執行此操作。
何時偵測編號變更
當清單的編號對審閱者具有意義時,請開啟此選項。法律和政策文件是常見的情況:將條款編號從 1. 重新編為 (a) 會改變其他文件對其的引用方式,因此審閱者需要看到此變更。當您在系統之間遷移文件並希望確認清單編號在搬移後保持不變時,這也很有用。
當您只關心文字內容時,請將其關閉。內容審閱、翻譯檢查以及文字層級的差異比較,在沒有格式修訂混雜的情況下更容易閱讀。
需要注意的事項
ignore_formatting覆蓋此選項。 如果將options.ignore_formatting = True設為 True,則即使compare_list_definitions = True,編號變更也不會被報告。- 比較前文件不得包含修訂。 如果任一文件已經有追蹤變更,
compare會拋出RuntimeError,提示比較的文件不得有修訂。請先接受或拒絕現有的修訂。這也意味著您不能在已包含第一次比較結果的文件上再次執行比較;每次都需要重新載入文件。 - 其他修訂仍會顯示。 列表項目中的插入或刪除文字會被報告,無論此選項是否開啟,因此如果需要將編號變更與文字變更分開,請檢查
revision_type。
下一步
Aspose.Words for Python 文檔中的 Compare Documents 文章涵蓋了其他比較設定,包括粒度、比較目標以及忽略選項。
FAQs
為什麼 Aspose.Words 在比較 Word 檔案時無法偵測編號變更? 預設情況下,Aspose.Words 會遵循 Microsoft Word,並將清單定義(例如編號樣式或項目符號字元)排除在比較之外。除非啟用
compare_list_definitions,否則從編號變更為項目符號的清單不會產生任何修訂。如何在 Python 中檢測編號變更? 建立
CompareOptions,將options.advanced_options.compare_list_definitions設為True,然後將此選項傳遞給Document.compare。每個編號或項目符號發生變更的清單段落都會收到FORMAT_CHANGE修訂。什麼樣的修訂會因編號變更而產生? 每個受影響的清單段落都會獲得類型為
RevisionType.FORMAT_CHANGE的修訂。接受它會套用已編輯檔案的清單格式,拒絕則保留原始內容。此選項能與 ignore_formatting 一起使用嗎? 不會。當
CompareOptions.ignore_formatting為True時,即使compare_list_definitions為True,也不會報告編號變更。Document.compare 會回傳什麼? 沒有。它會將差異寫入您呼叫它的文件中作為修訂,您可以從該文件的
revisions集合中讀取它們。哪個版本的 Aspose.Words for Python 添加了此選項?
AdvancedCompareOptions的compare_list_definitions屬性已在 Aspose.Words for Python via .NET 26.9 中加入。
