在這篇文章中將介紹如何利用 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 模組

核心程式碼解析

文件分割功能

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

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 介面的邏輯處理:

@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 快速構建了一個簡單的表單頁面:

<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 相關模組:
    pip install flask pywin32
    
  2. 確保系統安裝了 Microsoft Word。

執行伺服器

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

python app.py

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