在日常工作中,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 如下所示:
![](https://img2020.cnblogs.com/blog/1068941/202103/1068941-20210301195920256-1592376389.png)
数据源文件
数据源是一系列格式相同的Excel文件,共七列,其中第1列要按【/】进行截取拆分,格式如下:
![](https://img2020.cnblogs.com/blog/1068941/202103/1068941-20210301194422190-1438142753.png)
核心代码
本文核心源码,主要分三部分:
导入相关模块包,如下所示:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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,如下所示:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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部分:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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
备注
子曰:“不患无位,患所以立。不患莫己知,求为可知也。
|