python-docx与openpyxl办公自动化实战:24个实验批量处理Word和Excel
在日常工作中,批量生成Word文档和Excel报表是高频需求。本文基于Ubuntu 24.04 + Python 3.12.3环境,通过24个可复现实验,系统讲解python-docx 1.1.2和openpyxl 3.1.5的核心用法,包括文档创建、表格操作、样式设置、页面布局、公式计算、性能坑点等。所有代码已上机通过,可直接用于生产脚本。一、环境搭建与依赖安装
使用阿里云PyPI镜像安装三个核心库:
pip3 install python-docx openpyxl Pillow --break-system-packages \
-i https://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
注意:Ubuntu 24.04默认启用PEP 668,需加--break-system-packages跳过限制。若使用华为云香港PyPI源可能超时,建议切换国内镜像。验证安装:
>>> from docx import Document
>>> import openpyxl
>>> openpyxl.__version__
'3.1.5'
二、python-docx:Word文档编程
2.1 核心架构
Document是顶层对象,内含paragraphs(段落)、tables(表格)、sections(节)。段落由Run(最小格式单元)组成。docx本质是ZIP包,word/document.xml为核心XML文件。
2.2 基础操作:创建文档、段落、标题
from docx import Document
doc = Document()
doc.add_heading("一级标题", level=1)
p = doc.add_paragraph("普通段落。")
p.add_run(" 同一行内的Run文字。")# Run作为段落内独立格式单元
p2 = doc.add_paragraph("第一行。")
p2.add_run("\n第二行(软换行)。")# \n对应Word的Shift+Enter,不是新段落
doc.add_page_break()
doc.add_paragraph("新页面。")
doc.save("output.docx")
2.3 表格操作:创建、合并、增删行
table = doc.add_table(rows=5, cols=4)
table.style = 'Light Grid Accent 1'
headers = ['类型','英文名','可变性','示例']
for i,h in enumerate(headers):
table.rows.cells.text = h
data = [['整数','int','不可变','42'],['字符串','str','不可变','"hello"'],['列表','list','可变',''],['字典','dict','可变','{"a":1}']]
for ri,row in enumerate(data,1):
for ci,val in enumerate(row):
table.rows.cells.text = val
# 合并与新增行
t2 = doc.add_table(rows=3, cols=3)
t2.cell(0,0).merge(t2.cell(0,2))
t2.cell(0,0).text = "合并区域"
row_new = t2.add_row()
for j in range(3):
row_new.cells.text = f"新列{j}"
doc.save("table_demo.docx")
内置63种表格样式,按类别分为:浅色网格(Light Grid Accent 1~6)、中等底纹(Medium Shading 1 Accent 1~6)、列表样式(Light List Accent 1~6)、彩色系列(Colorful Grid/List/Shading)等,可直接设置style属性。
2.4 Run属性详解
Run支持bold、italic、underline、font.strike(删除线)、font.size(Pt对象)、font.color.rgb(RGBColor)、font.name等。注意中文字体设置必须同时指定西文字体和东亚字体:
from docx.shared import Pt, RGBColor
from docx.oxml.ns import qn
run = p.add_run("宋体中文")
run.font.name = '宋体'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')# 关键:设置eastAsia属性,否则中文不生效
2.5 样式系统
使用内置段落样式(共36种,如Normal、Heading1~9、Title、Subtitle、Quote、List Bullet等):
doc.add_paragraph("引用样式", style='Quote')
# 修改默认样式
style = doc.styles['Normal']
style.font.size = Pt(11)
style.font.name = 'Times New Roman'
2.6 文档属性与批量生成
通过core_properties设置标题、作者、创建时间等元数据,循环生成多份文档(例如4份入职通知书,每份约36KB):
doc.core_properties.title = "批量文档"
users = ["张三","李四"]
for user in users:
doc = Document()
doc.add_heading(f"{user}入职通知", level=1)
doc.add_paragraph(f"尊敬的{user}:恭喜入职。")
doc.save(f"{user}_通知.docx")
2.7 计量单位换算
python-docx使用EMU(English Metric Unit)作为基础单位:1 pt = 12700 EMU,1 cm = 360000 EMU,1 inch = 914400 EMU。可通过Pt、Cm、Inches等辅助类传入。
2.8 字体颜色RGB真彩色
colors = [("红",0xFF,0,0),("绿",0,0x80,0)]
for name,r,g,b in colors:
run = p.add_run(f"[{name}]")
run.font.color.rgb = RGBColor(r,g,b)
2.9 段落间距与行距
p.paragraph_format.space_before = Pt(6)
p.paragraph_format.space_after = Pt(6)
p.paragraph_format.line_spacing = 1.5 # 倍数
p.paragraph_format.line_spacing = Pt(24) # 固定值
2.10 页面设置与分节符混排
通过sections设置A4页面,add_section()创建新节,可单独设置横向:
from docx.shared import Cm
from docx.enum.section import WD_ORIENT
section = doc.sections
section.page_width = Cm(21)
section.page_height = Cm(29.7)
section.top_margin = Cm(2.54)
doc.add_section()
sec2 = doc.sections
sec2.orientation = WD_ORIENT.LANDSCAPE
sec2.page_width = Cm(29.7)
sec2.page_height = Cm(21)
常用纸张尺寸:A4 21×29.7cm,A3 29.7×42.0cm,Letter 21.59×27.94cm,B5 17.6×25.0cm。
2.11 页脚与域:自动页码
通过OxmlElement构造w:fldChar和w:instrText实现PAGE、NUMPAGES域:
footer = doc.sections.footer
p = footer.paragraphs
p.text = "第 "
# 插入PAGE域(需要begin、instrText、end三段)
run = p.add_run()
fldChar = OxmlElement('w:fldChar')
fldChar.set(qn('w:fldCharType'), 'begin')
run._r.append(fldChar)
run2 = p.add_run()
instrText = OxmlElement('w:instrText')
instrText.set(qn('xml:space'), 'preserve')
instrText.text = ' PAGE '
run2._r.append(instrText)
# … 类似插入NUMPAGES域 …
p.add_run(" 页 / 共 ")
p.add_run(" 页")
p.alignment = 1# 居中
常用域代码:PAGE、NUMPAGES、DATE、TOC(需Word打开后更新域)、HYPERLINK。
2.12 页眉与目录
header = doc.sections.header
header.paragraphs.text = "手册标题"
# TOC域只能写入代码,目录内容需Word打开后右键→更新域才能渲染
2.13 综合Demo:列表、图片、表格
支持无序列表(List Bullet)、有序列表(List Number),插入图片(add_picture),也可用zipfile解压docx提取media目录中的图片。
三、openpyxl:Excel电子表格编程
3.1 核心架构
Workbook(工作簿)包含多个Worksheet(工作表),每个工作表由Cells(单元格)组成,支持行/列操作、样式、保护、属性等。
3.2 基础工作流
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws.title = "数据表"
ws['A1'] = '姓名'
ws['B1'] = '年龄'
data = [['张三',28,'深圳',15000],['李四',32,'北京',22000]]
for i,row in enumerate(data,2):
for j,val in enumerate(row):
ws.cell(row=i, column=j+1, value=val)
# 公式
ws['D7'] = '=AVERAGE(D2:D6)'
wb.save("basic.xlsx")
# 回读
wb2 = openpyxl.load_workbook("basic.xlsx")
ws2 = wb2.active
for row in ws2.iter_rows(min_row=1, max_row=7, values_only=True):
print(row)
注意:openpyxl的行列索引从1开始(与Excel一致),公式以字符串形式写入,Excel打开后自动计算。
3.3 工作表操作:CRUD、移动、复制
wb = Workbook()
for name in ['Q1','Q2','Q3','Q4']:
wb.create_sheet(name)
del wb['Sheet']# 删除默认Sheet,如果只剩一个会报错:ValueError
print(wb.sheetnames)# ['Q1','Q2','Q3','Q4']
# 复制
wb.copy_worksheet(wb['Q1'])
wb['Q1 Copy'].title = 'Q1备份'
# 移动
wb.move_sheet('Q4', offset=-2)
# 创建时指定位置
wb.create_sheet("新表", 0)
关键方法速查:create_sheet(name, index)、copy_worksheet(ws)、del wb、move_sheet(sheet, offset)、wb.active、wb.worksheets。
3.4 工作表属性:标签颜色、显示比例、冻结窗格、自动筛选
ws.sheet_properties.tabColor = "FF6B35"# 十六进制颜色
ws.sheet_view.zoomScale = 120# 120%缩放
ws.sheet_view.showGridLines = False# 隐藏网格线
ws.freeze_panes = 'A2'# 冻结首行
ws.auto_filter.ref = "A1:F6"
3.5 样式综合演示
openpyxl样式组件包括Font、PatternFill、Border、Side、Alignment等。构建企业级表格时,可设置表头样式、数据边框、隔行变色、条件着色:
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
header_font = Font(name='微软雅黑', size=11, bold=True, color='FFFFFF')
header_fill = PatternFill(start_color='4472C4', end_color='4472C4', fill_type='solid')
thin_border = Border(left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin'))
for r_idx, row in enumerate(data, 2):
for c_idx, val in enumerate(row):
cell = ws.cell(row=r_idx, column=c_idx+1, value=val)
cell.border = thin_border
cell.alignment = Alignment(horizontal='center', vertical='center')
if r_idx % 2 == 0:
cell.fill = PatternFill(start_color='D9E2F3', end_color='D9E2F3', fill_type='solid')
3.6 保护工作表/工作簿
使用ws.protection设置密码,wb.security.lockStructure保护工作簿结构。
四、踩坑记录与性能提示
1. 中文字体不生效:python-docx需同时设置rFonts的eastAsia属性。
2. PEP 668限制:Ubuntu 24.04使用--break-system-packages或创建虚拟环境。
3. 华为云香港PyPI超时:改用阿里云、清华等国内镜像。
4. TOC目录不显示:python-docx仅写入域代码,需Word打开后手动更新域。
5. 单元格坐标从1开始:openpyxl的行列索引从1起,与Excel一致。
6. 删除唯一工作表报错:工作簿至少保留一个可见工作表,删除最后一个会引发ValueError。
性能测试显示,生成4份入职文档瞬间完成,每份约36KB;24个实验全部在Ubuntu 24.04 + Python 3.12.3环境下跑通,产出Word文件19个、Excel文件7个。
总结
python-docx和openpyxl是处理Office文档的利器,掌握本文全部实验,即可独立完成合同批量生成、数据报表自动化、样式控制等任务。代码可直接套用,注意根据实际环境调整中文字体设置和镜像源。
Re: python-docx与openpyxl办公自动化实战:24个实验批量处理Word和Excel
感谢分享,很详细的实战教程!python-docx 的 Run 属性设置那段特别实用,尤其是中文东亚字体必须用 `qn('w:eastAsia')` 这个坑,之前踩过几次才明白。期待后续 openpyxl 部分,标题说是 24 个实验,目前只看到 python-docx 的,希望能继续补充 Excel 批量处理的案例,比如公式写入和图表生成。Ubuntu 24.04 加 `--break-system-packages` 这个提示对新手也很友好,省得折腾虚拟环境。Re: python-docx与openpyxl办公自动化实战:24个实验批量处理Word和Excel
楼主总结得很全面,特别是中文乱码的字体设置方法,之前一直困扰我。请问批量生成word文档时,如果需要根据模板替换占位符,有什么好方法吗?再次感谢!Re: python-docx与openpyxl办公自动化实战:24个实验批量处理Word和Excel
感谢楼主分享这么详细的实战经验!从环境搭建到代码示例都很清晰,特别是中文字体设置时eastAsia属性的说明,还有EMU单位换算表,这些细节在实际开发中很容易踩坑。你提到还有公式计算和性能坑点等实验,请问后续会继续补充吗?期待看到批量生成和性能优化的部分。
页:
[1]