iT邦幫忙

2025 iThome 鐵人賽

DAY 11
0

儲存 Word 文件 — 完整解析 /save-word (6)

前面我們已經學會:

  1. 開啟空白 Word /open-blank-word
  2. 開啟 Word 並寫入文字 /open-word
  3. 修改已開啟 Word /modify-word

接下來,要把 Word 文件 儲存到指定位置,這就是 /save-word 的功能。


功能

  • 儲存當前開啟的 Word 文件
  • 自動存到桌面
  • 自動檢查檔名衝突並加上數字後綴
  • 支援 .docx.doc
  • 完整錯誤處理,提供明確訊息

核心程式碼與解析

@app.post("/save-word")
def save_word_document(request: WordSaveRequest):
    """
    儲存已開啟的 Word 文件到指定的檔名。
    """
    word_app = None
    try:
        # 初始化 COM,多執行緒環境必須
        pythoncom.CoInitialize()

        # 取得正在運行的 Word,如果失敗則創建新的
        try:
            word_app = win32.GetObject(Class="Word.Application")
        except:
            word_app = win32.Dispatch("Word.Application")
            word_app.Visible = True

        # 確認有文件開啟
        if word_app.Documents.Count == 0:
            return {"status": "error", "message": "錯誤:沒有已開啟的 Word 文件。"}

        doc = word_app.ActiveDocument

        # 檔名處理
        filename = request.filename.strip()
        if not filename:
            return {"status": "error", "message": "錯誤:檔案名稱不能為空。"}
        if not filename.lower().endswith(('.docx', '.doc')):
            filename += '.docx'

        # 取得桌面路徑
        desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
        if not os.path.exists(desktop_path):
            os.makedirs(desktop_path, exist_ok=True)

        full_path = os.path.join(desktop_path, filename)

        # 檔名衝突處理
        counter = 1
        original_path = full_path
        while os.path.exists(full_path):
            name_without_ext = os.path.splitext(original_path)[0]
            ext = os.path.splitext(original_path)[1]
            full_path = f"{name_without_ext}_{counter}{ext}"
            counter += 1

        # 儲存文件,依序嘗試 SaveAs2 / SaveAs / Save
        try:
            doc.SaveAs2(full_path, FileFormat=16)  # 16 = wdFormatXMLDocument (.docx)
        except:
            try:
                doc.SaveAs(full_path)
            except:
                doc.Save()
                full_path = doc.FullName

        logger.info(f"已成功儲存 Word 文件到: {full_path}")
        return {"status": "success", "message": f"已成功儲存 Word 文件到: {full_path}"}

    except Exception as e:
        error_msg = str(e)
        logger.error(f"儲存 Word 時發生錯誤: {error_msg}")

        if "(-2147352567" in error_msg:
            return {"status": "error", "message": "Word 操作失敗。請確保 Word 應用程式正常運行且文件未被鎖定。"}
        elif "(-2146824090" in error_msg:
            return {"status": "error", "message": "Word 命令執行失敗。請檢查檔案權限或嘗試不同的檔案名稱。"}
        else:
            return {"status": "error", "message": f"儲存 Word 時發生錯誤: {error_msg}"}

    finally:
        try:
            pythoncom.CoUninitialize()
        except:
            pass


運作流程

  1. 初始化 COM → 確保多執行緒安全
  2. 連到 Word 或創建新的 Word 實例
  3. 檢查是否有文件開啟
  4. 處理檔名:
    • 加副檔名 .docx
    • 桌面路徑不存在時自動建立
    • 檔名衝突自動加數字後綴
  5. 儲存文件:
    • 優先用 SaveAs2SaveAsSave
  6. 回傳成功或錯誤訊息
  7. 最後釋放 COM 資源

上一篇
DAY 10
系列文
我的 AI 助手開發11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言