Khi bạn so sánh hai tệp Word và sự khác biệt duy nhất là cách đánh số danh sách, ví dụ các điều khoản trước đây là 1. và 2. bây giờ trở thành a. và b., hoặc một danh sách đánh số đã chuyển thành danh sách có dấu đầu dòng, Aspose.Words mặc định không báo cáo bất kỳ sự khác biệt nào. Hướng dẫn này cho bạn cách phát hiện các thay đổi về đánh số khi so sánh tệp Word trong Python. Nó cũng giải thích cách xem lại, chấp nhận hoặc từ chối các thay đổi mà nó tìm thấy.

Key Takeaways

  • Mặc định, việc thay đổi kiểu đánh số hoặc ký tự dấu đầu mục của danh sách sẽ không tạo ra bất kỳ sửa đổi nào khi bạn so sánh các tệp Word.
  • Thiết lập options.advanced_options.compare_list_definitions = True báo cáo mỗi đoạn danh sách bị ảnh hưởng như một sửa đổi FORMAT_CHANGE.
  • Các thay đổi văn bản bên trong các mục danh sách đều được báo cáo dù sao. Tùy chọn chỉ thêm các thay đổi về đánh số và dấu đầu mục.
  • ignore_formatting=True ẩn các thay đổi về đánh số ngay cả khi tùy chọn được bật.

Tại sao các thay đổi đánh số không hiển thị mặc định

Việc đánh số và dấu đầu dòng trong Word xuất phát từ một định nghĩa danh sách. Nó mô tả cách mỗi cấp độ danh sách trông như thế nào: kiểu số (1., a., i.), ký tự dấu đầu dòng và định dạng liên quan. Khi bạn so sánh tài liệu, Aspose.Words tuân theo Microsoft Word theo mặc định và loại bỏ các định nghĩa danh sách khỏi quá trình so sánh. Vì vậy, nếu chỉ có sự thay đổi về đánh số, quá trình so sánh sẽ không thấy gì để báo cáo.

Tùy chọn compare_list_definitions không có tương đương trong Word. Nó cho Aspose.Words bao gồm các định nghĩa danh sách trong quá trình so sánh. Dưới đây là những gì chúng tôi thấy khi so sánh các danh sách hai mục trong phiên bản 26.9:

Danh sách gốcDanh sách đã chỉnh sửaTùy chọn tắtTùy chọn bật
Đánh số 1. 2.Dấu đầu dòng0 sửa đổi2 FORMAT_CHANGE
Đánh số 1. 2.Có chữ cái a. b.0 sửa đổi2 FORMAT_CHANGE
Đánh số, “Mục 2”Dấu đầu dòng, “Mục hai”2 (DELETION, INSERTION)4 (thêm 2 FORMAT_CHANGE)
Đánh sốDanh sách đánh số giống nhau0 sửa đổi0 sửa đổi

Dòng cuối cùng quan trọng trong thực tế. Bật tùy chọn này sẽ không tạo ra các phiên bản phụ thêm cho các danh sách giống nhau trong cả hai tệp.

Yêu cầu trước

Bạn cần Aspose.Words for Python via .NET 26.9 hoặc phiên bản mới hơn. Cài đặt hoặc nâng cấp nó từ PyPI:

pip install --upgrade "aspose-words>=26.9"

Nếu không có giấy phép, Aspose.Words chạy ở chế độ đánh giá với các hạn chế. Một giấy phép tạm thời sẽ loại bỏ chúng khi bạn thử nghiệm.

Xem sự khác biệt: Thay đổi đánh số có và không có tùy chọn

Kịch bản sau tạo hai tài liệu chứa cùng hai mục. Tài liệu đầu tiên sử dụng danh sách có đánh số, còn tài liệu thứ hai sử dụng danh sách dấu đầu dòng. Nó so sánh chúng hai lần, một lần khi tùy chọn tắt và một lần khi bật, để bạn có thể thấy chính xác những thay đổi mà tùy chọn mang lại.

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")

Khi chạy script, in ra:

compare_list_definitions=False: 0 revision(s)
compare_list_definitions=True: 2 revision(s)
  FORMAT_CHANGE: Item 1
  FORMAT_CHANGE: Item 2

Cách mã hoạt động

  • build_list_document sử dụng DocumentBuilder.list_format để bắt đầu một danh sách đánh số hoặc có dấu đầu dòng mặc định, ghi hai mục, và sau đó gọi remove_numbers() để bất kỳ đoạn văn nào sau đó không thuộc danh sách.
  • CompareOptions.advanced_options cho phép truy cập compare_list_definitions, mặc định là False.
  • original.compare(...) so sánh original với edited và ghi lại các khác biệt dưới dạng revision trong original. Phương thức trả về None, vì vậy luôn đọc kết quả từ tài liệu mà bạn đã gọi phương thức này.
  • parent_node của mỗi revision là đoạn danh sách mà định dạng đã thay đổi. revision_type là RevisionType.FORMAT_CHANGE cho các thay đổi về đánh số và dấu đầu dòng.

Phát hiện thay đổi đánh số giữa hai tệp Word

Trong một quy trình thực tế, bạn so sánh hai tệp hiện có, chẳng hạn như hai phiên bản của một hợp đồng. Những so sánh đó thường cũng chứa các sửa đổi khác, vì vậy đoạn script bên dưới chỉ giữ lại các thay đổi định dạng nằm trên các đoạn danh sách.

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")

Trong thử nghiệm của chúng tôi, phiên bản 2 của hợp đồng đã thay đổi danh sách đánh số thành dấu đầu dòng và cũng làm cho một câu không liên quan trở nên in đậm. Kết quả là:

Total revisions: 5
Formatting changes on list paragraphs: 2
  Invoices are due in 30 days.
  Late fees apply after 45 days.

Bộ lọc chọn ra hai mục danh sách và bỏ qua thay đổi in đậm, vì bản sửa đổi đó nằm trên văn bản chứ không phải trên đoạn danh sách. Hãy nhớ rằng nó khớp với bất kỳ thay đổi định dạng cấp đoạn nào trên một mục danh sách, chẳng hạn như thụt lề đã thay đổi, không chỉ số thứ tự. Kiểm tra tài liệu đã lưu nếu bạn cần phân biệt chúng.

Xem lại, Chấp nhận hoặc Từ chối các Thay đổi Đánh số

Vì các thay đổi đánh số là các sửa đổi định dạng thông thường, bạn xử lý chúng theo cùng cách như bất kỳ sửa đổi nào khác:

  • revisions.accept_all() áp dụng định dạng danh sách đã chỉnh sửa. Trong ví dụ đầu tiên, cả hai mục đều trở thành dấu đầu dòng.
  • revisions.reject_all() giữ nguyên định dạng gốc, vì vậy các mục vẫn được đánh số 1. và 2..
  • Lưu tài liệu sẽ ghi các revision dưới dạng thay đổi được theo dõi, để người xem có thể mở tệp trong Microsoft Word và tự quyết định mỗi thay đổi.

Bạn cũng có thể gọi accept() hoặc reject() trên các đối tượng Revision riêng lẻ, ví dụ chỉ trên các mục trong danh sách list_changes từ phần trước.

Khi nào nên phát hiện thay đổi đánh số

Bật tùy chọn này khi việc đánh số của danh sách mang ý nghĩa đối với người xem của bạn. Các tài liệu pháp lý và chính sách là một trường hợp phổ biến: việc đánh số lại các điều khoản từ 1. thành (a) thay đổi cách các tài liệu khác tham chiếu tới chúng, vì vậy người xem cần thấy sự thay đổi này. Nó cũng hữu ích khi bạn di chuyển tài liệu giữa các hệ thống và muốn xác nhận rằng việc đánh số danh sách vẫn giữ nguyên sau quá trình di chuyển.

Tắt tính năng này khi bạn chỉ quan tâm đến nội dung. Việc xem xét nội dung, kiểm tra bản dịch và các diff ở mức văn bản sẽ dễ đọc hơn khi không có các sửa đổi định dạng xen lẫn.

Những Điều Cần Lưu Ý

  • ignore_formatting ghi đè tùy chọn. Nếu bạn đặt options.ignore_formatting = True, các thay đổi đánh số sẽ không được báo cáo, ngay cả khi compare_list_definitions = True.
  • Các tệp không được chứa các phiên bản trước khi bạn so sánh chúng. Nếu bất kỳ tài liệu nào đã có các thay đổi được theo dõi, compare sẽ gây ra một RuntimeError nói rằng các tài liệu được so sánh không được có phiên bản. Hãy chấp nhận hoặc từ chối các phiên bản hiện có trước. Điều này cũng có nghĩa là bạn không thể thực hiện so sánh thứ hai trên một tài liệu đã chứa kết quả của lần so sánh đầu tiên; hãy tải lại các tệp mỗi lần.
  • Các phiên bản khác vẫn xuất hiện. Văn bản được chèn hoặc xóa trong một mục danh sách sẽ được báo cáo bất kể tùy chọn bật hay tắt, vì vậy hãy kiểm tra revision_type nếu bạn cần tách biệt các thay đổi đánh số khỏi các thay đổi về nội dung.

Các bước tiếp theo

Bài viết Compare Documents trong tài liệu Aspose.Words for Python đề cập đến các cài đặt so sánh khác, bao gồm độ chi tiết, mục tiêu so sánh và các tùy chọn bỏ qua.

Câu hỏi thường gặp

  1. Tại sao Aspose.Words không phát hiện sự thay đổi đánh số khi so sánh các tệp Word? Mặc định, Aspose.Words tuân theo Microsoft Word và bỏ qua các định nghĩa danh sách, chẳng hạn như kiểu đánh số hoặc ký tự dấu đầu dòng, trong quá trình so sánh. Một danh sách chuyển từ số sang dấu đầu dòng sẽ không tạo ra bất kỳ sửa đổi nào trừ khi bạn bật compare_list_definitions.

  2. Làm thế nào để tôi phát hiện sự thay đổi đánh số trong Python? Tạo CompareOptions, đặt options.advanced_options.compare_list_definitions thành True, và truyền các tùy chọn này cho Document.compare. Mỗi đoạn danh sách mà số thứ tự hoặc dấu đầu dòng thay đổi sẽ nhận được một revision FORMAT_CHANGE.

  3. Thay đổi đánh số tạo ra loại sửa đổi nào? Mỗi đoạn danh sách bị ảnh hưởng sẽ nhận một sửa đổi loại RevisionType.FORMAT_CHANGE. Chấp nhận nó sẽ áp dụng định dạng danh sách của tệp đã chỉnh sửa, và từ chối nó sẽ giữ nguyên bản gốc.

  4. Tùy chọn này có hoạt động cùng với ignore_formatting không?
    Không. Khi CompareOptions.ignore_formatting là True, các thay đổi đánh số không được báo cáo, ngay cả khi compare_list_definitions là True.

  5. Document.compare trả về gì? Không có gì. Nó ghi các khác biệt dưới dạng revision vào tài liệu mà bạn gọi hàm, vì vậy bạn đọc chúng từ bộ sưu tập revisions của tài liệu đó.

  6. Phiên bản nào của Aspose.Words for Python đã thêm tùy chọn này? Thuộc tính compare_list_definitions của AdvancedCompareOptions đã được thêm vào Aspose.Words for Python via .NET 26.9.

Nhận Giấy Phép Miễn Phí và Hỗ Trợ