• 9、【办公自动化】Python实现Word文件的批量操作


    说明

    上一篇介绍了【Python 实现 PDF 文件的批量操作】,这篇将介绍通过 Python 实现 Word 文档的批量操作。Word 作为日常办公重要且常用的文档之一,经常也会遇到一些繁琐的操作场景,比如批量生成某一类型的 Word 文档,批量对 Word 文档的关键字进行标注、替换或者删除,批量将 Word 文档转换成其他格式的文件等。为了提升工作的效率,通过 Python 解决这些场景的方式,有必要了解下。

    Word 文件的后缀有.doc 和 .docx 格式,以下模块支持 word 文档的读写:

    • python-docx:只支持.docx 格式,但可以将 .doc 转成 .docx 格式,从而间接支持 .doc 格式;
    • pywin32:调用系统的word功能,可以同时支持.doc 和 .docx 格式;

    接下来,使用会涉及到这两个模块的使用,可以通过 pip 命令先下载这些模块,

    1. pip install python-docx
    2. pip install pywin32

    需要注意,python-docx 模块在 import 时,名称是 docx;pywin32 模块在导入时,名称是win32com。

    1、批量生成Word文档

    我们知道,在平时办公中,如果使用 Word 文档的 "邮件合并" 功能,可以批量制作一些主要内容相同、只是部分数据不一样的文档,比如邀请函、通知单、采购合同、成绩单等。Python 也可以实现类似的功能,通过套用指定的模板批量生成 Word 文档。

    以邀请函的批量制作为例,首先准备一份模板,内容如下:

    邀请函中需要替换的字段都用 英文单词 标记,而填充到模板中的具体信息,可以放在 Excel 表格保存,需要注意的是,Excel 表格各列的标题必须与模板中的字段名保持一致,如下:

    代码实现的思路也比较简单:从 Excel 表格中逐行读取数据,然后在 Word 模板文档中查找对应的字段进行替换,最后保存替换后的 Word 文档,完成邀请函的批量制作。

    引入的模块:

    1. from docx import Document
    2. from openpyxl import load_workbook

    自定义替换标记内容的方法,如下:

    1. def process_replace(doc, header, data):
    2. # 段落(不支持表格文本)、具有相同样式的一段连续文本、文本内容
    3. paragraphs = doc.paragraphs
    4. # print("paragraphs is not null.")
    5. if len(paragraphs) > 0:
    6. for paragraph in paragraphs:
    7. runs = paragraph.runs
    8. if len(runs) > 0:
    9. for run in runs:
    10. run.text = run.text.replace(header, data)
    11. print(f"run.text: { run.text}")
    12. # 含表格的文本
    13. tables = doc.tables
    14. if len(tables) > 0:
    15. # print("tables is not null.")
    16. for table in tables:
    17. rows = table.rows
    18. if len(rows) > 0:
    19. for row in rows:
    20. cells = row.cells
    21. if len(cells) > 0:
    22. for cell in cells:
    23. cell.text = cell.text.replace(header, data)

    读取 Excel ,经过替换处理后,批量生成带公司名称的 Word 文档:

    1. def process(doc_path, excel_path):
    2. wb = load_workbook(excel_path)
    3. sheet = wb.active
    4. for row in range(2, sheet.max_row + 1):
    5. doc = Document(doc_path)
    6. for col in range(1, sheet.max_column + 1):
    7. # 表头和数据
    8. header = str(sheet.cell(row=1, column=col).value)
    9. data = str(sheet.cell(row=row, column=col).value)
    10. # 更新word文档
    11. process_replace(doc, header, data)
    12. # 批量保存,使用excel的第6列的【公司】作为word文档的后缀名称
    13. column_name = str(sheet.cell(row=row, column=6).value)
    14. doc.save(f'{base_path}{column_name}邀请函.docx')

    测试如下:

    1. if __name__ == '__main__':
    2. base_path = "D:\\XXX\\test-word\\doc_invitation\\"
    3. doc_path = base_path + "邀请函.docx"
    4. excel_path = base_path + "邀请函的明细.xlsx"
    5. process(doc_path, excel_path)

    效果如下:

     打开其中的一个 Word 文档,验证替换效果,如下:

    完美~~

    2、批量操作Wor文档的关键词

    2.1 批量标注关键词

    有时候,我们可能比较关心 Word 文档里的某些关键词,如果搜索一篇几十页的文档的话,每次只能查找一个关键词,极不方便,有没有办法将我们关心的关键词列表在文档显著的标注出来呢?这样翻看的时候,既能抓住重点,也能避免漏掉关键信息的说明。

    基于这种需求场景,接下来使用 Python 实现对 Word 文档的关键词进行批量标注。思路是,使用win32com 模块模拟打开 Word 文档的过程,并在此过程中对指定的关键词列表进行查找和样式标记,全部查找并标注完成后,调用另存为方法对新的 Word 文档保存。

    首先,导入相关依赖:

    import win32com.client

    接着,开始编码实现,如下:

    1. def tag_word(wordPath, newWordPath,keywordList):
    2. # 打开office窗口,并设置隐藏(后台运行),之后就可以打开Word文档了
    3. app = win32com.client.gencache.EnsureDispatch('Word.Application')
    4. app.Visible = False
    5. word = app.Documents.Open(wordPath)
    6. # 设置样式
    7. constants = win32com.client.constants
    8. colorList = [constants.wdRed, constants.wdYellow, constants.wdBlue, constants.wdGreen]
    9. process_style(app, constants, keywordList, colorList)
    10. # 另存为新Word文档
    11. word.SaveAs(newWordPath)
    12. # 关闭
    13. word.Close()
    14. app.Quit()

    在设置样式时,可自定义设置要标注的样式,如下:

    1. def process_style(app, constants, keywordList, colorList):
    2. if len(keywordList) > 0 and len(colorList) and len(keywordList) == len(colorList):
    3. for keyword, color in zip(keywordList, colorList):
    4. app.Options.DefaultHighlightColorIndex = color
    5. obj = app.Selection.Find
    6. obj.ClearFormatting()
    7. obj.Text = keyword
    8. obj.Replacement.ClearFormatting()
    9. obj.Replacement.Text = keyword
    10. obj.Replacement.Font.Bold = True #设置加粗
    11. obj.Replacement.Font.Italic = True #设置斜体
    12. obj.Replacement.Font.Underline = constants.wdUnderlineDouble #设置下划线
    13. obj.Replacement.Highlight = True #高亮显示
    14. obj.Execute(Replace=constants.wdReplaceAll)

    然后,就可以测试了,测试代码如下:

    1. if __name__ == '__main__':
    2. basePath = 'D:\\XXX\\test-word\\doc_tag\\'
    3. wordPath = basePath + '公司考勤制度(参考).docx'
    4. newWordPath = basePath + '关键词批量标注_公司考勤制度(参考).docx'
    5. keywordList = ['旷工', '迟到', '早退', '加班']
    6. tag_word(wordPath, newWordPath, keywordList)

    在网上搜索了一篇关于考勤制度的 Word 文档说明,有几十页之多,说实话每个人可能不会去耐心看完的!而我比较关心'旷工', '迟到', '早退', '加班'等关键词信息,这里通过批量标注,来选择性的阅读。测试效果,如下:

    打开【关键词批量标注_公司考勤制度(参考).docx】,看一下:

    以后阅读这种长篇的 Word 文档,通过批量标注的方式就可以提升效率了~~

    2.2 批量替换/删除关键词

    有了批量标注 Word 文档关键词的思路之后,实现批量替换/删除就很简单了,其实就是将 colorList 里颜色常量,修改成替换后的关键词,如下:

    replaceList = ["KG", "CD", "ZT", "JB"]

    样式设置的话,略做修改:

    1. def process_replace(app, constants, keywordList, replaceList):
    2. if len(keywordList) > 0 and len(replaceList) and len(keywordList) == len(replaceList):
    3. for old_kw, replace_kw in zip(keywordList, replaceList):
    4. obj = app.Selection.Find
    5. obj.ClearFormatting()
    6. obj.Text = old_kw #原关键词
    7. obj.Replacement.ClearFormatting()
    8. obj.Replacement.Text = replace_kw #替换后的关键词
    9. obj.Replacement.Font.Bold = True
    10. obj.Replacement.Font.Italic = True
    11. obj.Replacement.Font.Underline = constants.wdUnderlineDouble
    12. obj.Replacement.Highlight = True
    13. obj.Execute(Replace=constants.wdReplaceAll)

    仍以考勤制度的 Word 文档为例:

     打开【关键词批量替换_公司考勤制度(参考).docx】,效果如下:

    效果看上去还不错,如果批量删除的话,就更简单了,把 colorList 都用空字符串填充即可。

    3、批量将Word文件转成其他格式文件

    3.1 Word 转 txt

    这里,使用 win32com 模块,通过 SaveAs("输出路径", 2)  核心 API 即可实现 Word 转 txt。思路是 模拟打开 Word 文档,并另存为... 的操作过程。实现如下:

    1. import win32com.client
    2. def doc2txt(wordPath, txtPath):
    3. # 打开office,再打开word
    4. app = win32com.client.Dispatch('Word.Application')
    5. word = app.Documents.Open(wordPath)
    6. # 转储到其他文件:2为txt,空为原格式
    7. word.SaveAs(txtPath, 2)
    8. print("文件转储成功!!!")
    9. # 关闭连接
    10. word.Close()
    11. app.Quit()

    转换效果,如下:

    需要注意,如果 Word 文档含有图片、表格、图表等特殊区域元素的话,这些是不会被转储到 txt 文件的!!

    3.2 Word 转 PDF

    批量将 Word 文档转换成 PDF 文件,在之前的文章详细说明过,可以参考 4、【办公自动化】Python实现Word转PDF ,这里不再赘述了。

    3.3 Word 转 图片

    有时候,我们可能还会遇到将 Word 文档内容直接贴出来,而不是发送 Word 文档。比如,写博客文章时贴图,又比如 PPT 引用图片等场景。这样的话,靠截图可以简单实现,如果 Word 文档页数很多,一张张截图未免太麻烦了,这时候将 Word 文档转换成图片才是明智之举。

    如何将 Word 文档转换成图片呢?有个可行的思路,如下:

    • 先将 Word 转换成 PDF;
    • 再利用 PDF 的 pdfplumber 模块的 to_inmage() 方法转换成图片;
    • 最后为了满足转换不同格式的图片,可编写个图片格式转换器。

    第一步,就是 4.2 描述的场景,第二步在上篇的【提取PDF文件的内容】的【提取图片】有说明过,这些都是验证过并现成的,不再赘述了。

    这里,重点实现下图片格式转换器,前面都是默认的 .png 格式,如果转成其他格式,可以自定义实现,如下:

    1. from pathlib import Path
    2. from PIL import Image
    3. src_format = input("请输入要转换的图片格式: ")
    4. desc_format = input("请输入转换后的图片格式: ")
    5. path = input('请输入要转换的图片所在的路径:')
    6. # 输出路径
    7. desc_dir = Path(path + "convert\\")
    8. # 自定义转换
    9. for i in list(Path(path).glob(f"*.{src_format}")):
    10. desc_file = (desc_dir / i.name).with_suffix(f".{desc_format}")
    11. Image.open(i).save(desc_file)
    12. print(f'{i.name} 已转换成{desc_format}')

    测试用的图片默认的是 .jpg,需要转换成 .png 或 .bmp 格式,转换后的效果,如下:

     经过这三步,就可以轻松实现 Word 转换成图片的需求了,so easy啊!

  • 相关阅读:
    百趣代谢组学文献分享:三组学整合分析在中医药研究中的应用
    OpenRadar DOA函数 Bartlett/CBF和Capon使用
    k8s、数据存储
    消息队列-rabbitMq
    巨额亏损,股价遭受重创,Polestar极星汽车已陷入困境
    【教程】几种不同的RBF神经网络
    本地知识库开源框架Fastgpt、MaxKB产品体验
    acwing算法基础之搜索与图论--最短路问题
    (附源码)ssm失物招领系统 毕业设计 182317
    九、数据仓库详细介绍(元数据)
  • 原文地址:https://blog.csdn.net/qq_29119581/article/details/127591930