用python将word文档合并实例代码

作者:task138 时间:2021-08-13 06:17:01 

背景:

        由于工作需要,现在有这么一个需求,要合并大量的word文档,而且要在不同的目录下找到同一个人的word文档,进行合并,最终输出一个合并后的word文档。一般来说几个或者十几个量不多的话,就手工合并一下好了,但现在这个量是真的大。目录有十多个,每个目录又有50多个不同人的word文档,而且同一个人在不同目录下又不一定都有word文档,因此,整个合并工作就出现了人工操作的困难:

工作量多;容易疏漏犯错。

 为此,利用python进行高效准确的执行这类工作,尤为凸显现代自动化办公的能力。因此,我写了这个python脚本,作为一个小工具来辅助我的工作需求。

设计思路:

        首先,整个脚本实现两个功能:

查看各目录下未提交word文档的名单合并各目录下的word文档查看各目录未提交名单:

        对于这个需求,首先是读一个写有所有人姓名等信息的Excel文件,有格式要求。然后通过遍历Excel的信息,获取到所有人的姓名。遍历各目录下,是否有对应姓名的文件存在,如果没有,则输出没有提交文件的姓名。

合并word文件:

        合并word文件和上一个需求有类似的地方。首先我们都需要读Excel文件,得到姓名信息,然后在各目录下获取到这个人所提交的所有word文件的文件路径,然后通过合并word的操作实现文件合并,合并后最终输出到指定的目录下。

脚本环境说明:

        脚本对第三方包有依赖,执行前必须先安装对应的第三方包


pip install python-docx pywin32 xlrd

        首先,目录结构必须是如下图所示,所有需要遍历的目录名称都必须是【实训+数字】,因为脚本中涉及多处正则匹配。

用python将word文档合并实例代码

        其次,Excel文件必须遵循下图所示的格式,首行是标题行,遍历的时候会自动跳过,遍历时会遍历C列和D列,其中C列是人员编号,D列是人员姓名

 用python将word文档合并实例代码

        接着,python脚本必须要根目录下

        最后,执行脚本的时候,必须带有传参,传递的参数就是那个Excel表


Microsoft Windows [版本 10.0.19043.1415]
(c) Microsoft Corporation。保留所有权利。

C:\Windows\system32>python tools.py 花名册.xlsx

完整代码:


#! /usr/bin env python
# -*- coding:utf-8 -*-

"""
============================
======Power By Python3======
====== Author Task138 ======
============================
"""

import sys
import xlrd, os, re
from docx import Document
from docxcompose.composer import Composer
from win32com import client as wc

# 读Excel表获取学生的学号和姓名
def read_excel(excel_file):
   workbook = xlrd.open_workbook(excel_file)
   sheet = workbook.sheet_by_index(0)
   name_list = []
   name_dict = []

Sno_list = sheet.col_values(2)[1::]
   Sname_list = sheet.col_values(3)[1::]
   for i in range(len(Sno_list)):
       try:
           Sno = str(int(Sno_list[i]))
       except:
           Sno = Sno_list[i]
       dict = {}
       dict['Sno'] = Sno
       dict['Sname'] = Sname_list[i]
       name_list.append(Sname_list[i])
       name_dict.append(dict)

return name_list, name_dict

# 合并文档
def merge_doc(source_file_path_list,target_file_path):
   #填充分页符号文档
   page_break_doc = Document()
   page_break_doc.add_page_break()
   #定义新文档
   target_doc = Document(source_file_path_list[0])
   target_composer = Composer(target_doc)
   for i in range(len(source_file_path_list)):
       #跳过第一个作为模板的文件
       if i==0:
           continue
       #填充分页符文档
       target_composer.append(page_break_doc)
       #拼接文档内容
       f = source_file_path_list[i]
       target_composer.append(Document(f))
   #保存目标文档
   target_composer.save(target_file_path)
   print('[ %s ]保存成功' % target_file_path)

if __name__ == '__main__':
   if len(sys.argv) < 2:
       print('缺乏必要的参数,请输入学生Excel表作为参数')
       print('程序终止')
       exit()

excel_file = sys.argv[1]

print('请选择需要执行的功能:')
   print('[ 0 ] 查看各实训目录下未提交的学生名单')
   print('[ 1 ] 合并实训文件')
   cmd = input('请选择: ')

while cmd not in ['0','1']:
       print('输入有误,请重新输入,按 Ctrl+C 可退出程序')
       print('请选择需要执行的功能:')
       print('[ 0 ] 查看各实训目录下未提交的学生名单')
       print('[ 1 ] 合并实训文件')
       cmd = input('请选择: ')

try:
       name_list, name_dict = read_excel(excel_file)
   except Exception as e:
       print('Excel读取失败,程序终止,错误如下:')
       print(e)
       print()
       exit()
   else:
       if cmd == '0':
           # 实训目录的数列
           file_list = []
           for i in os.listdir():
               if os.path.isdir(i):
                   if re.match(r'实训\d', i):
                       file_list.append(i)

for i in range(1, len(file_list) + 1):
               dir_name = '实训%s' % i
               # 进入该实训目录
               os.chdir(dir_name)
               file_list = os.listdir()
               submit_list = []
               for x in file_list:
                   for j in name_list:
                       if j in x and j not in submit_list:
                           submit_list.append(j)
               result = list(set(submit_list) ^ set(name_list))
               if result:
                   print(dir_name, result)
               os.chdir('../')

if cmd == '1':
           if not os.path.exists('实训汇总'):
               os.mkdir('实训汇总')
               print('目录[ 实训汇总 ]创建成功')

# 实训目录的数列
           file_list = []
           for i in os.listdir():
               if os.path.isdir(i):
                   if re.match(r'实训\d',i):
                       file_list.append(i)

for i in name_dict:
               doc_list = []
               for j in range(1,len(file_list)+1):
                   dir_name = '实训%s' % j
                   # 进入该实训目录
                   os.chdir(dir_name)

tmp = []
                   for x in os.listdir():
                       # 判断文件尾缀
                       fname,fext = os.path.splitext(x)
                       # 如果是.doc,则转换为.docx
                       if fext == '.doc' and not x.startswith('~$'):
                           w = wc.Dispatch('Word.Application')
                           doc = w.Documents.Open(os.path.abspath(x))
                           doc.SaveAs(os.path.join(os.getcwd(),'%s.docx' % fname), 16)
                           doc.Close()
                           os.remove(x)
                           print('转换文件[ %s ]类型为.docx' % x)
                       elif fext == '.docx':
                           if (i['Sname'] in x) and (len(tmp) == 0):
                               # 只有一个文件
                               tmp.append(x)
                           elif (i['Sname'] in x) and (len(tmp) != 0):
                               # 有多个文件,按照最新的修改时间进行替换
                               tmp_file = tmp.pop()
                               old_file_mtime = os.path.getmtime(tmp_file)
                               new_file_mtime = os.path.getmtime(x)
                               if new_file_mtime > old_file_mtime:
                                   # 新文件比较新,以新的为准
                                   tmp.append(x)
                               else:
                                   # 老文件比较新,以老文件为准
                                   tmp.append(tmp_file)
                       else:
                           # 其它文件类型,直接跳过
                           # print('当前文件[ %s ]类型不是.doc或者.docx,跳过此文件的合并' % os.path.abspath(x))
                           continue

if tmp:
                       # 如果这次实训有这位同学的文件
                       doc_list.append(os.path.join(dir_name,tmp.pop()))
                   # 返回父目录
                   os.chdir('../')
               if doc_list:
                   # 有内容,进行文档合并
                   try:
                       merge_file_name = i['Sno'] + '-' + i['Sname'] + '-' + '实训汇总' + '.docx'
                       merge_doc(doc_list, './实训汇总/' + merge_file_name)
                   except Exception as e:
                       print()
                       print('[ %s ]学生信息有误,程序中断' % i['Sname'])
                       print(e)
                       print()

功能执行效果图:

用python将word文档合并实例代码

用python将word文档合并实例代码

总结:

通过python,我们可以很便捷的满足我们的需求,鉴于这个需求似乎是长期性的,所以还是有必要写个小工具来优化一下自己的办公方式,提高自己的业务能力。

来源:https://blog.csdn.net/cbcrzcbc/article/details/122052694

标签:python,合并,word
0
投稿

猜你喜欢

  • Pandas 按索引合并数据集的方法

    2023-06-01 13:35:10
  • 详解python中的lambda与sorted函数

    2022-04-29 00:01:56
  • Python3.8.2安装包及安装教程图文详解(附安装包)

    2021-11-17 19:35:14
  • matplotlib图形整合之多个子图绘制的实例代码

    2023-10-23 23:17:47
  • Golang学习笔记(一):简介

    2024-02-22 18:59:28
  • Python爬虫JSON及JSONPath运行原理详解

    2023-02-21 17:59:48
  • 动易CMS:九个常见的错误原因分析及解决方法(ZT)

    2008-07-01 12:40:00
  • 手把手带你走进Go语言之常量解析

    2024-05-08 10:44:38
  • Python绘制动态的521玫瑰花

    2021-05-05 09:31:03
  • sql的临时表使用小结

    2024-01-25 19:50:31
  • 文字适度阅读的宽度或者字数

    2007-10-26 07:31:00
  • Python 面向切面编程 AOP 及装饰器

    2021-05-07 14:16:36
  • Python获取浏览器窗口句柄过程解析

    2022-05-25 10:37:33
  • python区块链创建多个交易教程

    2021-05-28 13:40:42
  • 利用tkinter改变下拉列表(Combobox)的选项值

    2023-07-20 03:10:37
  • Python实战之外星人入侵游戏示例代码

    2023-12-23 08:18:18
  • 分析python并发网络通信模型

    2023-12-15 11:13:59
  • python3.8下载及安装步骤详解

    2023-11-19 18:47:02
  • asp中判断服务器是否安装了某种组件的函数

    2011-02-16 10:53:00
  • MySQL事务管理的作用详解

    2024-01-23 21:20:37
  • asp之家 网络编程 m.aspxhome.com