使用 Flask 和 Python 自動化 Word 分割工具

在這篇文章中將介紹如何利用 Python 和 Flask 開發一個簡單的工具,來實現將 Microsoft Word 文件按照節(Section)分割為多個文件的功能。同時我們會使用 Bootstrap 來提升前端頁面的可讀性和操作便利性。

專案功能簡介

本專案的目標是提供一個 Web 介面,讓用戶可以:

  1. 上傳一個包含多個 Sections 的 Word 文件。
  2. 上傳一個對應的文件名稱清單。
  3. 根據名稱清單分割原始文件並生成多個 Word 文件。
  4. 自動刪除頁腳並套用新頁腳內容(若需要)。

這個工具對需要批量處理 Word 文件的人來說是非常實用的,比如需要將長文檔分解為不同部門的文件時。


技術架構與工具

  1. 後端框架:Flask
  2. 文檔操作pywin32(使用 Windows COM 操作 Word)
  3. 前端框架:Bootstrap 5
  4. 文件上傳與處理:Flask 的 request.files
  5. 目錄管理os 模組

核心程式碼解析

文件分割功能

以下是實現文件分割功能的核心程式碼片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
def split_by_section_with_names(input_doc_path, output_dir, filenames):
pythoncom.CoInitialize() # 明確初始化 COM
try:
word_app = win32.Dispatch("Word.Application")
word_app.Visible = False

doc = word_app.Documents.Open(input_doc_path)
total_sections = doc.Sections.Count

if len(filenames) + 1 < total_sections:
doc.Close(False)
word_app.Quit()
return f"Error: Insufficient filenames provided. Expected at least {total_sections - 1}, got {len(filenames)}."

for i in range(1, total_sections):
section_range = doc.Sections(i).Range
new_doc = word_app.Documents.Add()
section_range.Copy()
new_doc.Range().Paste()

for sec_idx in range(1, new_doc.Sections.Count + 1):
sec = new_doc.Sections(sec_idx)
remove_and_set_footer(sec)

output_path = os.path.join(output_dir, f"{filenames[i - 1]}.docx")
new_doc.SaveAs2(output_path, FileFormat=WD_FORMAT_XML_DOCUMENT)
new_doc.Close(False)

doc.Close(False)
word_app.Quit()
return "Split completed successfully. Files saved to output directory."
finally:
pythoncom.CoUninitialize() # 確保釋放 COM

關鍵功能解析

  1. 初始化與操作 Word 文件

    • 利用 win32.Dispatch 操作 Word 應用程式,通過 COM 介面開啟指定的 Word 文件。
  2. 分割 Sections

    • 遍歷 Word 文件中的 Sections,將每個 Section 複製到新的 Word 文件中。
  3. 頁腳處理

    • 呼叫 remove_and_set_footer 函數,刪除原有的頁腳並可設定新的頁腳文字。
  4. 文件保存

    • 使用 SaveAs2 方法將文件保存為 .docx 格式。

Flask 後端路由

透過以下程式碼實現 Web 介面的邏輯處理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
doc_file = request.files['doc_file']
filename_file = request.files['filename_file']

if not doc_file or not filename_file:
flash('Both DOCX and Filename files are required!', 'danger')
return redirect(url_for('index'))

doc_path = os.path.join(UPLOAD_FOLDER, secure_filename(doc_file.filename))
filename_path = os.path.join(UPLOAD_FOLDER, secure_filename(filename_file.filename))

doc_file.save(doc_path)
filename_file.save(filename_path)

filenames = load_filenames(filename_path)
result = split_by_section_with_names(doc_path, OUTPUT_FOLDER, filenames)

# 處理完成後清空 upload 資料夾
clear_upload_folder()

if result.startswith("Error"):
flash(result, 'danger')
else:
flash(f"{result} Output folder: {OUTPUT_FOLDER}", 'success')

return redirect(url_for('index'))

return render_template('index.html')

功能概述

  1. 文件上傳

    • 接收用戶上傳的 Word 文件及名稱清單文件,並保存到伺服器的臨時目錄。
  2. 名稱清單加載

    • 使用 load_filenames 函數解析名稱清單,確保其格式正確。
  3. 分割與結果反饋

    • 調用 split_by_section_with_names 完成文件分割,並通過 Flash 消息告知用戶操作結果。

前端設計

我們使用 Bootstrap 5 快速構建了一個簡單的表單頁面:

1
2
3
4
5
6
7
8
9
10
11
<form action="/" method="post" enctype="multipart/form-data">
<div class="mb-3">
<label for="doc_file" class="form-label">請上傳 Word 檔案:</label>
<input type="file" name="doc_file" id="doc_file" class="form-control" required>
</div>
<div class="mb-3">
<label for="filename_file" class="form-label">請上傳 Filename 清單:</label>
<input type="file" name="filename_file" id="filename_file" class="form-control" required>
</div>
<button type="submit" class="btn btn-primary">開始分割</button>
</form>

如何部署

需求

  1. 安裝 Python 相關模組:
    1
    pip install flask pywin32
  2. 確保系統安裝了 Microsoft Word。

執行伺服器

運行以下指令啟動本地伺服器:

1
python app.py

然後打開瀏覽器訪問 http://127.0.0.1:5000


結語

這個工具展示了如何結合 Python 的 COM 技術與 Flask 架構,實現一個功能強大且易於使用的 Word 文件分割工具。透過此專案,您可以輕鬆處理多節文件並生成自定義名稱的分割檔案。

歡迎根據需要擴展此工具,例如增加更多文檔格式支持或加入進階的樣式處理功能!