在繁忙的职场中,你是否也遇到过这样的烦恼:辛苦整理完Excel数据后,还要手动复制到Word文档中,调整格式,甚至因为数据变更而忘记修改Word内容?今天,就让我们一起探索如何用Python自动化办公,将Excel中的数据一键填充到Word模板中,并且还能自动调整好格式!让工作更高效!
背景故事
小李是一家大型公司的中层管理,每天都需要汇总各种数据,并撰写报告给不同层级的领导。然而,数据汇总完毕后,他还需要花费大量时间将Excel中的数据复制到Word文档中,并调整格式。更糟糕的是,当Excel数据发生变更时,他很容易忘记修改对应的Word内容,导致报告出现错误,这个过程中最让他头疼的就是复制粘贴和格式调整的工作,机械地重复性工作渐渐消磨掉了他的激情和热情。
解决方案
为了解决小明的困扰,我们引入了Python自动化办公的解决方案。通过Python的强大功能,我们可以编写一个脚本,自动读取Excel中的数据,并填充到Word文档的对应表格中。同时,我们还能通过脚本自动调整Word文档的格式,确保生成的报告既准确又美观。
实战操作
此例要求将Excel档的“收货数据”填写到Word档的“收货记录”中去,并加总收货数量。模板是下面这样的,需要将Excel里面的信息插入到模板表里。
模板文档:
填充完模板后得到的理想结果:
Excel数据信息:
首先,从excel里提取数据
#从Excel表中提取数据
from openpyxl import load_workbook
wb = load_workbook("收货数据.xlsx")
ws = wb.active
data=[]
for row in range(2,ws.max_row+1):
seq = ws["A"+str(row)].value
supplier = ws["B"+str(row)].value
material_pn = ws["C"+str(row)].value
material_model = ws["D"+str(row)].value
desp = ws["E"+str(row)].value
qty = ws["F"+str(row)].value
date = ws["G"+str(row)].value.date()
info = [seq, supplier, material_pn, material_model, desp, qty, date]
data.append(info)
检查一下提取到数据
其次,对数据进行相应的加总
#定义数量加总函数
def Sum_list(list):
s = 0
for i in list: #累加列表中的所有数
s+=i
return s
#加总数量列的所有数字
qty_list=[]
for i in data:
qty_list.append(i[5]) #数量在内层列表的第6个位置,索引是5
sum_qty= Sum_list(qty_list) #调用加总函数加总
sum_qty
接着,调整格式,合并单元格等
def Merge_cells(table,target_list,start_row,col):
'''
table: 是需要操作的表格
target_list: 是目标列表,即含有重复数据的列表
start_row: 是开始行,即表格中开始比对数据的行(需要将标题除开)
col: 是需要处理数据的列
'''
start = 0 #开始行计数
end = 0 #结束行计数
reference = target_list[0] #设定基准,以列表中的第一个字符串开始
for i in range(len(target_list)): #遍历列表
if target_list[i] != reference: #开始比对,如果内容不同执行如下
reference = target_list[i] #基准变成列表中下一个字符串
end = i - 1
table.cell(start+start_row,col).merge(table.cell(end+start_row,col))
start = end + 1
if i == len(target_list) - 1: #遍历到最后一行,按如下操作
end = i
table.cell(start+start_row,col).merge(table.cell(end+start_row,col))
然后,往word表格里按格式写入word里
#数据提取即处理完毕后,就可以往Word的表格中写入数据了
from docx import Document
doc = Document("收货记录模板.docx")
#读取word文档中的第一个表格的第二和第三列除标题和尾部总数行的数据
table = doc.tables[0] #已确定是第一个表格,其索引是0
supplier = [] #存储供应商名称
pn = [] #存储物料编码
for i in data:
supplier.append(i[1])
pn.append(i[2])
#按需增加行,以便填写数据
for i in range(len(supplier)): #模板中已经有一行了,所以总共只需增加len(supplier)行
table.add_row()
#增加好行后先做合并单元格操作
Merge_cells(table,supplier,1,1) #开始合并行为2,索引为1;供应商名称是在2列,索引为1
Merge_cells(table,pn,1,2) #开始合并行为2,索引为1;物料编码是在3列,索引为2
#写入数据到表格
for row in range(1,len(supplier)+1):
for col in range(7):
table.cell(row,col).text = str(data[row-1][col])
max_row = len(table.rows) #获取最大一行
qty_row = max_row-1 #确定需要写入加总数据的一行
table.cell(qty_row,5).merge(table.cell(qty_row,5)) #合并右下角用于填写数量的两个单元格
table.cell(qty_row,4).text = '总数:'
table.cell(qty_row,5).text = str(sum_qty)
doc.save("收货记录.docx")
最后,对word里的表格进行格式处理
from docx.table import _Cell
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
def Set_cell_border(cell: _Cell, **kwargs):
"""
设置单元格边框函数
使用方法:
Set_cell_border(
cell,
top={"sz": 12, "val": "single", "color": "#FF0000", "space": "0"},
bottom={"sz": 12, "color": "#00FF00", "val": "single"},
start={"sz": 24, "val": "dashed", "shadow": "true"},
end={"sz": 12, "val": "dashed"},
)
传入参数有cell, 即单元格;top指上边框;bottom指下边框;start指左边框;end指右边框。
"sz"指线的粗细程度;"val"指线型,比如单线,虚线等;"color"指颜色,颜色编码可百度;
"space"指间隔,一般不设置,设置的值大于0会导致线错开;"shadow"指边框阴影
"""
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
tcBorders = tcPr.first_child_found_in("w:tcBorders")
if tcBorders is None:
tcBorders = OxmlElement('w:tcBorders')
tcPr.append(tcBorders)
for edge in ('start', 'top', 'end', 'bottom', 'insideH', 'insideV'):
edge_data = kwargs.get(edge)
if edge_data:
tag = 'w:{}'.format(edge)
element = tcBorders.find(qn(tag))
if element is None:
element = OxmlElement(tag)
tcBorders.append(element)
for key in ["sz", "val", "color", "space", "shadow"]:
if key in edge_data:
element.set(qn('w:{}'.format(key)), str(edge_data[key]))
#定义单元格填充颜色函数
from docx.oxml.ns import nsdecls
from docx.oxml import parse_xml
def Set_Background_Color(cell,rgbColor):
shading_elm = parse_xml(r' '.format(nsdecls('w'),color_value = rgbColor)) #固定写法,照抄即可
cell._tc.get_or_add_tcPr().append(shading_elm)
from docx.enum.text import WD_ALIGN_PARAGRAPH #设置水平居中对齐需要用到的库
from docx.enum.table import WD_ALIGN_VERTICAL #设置垂直居中对齐需要用到的库
from docx.shared import Cm # 长度单位(厘米cm用到的库)
from docx import Document
doc = Document("收货记录.docx") #打开word文件
table= doc.tables[0]
max_row = len(table.rows) #获取表格总行数
#1.最后一行中,“总数”两个字要加粗
run = table.cell(max_row-1,4).paragraphs[0].runs[0] # 获取最后一行第五列对应单元格中的文字块,即“总数”字样所在单元格
run.font.bold = True #将文字块设置为粗体
#2.最后一行的行高要调大一点,现在这样扁扁的,难看
table.rows[max_row-1].height = Cm(1) # 将最后一行的行高设置为1厘米
#3.最后一行那几个空单元格有框线,太碍眼,得去掉,将总数及左边两个cell左边框和下边框设成白色
for i in range(3):
cell = table.cell(max_row-1,i)
Set_cell_border(
cell,
bottom={"color": "#FFFFFF"},
start={"color": "#FFFFFF" },
end={"color": "#FFFFFF"}
)
cell_1 = table.cell(max_row-1,3)
Set_cell_border(cell_1,start={"color": "#FFFFFF" },bottom={"color": "#FFFFFF"})
cell_2 = table.cell(max_row-1,6)
Set_cell_border(cell_2,end={"color": "#FFFFFF" },bottom={"color": "#FFFFFF"})
#4.各单元格水平和垂直方向都要居中对齐
for row in range(1,max_row):
for col in range(len(table.columns)):
table.cell(row,col).paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
table.cell(row,col).vertical_alignment = WD_ALIGN_VERTICAL.CENTER
#5.数量列≥85的,底色设置为橙色
qty = [] #存储数量信息
#读取第二行到29行,第2,3列中的数据
for i in range(1,max_row-1):
qty_info = table.rows[i].cells[5].text #cells[5]指表格第6列
qty.append(int(qty_info))
#将数量≥85的单元格填色
row=1 #行计数器
for i in qty:
if i>=85:
cell = table.cell(row,5) #第6列数据为数量,列索引是5
Set_Background_Color(cell,"98F5FF") #填充颜色,"98F5FF"是蓝色的编码
row+=1 #跳转到下一行
doc.save("收货记录-整理.docx")
总结与展望
通过Python自动化办公,我们可以轻松实现Excel数据到Word文档的自动填充和格式调整。这不仅提高了工作效率,还减少了人为错误的可能性。未来,我们还可以进一步探索Python自动化办公的更多应用场景,如邮件自动发送、PPT自动制作等。让我们一起用技术改变生活,享受更加高效的工作体验吧!
关注公众号,私信“word"获取本篇文章的代码和示例数据。
html字段最大长度限制,html input 限制输入的长度并提示的方法
html 中 input 标签的 value 值的长度理论上应该是 2^32(数据来源于资料,没有测试过),但为了防止一些 input 的输入数据过长来做一些限制,该如何实现呢?这篇文章就来介绍一下,如何限制 input 输入数据的长度并且输入的数据超过规定的长度该如何去提示?
html input 限制输入字符串长度的方法
input 标签中的 maxlength 属性,可以用来规定输入字符串的最大长度。
示例代码:
html input 限制输入字符串的长度并提示的方法
maxlength 属性虽然可以限制 input 输入字符串的长度,但对于用户的体验来说是很不友好的,所以我们要利用 js 代码在 input 输入的字符超过规定的长度时给出提示!
jq示例代码:
$('#inputs').on('inputpropertychange',function(){
varnum,le;
num=$(this).val().length;
le=parseInt($(this).attr('maxlength'))-1;//这里是获取的maxlength属性的值
if(num>le){
alert('长度超过限制!');
})
注意:
1、上面 js 代码中 le 变量规定的限制长度要比实际中少一位(减去一个1),不然不会触发判断逻辑
2、js 中 le 变量获取的是 maxlength 属性的值,如不想获取此属性的值,可以自定义!
3、使用上面的 js 代码前,要加载 jquery.js 文件!
原生 js 代码示例
functionkeyPress(ob){
//这里比较时,要比实际的限制数量少一位才会触发判断逻辑!
if(ob.value.length>9){
alert('长度超过限制啦!');