• Python办公自动化之Excel转Word


    在日常工作中,Python在办公自动化领域应用非常广泛,如批量将多个Excel中的数据进行计算并生成图表,批量将多个Excel按固定格式转换成Word,或者定时生成文件并发送邮件等场景。本文主要以一个简单的小例子,简述Python在Excel和Word方面进行相互转换的相关知识点,谨供学习分享使用,如有不足之处,还请指正。

    相关知识点

    本文主要是将Excel文件通过一定规则转换成Word文档,涉及知识点如下所示:

    • xlrd模块:主要用于Excel文件的读取,相关内容如下:
      • xlrd.open_workbook(self.excel_file) 打开Excel文件并返回文档对象,参数为Excel的完整路径
      • book.sheet_by_name(self.sheet_name) 通过名称获取对应的sheet页,并返回sheet对象
      • sheet.nrows sheet页的有效行数
      • sheet.ncols sheet页的有效列数
      • sheet.row_values(0) 返回Excel中对应sheet页的第一行的值,以数组返回
      • sheet.cell_value(row, col) 返回某一个单元格的值
    • python-docx模块:主要操作Word文档,如:表格,段落等相关,相关内容如下所示:
      • Document word的文档对象,代表整个word文档
      • doc.sections[0] 获取章节
      • doc.add_section(start_type=WD_SECTION_START.CONTINUOUS) 添加连续章节
      • doc.add_heading(third, level=2) 增加标题,level表示级别,如二级标题,返回标题对象
      • doc.add_paragraph(text='', style=None) 增加段落,返回段落对象
      • doc.add_table(rows=4, cols=5) 增加表格,并返回表格对象
      • doc_table.style = "Table Grid" 设置表格样式
      • doc_table.rows[0].cells[1].merge(doc_table.rows[0].cells[4]) 合并单元格
      • doc_table.rows[3].cells 获取表格某一行所有单元格,以数组形式返回
      • head_cells[0].width = Cm(1.9) 设置列宽,单位cm
      • doc_table.rows[i].cells[j].vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER 表格内容垂直居中
      • doc_table.add_row() 新增行,并返回行对象

    插件安装

    插件可以在pycharm的terminal面板下进行安装。python-docx安装命令为:pip install python-docx

    xlrd安装命令为:pip install xlrd  如下所示:

    数据源文件

    数据源是一系列格式相同的Excel文件,共七列,其中第1列要按【/】进行截取拆分,格式如下:

     核心代码

    本文核心源码,主要分三部分:

    导入相关模块包,如下所示:

    1 import xlrd
    2 from docx import Document
    3 from docx.enum.section import WD_ORIENTATION
    4 from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
    5 from docx.shared import Pt, Cm, RGBColor
    6 from docx.oxml.ns import qn
    7 from docx.enum.table import WD_CELL_VERTICAL_ALIGNMENT
    View Code

    读取Excel,如下所示:

     1     def read_excel(self):
     2         """读取Excel"""
     3         book = xlrd.open_workbook(self.excel_file)
     4         sheet = book.sheet_by_name(self.sheet_name)
     5         nrows = sheet.nrows  # 行数
     6         ncols = sheet.ncols  # 列数
     7         datas = []  # 存放数据
     8         # 第一列 标题
     9         keys = sheet.row_values(0)
    10         for row in range(1, nrows):
    11             data = {}  # 每一行数据
    12             for col in range(0, ncols):
    13                 value = sheet.cell_value(row, col)  # 取出每一个单元格的数据
    14                 # 替换到特殊字符
    15                 value = value.replace('<', '').replace('>', '').replace('$', '')
    16                 data[keys[col]] = value
    17                 # 截取第一列元素
    18                 if col == 0:
    19                     first = ''  # 截取元素 第1
    20                     second = ''  # 截取元素 第2
    21                     third = ''  # 截取元素 第3
    22                     arrs = value.lstrip('/').split('/')  # 去掉第一个/ 然后再以/分组
    23                     if len(arrs) > 0:
    24                         if len(arrs) == 1:
    25                             first = arrs[0]
    26                             second = first
    27                             third = second
    28                         elif len(arrs) == 2:
    29                             first = arrs[0]
    30                             second = arrs[1]
    31                             third = second
    32                         elif len(arrs) == 3:
    33                             first = arrs[0]
    34                             second = arrs[1]
    35                             third = arrs[2]
    36                         else:
    37                             first = arrs[0]
    38                             second = arrs[1]
    39                             third = arrs[2]
    40                     else:
    41                         first = value.ltrip('/')
    42                         second = first
    43                         third = second
    44                     data['first'] = first
    45                     data['second'] = second
    46                     data['third'] = third
    47                 # 截取第一列结束
    48             datas.append(data)
    49         return datas
    View Code

    生成Word部分:

      1     def write_word(self, datas):
      2         """生成word文件"""
      3         if len(datas) < 1:
      4             print('Excel没有内容')
      5             return
      6         # 定义word文档对象
      7         doc = Document()
      8         # 添加横向
      9         section = doc.sections[0]  # doc.add_section(start_type=WD_SECTION_START.CONTINUOUS)  # 添加横向页的连续节
     10         section.orientation = WD_ORIENTATION.LANDSCAPE
     11         page_h, page_w = section.page_width, section.page_height
     12         section.page_width = page_w  # 设置横向纸的宽度
     13         section.page_height = page_h  # 设置横向纸的高度
     14         # 设置字体
     15         doc.styles['Normal'].font.name = u'宋体'
     16         doc.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
     17         # 获取第3部分(部门) 并去重
     18         data_third = []
     19         for data in datas:
     20             third = data['third']
     21             if data_third.count(third) == 0:
     22                 data_third.append(third)
     23         for third in data_third:
     24             h2 = doc.add_heading(third, level=2)  # 写入部门,二级标题
     25             run = h2.runs[0]  # 可以通过add_run来设置文字,也可以通过数组来获取
     26             run.font.color.rgb = RGBColor(0, 0, 0)
     27             run.font.name = u'宋体'
     28             doc.add_paragraph(text='', style=None)  # 增加空白行 换行
     29             # 开始获取模板
     30             data_template = []
     31             for data in datas:
     32                 if data['third'] == third:
     33                     template = {'first': data['first'], '模板名称': data['模板名称']}
     34                     if data_template.count(template) == 0:
     35                         data_template.append(template)
     36             # 获取模板完成
     37             # 遍历模板
     38             for template in data_template:
     39                 h3 = doc.add_heading(template['模板名称'], level=3)  # 插入模板名称,三级标题
     40                 run = h3.runs[0]  # 可以通过add_run来设置文字,也可以通过数组来获取
     41                 run.font.color.rgb = RGBColor(0, 0, 0)
     42                 run.font.name = u'宋体'
     43                 doc.add_paragraph(text='', style=None)  # 换行
     44                 data_table = filter(
     45                     lambda data: data['third'] == third and data['模板名称'] == template['模板名称'] and data['first'] ==
     46                                  template['first'], datas)
     47                 data_table = list(data_table)
     48                 # 新增表格 4行5列
     49                 doc_table = doc.add_table(rows=4, cols=5)
     50                 doc_table.style = "Table Grid"
     51                 doc_table.style.font.size = Pt(9)
     52                 doc_table.style.font.name = '宋体'
     53 
     54                 # 合并单元格 赋值
     55                 doc_table.rows[0].cells[1].merge(doc_table.rows[0].cells[4])
     56                 doc_table.rows[1].cells[1].merge(doc_table.rows[1].cells[4])
     57                 doc_table.rows[2].cells[1].merge(doc_table.rows[2].cells[4])
     58                 doc_table.rows[0].cells[0].text = '流程名称:'
     59                 doc_table.rows[0].cells[1].text = data_table[0]['模板名称']
     60                 doc_table.rows[1].cells[0].text = '使用人:'
     61                 doc_table.rows[1].cells[1].text = data_table[0]['first']
     62                 doc_table.rows[2].cells[0].text = '流程说明:'
     63                 doc_table.rows[2].cells[1].text = data_table[0]['流程说明']
     64 
     65                 # 设置标题
     66                 head_cells = doc_table.rows[3].cells  # 前面还有三行,特殊处理
     67                 head_cells[0].text = '节点'
     68                 head_cells[1].text = '节点名'
     69                 head_cells[2].text = '处理人员'
     70                 head_cells[3].text = '处理方式'
     71                 head_cells[4].text = '跳转信息'
     72                 # 设置列宽
     73                 head_cells[0].width = Cm(1.9)
     74                 head_cells[1].width = Cm(4.83)
     75                 head_cells[2].width = Cm(8.25)
     76                 head_cells[3].width = Cm(2.54)
     77                 head_cells[4].width = Cm(5.64)
     78                 # 第1 列水平居中,并设置行高,所有单元格内容垂直居中
     79                 for i in range(0, 4):
     80                     # 水平居中
     81                     p = doc_table.rows[i].cells[0].paragraphs[0]
     82                     p.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
     83                     doc_table.rows[i].height = Cm(0.6)  # 行高
     84                     # 垂直居中
     85                     for j in range(0, 5):
     86                         doc_table.rows[i].cells[j].vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
     87 
     88                 # 生成表格并填充内容
     89                 row_num = 0
     90                 for data in data_table:
     91                     row = doc_table.add_row()
     92                     row_cells = row.cells
     93                     row_cells[0].text = str(row_num + 1) # 序号,需要转换成字符串
     94                     row_cells[1].text = data['节点名称']
     95                     row_cells[2].text = data['审批人员']
     96                     row_cells[3].text = data['审批方式']
     97                     row_cells[4].text = ''
     98                     # 水平居中
     99                     p = row_cells[0].paragraphs[0]
    100                     p.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
    101                     row.height = Cm(0.6)  # 行高
    102                     # 垂直居中
    103                     for j in range(0, 5):
    104                         row_cells[j].vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER
    105                     row_num = row_num + 1
    106 
    107                 doc.add_paragraph(text='', style=None)  # 换行
    108         doc.save(self.word_file)
    View Code

    备注

    子曰:“不患无位,患所以立。不患莫己知,求为可知也。


    作者:Alan.hsiang
    出处:http://www.cnblogs.com/hsiang/
    本文版权归作者和博客园共有,写文不易,支持原创,欢迎转载【点赞】,转载请保留此段声明,且在文章页面明显位置给出原文连接,谢谢。

  • 相关阅读:
    Java中使用synchronized多线程同步的实例
    JDK中String类的intern方法实例
    Ubuntu APT按时间顺序排列已安装的软件包
    LinuxMint/LMDE 安装后的配置
    XLNX XC7Z020平台GIC中断示例程序
    吾八哥学k8s(四):kubernetes常用基本命令
    吾八哥学k8s(三):kubernetes里创建资源的方法
    gitlab-runner在Kubernetes环境下挂载宿主机目录的方法
    吾八哥学k8s(二):golang服务部署到kubernetes
    记Windows10下安装Docker的步骤
  • 原文地址:https://www.cnblogs.com/hsiang/p/14465512.html
Copyright © 2020-2023  润新知