iT邦幫忙

2025 iThome 鐵人賽

DAY 21
1

Word 文件自動化 — 從開啟到儲存的完整操作鏈 (8)

先祝大家中秋節快樂,我也要去開心烤肉了
https://ithelp.ithome.com.tw/upload/images/20251005/20177921N3ejCr3vrx.jpg

在前面幾篇文章中,我們探討了內容生成和檔案分析系統,今天我們要深入「文件操作核心」:Word 文件自動化系統

這個系統實現了從空白文件開啟、內容寫入、文件修改到最終儲存的完整自動化工作流程,讓 AI 助手能夠直接操作 Microsoft Word 應用程式,提供真正的辦公自動化體驗。


功能簡介

Word 文件自動化系統提供:

  • 智能文件開啟:支援空白文件和帶內容文件的開啟
  • 內容智能管理:自動選擇最新的生成內容、分析結果或上傳檔案
  • 防重複操作機制:避免短時間內重複開啟造成的系統衝突
  • 完整操作鏈:從開啟到寫入到修改到儲存的一站式服務
  • 狀態監控系統:即時檢查 Word 應用程式的運行狀態

核心功能架構

1. 文件開啟系統

系統提供兩種文件開啟方式:

空白文件開啟

def open_blank_word_tool(self, input_text: str) -> str:
    """純粹開啟空白的 Word 應用程式,不寫入任何內容"""
    print(f"[DEBUG] ===== open_blank_word_tool 被調用了! =====")
    print(f"[DEBUG] 準備調用API: {LOCAL_API_BASE}/open-blank-word")
    try:
        response = requests.post(f"{LOCAL_API_BASE}/open-blank-word")
        response.raise_for_status()
        result = response.json()
        print(f"[DEBUG] API回應成功: {result}")
        return result["message"]
    except requests.exceptions.ConnectionError:
        print(f"[DEBUG] API連線失敗")
        return "錯誤:無法連線到本地 API 服務。請確認伺服器已啟動。"
    except Exception as e:
        print(f"[DEBUG] API調用發生錯誤: {e}")
        return f"開啟空白Word時發生錯誤: {e}"

帶內容文件開啟

def open_word_tool(self, content: str) -> str:
    """開啟 Word 並輸入指定內容"""
    print(f"[DEBUG] open_word_tool 被調用,參數: '{content}'")
    
    # 使用統一的時間檢查機制
    import time
    current_time = time.time()
    if hasattr(self, '_last_word_operation_time'):
        time_diff = current_time - self._last_word_operation_time
        if time_diff < 1.5:  # 縮短到1.5秒,使用統一機制
            print(f"[DEBUG] Word在{time_diff:.1f}秒前剛開啟過,避免重複調用")
            return "Word剛開啟過,請稍候..."
    
    # 設置最後操作時間
    self._last_word_operation_time = current_time

智能內容管理系統

內容優先順序機制

# 檢查內容來源優先順序:
# 1. 如果有具體內容,直接使用
# 2. 如果是空內容或要求解答/分析結果,按時間戳檢查最新內容
if (not content.strip() or 
    content.strip() in ["", "解答", "分析結果", "答案"] or
    "解答" in content and len(content.strip()) < 10):
    
    print(f"[DEBUG] 檢測到空內容或請求解答,檢查所有可用內容...")
    
    latest_time = 0
    latest_content = ""
    latest_source = ""
    
    # 檢查分析結果
    if (hasattr(self.app_instance, 'last_analysis_result') and 
        self.app_instance.last_analysis_result.strip()):
        analysis_time = getattr(self.app_instance, 'last_analysis_time', 0)
        if analysis_time > latest_time:
            latest_time = analysis_time
            latest_content = self.app_instance.last_analysis_result
            latest_source = "分析結果"
    
    # 檢查生成內容
    if (hasattr(self.app_instance, 'last_generated_content') and 
        self.app_instance.last_generated_content.strip()):
        gen_time = getattr(self.app_instance, 'last_generated_time', 0)
        if gen_time > latest_time:
            latest_time = gen_time
            latest_content = self.app_instance.last_generated_content
            latest_source = "生成內容"
    
    # 檢查上傳檔案
    if (hasattr(self.app_instance, 'uploaded_file_content') and 
        self.app_instance.uploaded_file_content.strip()):
        upload_time = getattr(self.app_instance, 'last_upload_time', 0)
        if upload_time > latest_time:
            latest_time = upload_time
            latest_content = self.app_instance.uploaded_file_content
            latest_source = "上傳檔案內容"

Word 操作執行引擎

實際執行函數

def _actually_open_word(self, content: str) -> str:
    """實際執行Word開啟的內部函數"""
    print(f"[DEBUG] ===== _actually_open_word 被調用了! =====")
    print(f"[DEBUG] 收到的參數: '{content[:100]}...'")
    
    # 統一使用同一個時間檢查機制,避免衝突
    current_time = time.time()
    if hasattr(self.app_instance.system_tools, '_last_word_operation_time'):
        time_diff = current_time - self.app_instance.system_tools._last_word_operation_time
        if time_diff < 1.5:  # 縮短到1.5秒,防止過度阻擋
            print(f"[DEBUG] Word在{time_diff:.1f}秒前剛開啟過,避免重複調用")
            return "Word剛開啟過,請稍候..."
    
    # 記錄操作時間
    self.app_instance.system_tools._last_word_operation_time = current_time

二次內容檢查機制

# 檢查是否有指定內容,如果沒有則檢查是否有分析結果可用
if (not content.strip() or 
    content.strip() == "您沒有指定內容,這是預設文字。" or
    "沒有預設" in content or 
    "請提供" in content or 
    "我目前沒有" in content or
    len(content.strip()) < 50):  # 如果內容太短,可能是預設回應
    if (hasattr(self.app_instance, 'last_analysis_result') and 
        self.app_instance.last_analysis_result.strip()):
        content = self.app_instance.last_analysis_result
        print(f"[DEBUG] 使用保存的分析結果作為內容,長度: {len(content)}")
    else:
        content = "您沒有指定內容,這是預設文字。"
        print(f"[DEBUG] 沒有找到分析結果,使用預設內容")

API 整合與錯誤處理

try:
    data = {"content": content}
    print(f"[DEBUG] 準備發送的數據長度: {len(str(data))}")
    print(f"[DEBUG] 準備調用API: {LOCAL_API_BASE}/open-word")
    
    response = requests.post(f"{LOCAL_API_BASE}/open-word", json=data, timeout=30)
    
    print(f"[DEBUG] API響應狀態碼: {response.status_code}")
    print(f"[DEBUG] API響應內容: {response.text}")
    
    response.raise_for_status()
    result = response.json()
    
    # 檢查API返回的狀態
    if result.get("status") == "error":
        return f"API錯誤: {result.get('message', '未知錯誤')}"
    
    return result.get("message", "Word操作完成,但沒有返回詳細信息")
except requests.exceptions.ConnectionError as e:
    return f"錯誤:無法連線到本地 API 服務 (127.0.0.1:8000)。請確認伺服器已啟動。詳細錯誤: {e}"
except requests.exceptions.Timeout as e:
    return f"錯誤:API請求超時。詳細錯誤: {e}"
except requests.exceptions.HTTPError as e:
    return f"錯誤:HTTP錯誤 {response.status_code}。響應內容: {response.text}"

主題式內容生成與寫入

def write_to_word_tool(self, topic: str) -> str:
    """生成內容並寫入Word"""
    print(f"[DEBUG] ===== write_to_word_tool 被調用了! =====")
    print(f"[DEBUG] 收到的主題: '{topic}'")
    
    # 使用統一的時間檢查機制
    import time
    current_time = time.time()
    if hasattr(self, '_last_word_operation_time'):
        time_diff = current_time - self._last_word_operation_time
        if time_diff < 1.5:  # 使用統一機制
            print(f"[DEBUG] Word在{time_diff:.1f}秒前剛開啟過,避免重複調用")
            return "Word剛開啟過,內容已經寫入完成。"
    
    try:
        # 先生成內容
        content = self.generate_content_tool(topic)
        print(f"[DEBUG] 生成的內容長度: {len(content)}")
        
        # 然後開啟Word並寫入內容
        result = self.open_word_tool(content)
        print(f"[DEBUG] Word操作結果: {result}")
        
        # 保留所有分析結果,不再清除任何內容
        # 這樣各種專家模式都能正常工作
        print(f"[DEBUG] 保留所有分析結果,支援多次Word操作")
        
        return f"已生成'{topic}'的內容並寫入Word。{result}"
        
    except Exception as e:
        error_msg = f"寫入內容到Word時發生錯誤: {type(e).__name__}: {e}"
        print(f"[DEBUG] {error_msg}")
        return error_msg

最近生成寫入

def write_generated_to_word_tool(self, input_text: str = "") -> str:
    """將最近生成的內容寫入Word"""
    print(f"[DEBUG] ===== write_generated_to_word_tool 被調用了! =====")
    
    try:
        content = ""
        source = ""
        latest_time = 0
        
        # 檢查各種內容的時間戳,選擇最新的
        if (hasattr(self.app_instance, 'last_generated_content') and 
            self.app_instance.last_generated_content.strip()):
            gen_time = getattr(self.app_instance, 'last_generated_time', 0)
            if gen_time > latest_time:
                latest_time = gen_time
                content = self.app_instance.last_generated_content
                source = "生成內容"
                print(f"[DEBUG] 找到生成內容,時間戳: {gen_time}, 長度: {len(content)}")
            
        if (hasattr(self.app_instance, 'last_analysis_result') and 
            self.app_instance.last_analysis_result.strip()):
            analysis_time = getattr(self.app_instance, 'last_analysis_time', 0)
            if analysis_time > latest_time:
                latest_time = analysis_time
                content = self.app_instance.last_analysis_result
                source = "分析結果"
                print(f"[DEBUG] 找到分析結果,時間戳: {analysis_time}, 長度: {len(content)}")
            
        if (hasattr(self.app_instance, 'uploaded_file_content') and 
            self.app_instance.uploaded_file_content.strip()):
            upload_time = getattr(self.app_instance, 'last_upload_time', 0)
            if upload_time > latest_time:
                latest_time = upload_time
                content = self.app_instance.uploaded_file_content
                source = "上傳檔案內容"
                print(f"[DEBUG] 找到上傳檔案內容,時間戳: {upload_time}, 長度: {len(content)}")
        
        print(f"[DEBUG] 選擇最新內容: {source},時間戳: {latest_time}")
        
        if content.strip():
            # 直接調用_actually_open_word避免重複的時間檢查
            result = self._actually_open_word(content)
            print(f"[DEBUG] Word操作結果: {result}")
            
            return f"已將{source}寫入Word。{result}"
        else:
            print(f"[DEBUG] 沒有找到任何可寫入的內容")
            return "沒有找到可寫入的內容。請先生成內容、分析檔案或上傳檔案,然後再寫入Word。"
            
    except Exception as e:
        error_msg = f"將內容寫入Word時發生錯誤: {type(e).__name__}: {e}"
        print(f"[DEBUG] {error_msg}")
        return error_msg

文件修改與狀態管理

文件內容修改

def modify_word_tool(self, content: str) -> str:
    """修改已開啟的 Word 文件內容"""
    try:
        data = {"content": content if content.strip() else "您沒有指定內容,這是預設文字。"}
        response = requests.post(f"{LOCAL_API_BASE}/modify-word", json=data)
        response.raise_for_status()
        result = response.json()
        return result["message"]
    except requests.exceptions.ConnectionError:
        return "錯誤:無法連線到本地 API 服務。請確認伺服器已啟動。"
    except Exception as e:
        return f"修改 Word 時發生錯誤: {e}"

Word 狀態檢查

def check_word_status_tool(self, input_text: str) -> str:
    """檢查Word應用程式狀態"""
    try:
        response = requests.post(f"{LOCAL_API_BASE}/check-word-status")
        response.raise_for_status()
        result = response.json()
        return result["message"]
    except requests.exceptions.ConnectionError:
        return "錯誤:無法連線到本地 API 服務。請確認伺服器已啟動。"
    except Exception as e:
        return f"檢查Word狀態時發生錯誤: {e}"

文件儲存系統

智能檔名處理

def save_word_tool(self, filename: str) -> str:
    """儲存 Word 文件"""
    print(f"[DEBUG] ===== save_word_tool 被調用了! =====")
    print(f"[DEBUG] 收到的檔名: '{filename}'")
    try:
        # 檢查是否提供檔名
        if not filename.strip():
            print(f"[DEBUG] 檔名為空,詢問用戶")
            return "請問要將檔案儲存為什麼名稱?"
        
        # 檢查檔名是否是一般性詞彙,而非真實檔名
        generic_names = ["文件", "檔案", "word文件", "word檔案", "內容", "文字"]
        if filename.strip().lower() in generic_names:
            print(f"[DEBUG] 檔名是一般性詞彙,詢問用戶")
            return "請問要將檔案儲存為什麼名稱?"
        
        print(f"[DEBUG] 準備發送API請求,檔名: '{filename.strip()}'")
        data = {"filename": filename.strip()}
        response = requests.post(f"{LOCAL_API_BASE}/save-word", json=data)
        response.raise_for_status()
        result = response.json()
        print(f"[DEBUG] API響應狀態碼: {response.status_code}")
        print(f"[DEBUG] API響應內容: {result}")
        return result["message"]
    except requests.exceptions.ConnectionError:
        return "錯誤:無法連線到本地 API 服務。請確認伺服器已啟動。"
    except Exception as e:
        return f"儲存 Word 時發生錯誤: {e}"

完整操作工作流程

標準操作流程

1. 內容準備階段
   ↓
2. Word 應用程式開啟
   ↓  
3. 內容寫入/修改
   ↓
4. 文件儲存
   ↓
5. 狀態確認

流程詳細說明

階段一:內容準備

  • 檢查是否有生成的內容、分析結果或上傳檔案
  • 根據時間戳選擇最新的內容
  • 驗證內容的有效性和完整性

階段二:應用程式開啟

  • 檢查是否在冷卻時間內,避免重複操作
  • 選擇開啟空白文件或帶內容文件
  • 與本地 API 服務建立連線

階段三:內容操作

  • 將準備好的內容寫入 Word 文件
  • 支援後續的內容修改和調整
  • 保持與 API 服務的通訊

階段四:文件儲存

  • 驗證檔名的有效性
  • 與用戶互動確認檔名
  • 執行實際的檔案儲存操作

階段五:狀態確認

  • 檢查 Word 應用程式的運行狀態
  • 確認操作是否成功完成
  • 提供用戶最終的操作結果

總結

Word 文件自動化系統是智能助手的「辦公核心」,它:

  • 實現了完整的文件操作自動化,從開啟到儲存的每個環節都有智能支援
  • 提供智能的內容管理機制,自動選擇最新和最相關的內容進行操作
  • 建立了穩定可靠的操作控制系統,避免重複操作和系統衝突
  • 整合了完善的錯誤處理和除錯機制,確保系統穩定性和可維護性

這個系統讓 AI 助手不僅能夠生成和分析內容,更能夠將這些智能成果轉化為實用的 Word 文件,真正實現了從「思考」到「成果」的完整自動化工作流程。


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

尚未有邦友留言

立即登入留言