python对word提取数据_用pywin32从MS-Word中提取数据

本文讲述了作者在Windows环境下使用python3.3尝试从Word文档中提取字符串的经历。首先尝试将.docx文件转为.txt再用正则表达式解析,但由于格式问题放弃此方法。接着,由于docx模块与python3.3不兼容,作者选择使用pywin32和COM接口。虽然能成功打开文档,但在解析和去除格式方面遇到困难,寻求帮助。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我在Windows中运行python3.3,需要从Word文档中提取字符串。一个星期以来,我一直在寻找最好的方法。最初我试图将.docx文件保存为.txt并使用RE进行解析,但是我在隐藏字符的格式设置上遇到了一些问题-我使用一个脚本打开.docx并另存为.txt。我想知道我是否做了一个正确的文件>SaveAs>.txt,它会去掉奇怪的格式,然后我可以正确地解析?我不知道,但我放弃了这个方法。在

我试图使用docx module,但有人告诉我它与python3.3不兼容。所以我只能使用pywin32和COM。我已经成功地用Excel来获得我需要的数据,但是我在Word上遇到了麻烦,因为文档太少了,而且微软网站上的reading through the object model太难了。在

以下是迄今为止我打开文档的方法:import win32com.client as win32

import glob, os

word = win32.gencache.EnsureDispatch('Word.Application')

word.Visible = True

for infile in glob.glob(os.path.join(r'mypath', '*.docx')):

print(infile)

doc = word.Documents.Open(infile)

所以现在我可以做一些类似的事情

^{pr2}$

看看这些文件的内容,但看起来还是有一些奇怪的格式,我不知道如何真正地通过解析来获取我需要的数据。我可以创建RE,它将成功地找到我正在寻找的字符串,我只是不知道如何使用COM将它们实现到程序中。在

到目前为止,我所掌握的代码大多是通过谷歌找到的。我甚至不认为这有那么难,只是通过微软网站上的对象模型阅读就像阅读一门外语。任何帮助都是非常感谢的。谢谢您。在

编辑:我用来将文件从docx保存到txt的代码:for path, dirs, files in os.walk(r'mypath'):

for doc in [os.path.abspath(os.path.join(path, filename)) for filename in files if fnmatch.fnmatch(filename, '*.docx')]:

print("processing %s" % doc)

wordapp.Documents.Open(doc)

docastxt = doc.rstrip('docx') + 'txt'

wordapp.ActiveDocument.SaveAs(docastxt,FileFormat=win32com.client.constants.wdFormatText)

wordapp.ActiveDocument.Close()

要将 `python-docx` 替换为 `pywin32` 来实现 Word 文档中的文本替换功能,我们需要利用 COM 自动化接口来控制 Microsoft Word 应用程序。以下是修改后的完整代码: ### 修改点说明: 1. **引入 pywin32 相关模块**:`win32com.client` 和 `pythoncom` 是 `pywin32` 提供的核心模块。 2. **创建 Word 应用实例**:通过 COM 创建一个 Word 应用实例,并打开指定的 .docx 文件。 3. **替换文档中的文本**:遍历文档的所有段落并进行文本替换操作。 4. **保存和关闭文档**:在替换完成后保存更改并关闭文档。 下面是完整的 Python 代码示例: ```python import re import os import tkinter as tk from tkinter import filedialog, messagebox, scrolledtext import win32com.client as win32 import pythoncom class WordContentReplacer: @staticmethod def wildcard_to_regex(pattern): """ Convert a Word-like wildcard pattern to a regex pattern. Args: pattern (str): The wildcard pattern string from the user input. Returns: str: Converted regex pattern. """ special_chars = { '?': '.', '*': '.*', '[': '[', ']': ']', '^': '\\^', '$': '\\$', '.': '\\.', '+': '\\+', '-': '\\-', '|': '\\|', '(': '\\(', ')': '\\)', } regex_pattern = '' escape_next = False for char in pattern: if escape_next: regex_pattern += '\\' + char escape_next = False continue if char == '\\': escape_next = True continue if char in special_chars: regex_pattern += special_chars[char] else: regex_pattern += re.escape(char) # Escape all other characters return regex_pattern @staticmethod def replace_text_in_doc(file_path, find_pattern, replace_text, use_wildcards=False, log_func=None): if use_wildcards: find_pattern = WordContentReplacer.wildcard_to_regex(find_pattern) # Create an instance of Word application word_app = win32.DispatchEx('Word.Application') word_app.Visible = False doc = None try: doc = word_app.Documents.Open(file_path) found = False # Process paragraphs for para in doc.Paragraphs: original_text = para.Range.Text.strip() updated_text = re.sub(find_pattern, replace_text, original_text) if updated_text != original_text: para.Range.Text = updated_text found = True if log_func: log_func(f"Paragraph modified: '{original_text}' -> '{updated_text}'\n") # Save changes if found: doc.Save() return found finally: if doc is not None: doc.Close(SaveChanges=0) # Do not save changes on close word_app.Quit() class FileRenamerAndWordEditorApp: def __init__(self, master): self.master = master master.title("文件批量重命名及Word内容替换工具 v1.0") self.log_text = scrolledtext.ScrolledText(master, wrap=tk.WORD, width=80, height=20) self.log_text.grid(row=4, column=0, columnspan=3, padx=10, pady=5, sticky="ew") self.create_widgets() def log(self, message): self.log_text.insert(tk.END, message) self.log_text.yview(tk.END) def create_widgets(self): # 文件夹选择部分 tk.Label(self.master, text="目标文件夹:").grid(row=0, column=0, padx=5, pady=5, sticky="w") self.folder_path = tk.StringVar() tk.Entry(self.master, textvariable=self.folder_path, width=40).grid(row=0, column=1, padx=5) tk.Button(self.master, text="浏览...", command=self.select_folder).grid(row=0, column=2, padx=5) # 重命名选项部分 options_frame = tk.LabelFrame(self.master, text="重命名选项") options_frame.grid(row=1, column=0, columnspan=3, padx=10, pady=5, sticky="ew") tk.Label(options_frame, text="添加前缀:").grid(row=0, column=0, padx=5, sticky="e") self.prefix_entry = tk.Entry(options_frame, width=25) self.prefix_entry.grid(row=0, column=1, pady=2) tk.Label(options_frame, text="添加后缀:").grid(row=1, column=0, padx=5, sticky="e") self.suffix_entry = tk.Entry(options_frame, width=25) self.suffix_entry.grid(row=1, column=1, pady=2) tk.Label(options_frame, text="查找内容:").grid(row=2, column=0, padx=5, sticky="e") self.find_entry = tk.Entry(options_frame, width=25) self.find_entry.grid(row=2, column=1, pady=2) tk.Label(options_frame, text="替换为:").grid(row=3, column=0, padx=5, sticky="e") self.replace_entry = tk.Entry(options_frame, width=25) self.replace_entry.grid(row=3, column=1, pady=2) # Word内容替换部分 word_options_frame = tk.LabelFrame(self.master, text="Word内容替换选项") word_options_frame.grid(row=2, column=0, columnspan=3, padx=10, pady=5, sticky="ew") tk.Label(word_options_frame, text="查找内容及格式:").grid(row=0, column=0, padx=5, pady=5, sticky="ne") self.word_find_text = scrolledtext.ScrolledText(word_options_frame, wrap=tk.WORD, width=40, height=6) self.word_find_text.grid(row=0, column=1, padx=5, pady=5) tk.Label(word_options_frame, text="替换为及格式:").grid(row=1, column=0, padx=5, pady=5, sticky="ne") self.word_replace_text = scrolledtext.ScrolledText(word_options_frame, wrap=tk.WORD, width=40, height=6) self.word_replace_text.grid(row=1, column=1, padx=5, pady=5) # 添加通配符选项的复选框 self.use_wildcards_var = tk.BooleanVar(value=False) tk.Checkbutton( word_options_frame, text="使用通配符", variable=self.use_wildcards_var ).grid(row=2, column=0, columnspan=2, padx=5, pady=5, sticky="nw") # 操作按钮 tk.Button(self.master, text="执行重命名", command=self.execute_rename, bg="#4CAF50", fg="white").grid(row=3, column=0, pady=10) tk.Button(self.master, text="执行Word内容替换", command=self.execute_word_replace, bg="#4CAF50", fg="white").grid(row=3, column=1, pady=10) def select_folder(self): """选择目标文件夹""" folder_selected = filedialog.askdirectory() if folder_selected: self.folder_path.set(folder_selected) def execute_rename(self): """执行重命名操作""" folder = self.folder_path.get() prefix = self.prefix_entry.get().strip() suffix = self.suffix_entry.get().strip() find_str = self.find_entry.get().strip() replace_str = self.replace_entry.get().strip() if not folder: messagebox.showerror("错误", "请先选择目标文件夹") return try: renamed_files = [] for filename in os.listdir(folder): old_path = os.path.join(folder, filename) if os.path.isfile(old_path): # 只处理文件 new_name = filename if find_str: new_name = new_name.replace(find_str, replace_str) if prefix: new_name = prefix + new_name if suffix: name, ext = os.path.splitext(new_name) new_name = f"{name}{suffix}{ext}" new_path = os.path.join(folder, new_name) if new_path != old_path: os.rename(old_path, new_path) renamed_files.append((old_path, new_path)) if renamed_files: details = "\n".join([f"{old} -> {new}" for old, new in renamed_files]) self.log(f"以下文件被重命名:\n{details}\n") messagebox.showinfo("完成", f"文件重命名操作已成功完成!共重命名了 {len(renamed_files)} 个文件。\n详情见日志窗口。") else: self.log("没有需要重命名的文件。\n") messagebox.showinfo("完成", "所有文件已经是最新的名称,无需重命名。") except Exception as e: messagebox.showerror("错误", f"操作失败:{str(e)}") self.log(f"重命名操作失败: {str(e)}\n") def execute_word_replace(self): """执行Word内容替换操作""" folder = self.folder_path.get() find_text = self.word_find_text.get("1.0", tk.END).strip() replace_text = self.word_replace_text.get("1.0", tk.END).strip() if not folder: messagebox.showerror("错误", "请选择目标文件夹") return if not find_text or not replace_text: messagebox.showerror("错误", "请输入查找内容和替换内容") return try: processed_files = [] for filename in os.listdir(folder): if filename.endswith(".docx"): file_path = os.path.join(folder, filename) if WordContentReplacer.replace_text_in_doc(file_path, find_text, replace_text, self.use_wildcards_var.get(), lambda msg: self.log(msg)): processed_files.append(filename) if processed_files: details = "\n".join(processed_files) self.log(f"以下文件的内容进行了替换:\n{details}\n") messagebox.showinfo("完成", f"Word文档内容替换操作已完成!共替换了 {len(processed_files)} 个文件。\n详情见日志窗口。") else: self.log("没有找到需要替换内容的文件。\n") messagebox.showinfo("完成", "所有Word文档内容已经是最新状态,无需替换。") except Exception as e: messagebox.showerror("错误", f"操作失败:{str(e)}") self.log(f"Word内容替换操作失败: {str(e)}\n") if __name__ == "__main__": root = tk.Tk() app = FileRenamerAndWordEditorApp(root) root.mainloop() ``` ### 注意事项: - 使用 `pywin32` 需要安装相应的包:可以通过命令 `pip install pywin32` 安装。 - 这种方法依赖于本地安装有 Microsoft Office(特别是 Word),因此适用于 Windows 平台。 - 在某些情况下,可能需要以管理员权限运行脚本来避免访问权限问题。 这样就可以利用 `pywin32` 实现对 Word 文档中特定文本的查找与替换了。希望这段代码能够满足您的需求。如果有任何疑问或需要进一步的帮助,请随时告知。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值