import win32com.client as win32 import pythoncom import logging from pathlib import Path # 配置日志 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler('docx_merge_win32com.log'), logging.StreamHandler() ] ) logger = logging.getLogger(__name__) # Word常量定义(如果无法从constants模块获取) class WordConstants: wdCollapseEnd = 0 wdSectionBreakNextPage = 2 wdHeaderFooterPrimary = 1 wdHeaderFooterFirstPage = 2 wdHeaderFooterEvenPages = 3 wdBorderBottom = -3 # 下边框常量 wdLineStyleSingle = 1 # 单线样式 class WordDocumentMerger: def __init__(self): # 初始化COM对象 pythoncom.CoInitialize() self.word_app = win32.DispatchEx('Word.Application') self.word_app.Visible = False self.word_app.DisplayAlerts = False self.constants = WordConstants() def merge_documents(self, doc1_path, doc2_path, output_path): """合并两个Word文档""" doc1 = doc2 = None try: logger.info(f"开始合并文档: {doc1_path} 和 {doc2_path}") # 打开文档 doc1 = self.word_app.Documents.Open(str(doc1_path)) logger.info(f"已打开第一个文档: {doc1_path}") doc2 = self.word_app.Documents.Open(str(doc2_path)) logger.info(f"已打开第二个文档: {doc2_path}") # 插入第二个文档的内容 self._insert_document_content(doc1, doc2) # 特别处理页眉格式 self._fix_header_borders(doc1) # 保存合并后的文档 output_path = self._ensure_unique_filename(output_path) doc1.SaveAs(str(output_path)) logger.info(f"已保存合并文档: {output_path}") return output_path except Exception as e: logger.error(f"文档合并失败: {str(e)}", exc_info=True) return None finally: self._cleanup(doc1, doc2) def _insert_section_break(self, doc): """在文档末尾插入分节符""" try: end_range = doc.Content end_range.Collapse(Direction=self.constants.wdCollapseEnd) end_range.InsertBreak(Type=self.constants.wdSectionBreakNextPage) logger.debug("已插入分节符") except Exception as e: logger.error(f"插入分节符失败: {str(e)}") raise def _insert_document_content(self, target_doc, source_doc): """插入文档内容""" try: source_range = source_doc.Content target_range = target_doc.Content target_range.Collapse(Direction=self.constants.wdCollapseEnd) source_range.Copy() target_range.Paste() logger.info("已插入第二个文档内容") # 合并页眉页脚 self._merge_headers_footers(target_doc, source_doc) except Exception as e: logger.error(f"插入文档内容失败: {str(e)}") raise def _merge_headers_footers(self, target_doc, source_doc): """合并页眉页脚""" try: last_section = target_doc.Sections(target_doc.Sections.Count) src_section = source_doc.Sections(1) # 合并页眉 for header_type in [self.constants.wdHeaderFooterPrimary, self.constants.wdHeaderFooterFirstPage, self.constants.wdHeaderFooterEvenPages]: if src_section.Headers(header_type).Exists: src_section.Headers(header_type).Range.Copy() last_section.Headers(header_type).Range.Paste() # 合并页脚 for footer_type in [self.constants.wdHeaderFooterPrimary, self.constants.wdHeaderFooterFirstPage, self.constants.wdHeaderFooterEvenPages]: if src_section.Footers(footer_type).Exists: src_section.Footers(footer_type).Range.Copy() last_section.Footers(footer_type).Range.Paste() logger.info("已合并页眉页脚") except Exception as e: logger.error(f"合并页眉页脚失败: {str(e)}") raise def _fix_header_borders(self, doc): """确保所有页眉都有底部边框线""" try: for section in doc.Sections: for header_type in [self.constants.wdHeaderFooterPrimary, self.constants.wdHeaderFooterFirstPage]: if section.Headers(header_type).Exists: header = section.Headers(header_type).Range if header.Paragraphs.Count > 0: border = header.Paragraphs(1).Borders( self.constants.wdBorderBottom) border.LineStyle = self.constants.wdLineStyleSingle border.LineWidth = 4 logger.info("已修复所有页眉边框线") except Exception as e: logger.error(f"修复页眉边框失败: {str(e)}") def _ensure_unique_filename(self, path): """确保文件名唯一""" path = Path(path) if not path.exists(): return path counter = 1 while True: new_path = path.parent / f"{path.stem}_{counter}{path.suffix}" if not new_path.exists(): return new_path counter += 1 def _cleanup(self, *docs): """清理资源""" try: for doc in docs: if doc and hasattr(doc, 'Close'): doc.Close(SaveChanges=False) if hasattr(self, 'word_app') and self.word_app: self.word_app.Quit() pythoncom.CoUninitialize() logger.info("已清理资源") except Exception as e: logger.error(f"清理资源失败: {str(e)}") # if __name__ == "__main__": # merger = WordDocumentMerger() # # 修改为您的实际文件路径 # doc1_path = Path(r"C:\Users\VogelimKafig\Desktop\金风模板\jingfeng_fengmian1.docx") # doc2_path = Path(r"C:\Users\VogelimKafig\Desktop\金风模板\quexian.docx") # output_path = Path(r"C:\Users\VogelimKafig\Desktop\金风模板\merged_document.docx") # if merger.merge_documents(doc1_path, doc2_path, output_path): # print(f"合并成功! 输出文件: {output_path}") # else: # print("合并失败,请查看日志文件。")