查看: 125|回复: 3

python-docx与openpyxl办公自动化实战:24个实验批量处理Word和Excel

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
在日常工作中,批量生成Word文档和Excel报表是高频需求。本文基于Ubuntu 24.04 + Python 3.12.3环境,通过24个可复现实验,系统讲解python-docx 1.1.2和openpyxl 3.1.5的核心用法,包括文档创建、表格操作、样式设置、页面布局、公式计算、性能坑点等。所有代码已上机通过,可直接用于生产脚本。

一、环境搭建与依赖安装

使用阿里云PyPI镜像安装三个核心库:
  1. pip3 install python-docx openpyxl Pillow --break-system-packages \
  2. -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
复制代码

注意:Ubuntu 24.04默认启用PEP 668,需加--break-system-packages跳过限制。若使用华为云香港PyPI源可能超时,建议切换国内镜像。验证安装:
  1. >>> from docx import Document
  2. >>> import openpyxl
  3. >>> openpyxl.__version__
  4. '3.1.5'
复制代码

二、python-docx:Word文档编程

2.1 核心架构

Document是顶层对象,内含paragraphs(段落)、tables(表格)、sections(节)。段落由Run(最小格式单元)组成。docx本质是ZIP包,word/document.xml为核心XML文件。

2.2 基础操作:创建文档、段落、标题
  1. from docx import Document
  2. doc = Document()
  3. doc.add_heading("一级标题", level=1)
  4. p = doc.add_paragraph("普通段落。")
  5. p.add_run(" 同一行内的Run文字。")  # Run作为段落内独立格式单元
  6. p2 = doc.add_paragraph("第一行。")
  7. p2.add_run("\n第二行(软换行)。")  # \n对应Word的Shift+Enter,不是新段落
  8. doc.add_page_break()
  9. doc.add_paragraph("新页面。")
  10. doc.save("output.docx")
复制代码

2.3 表格操作:创建、合并、增删行
  1. table = doc.add_table(rows=5, cols=4)
  2. table.style = 'Light Grid Accent 1'
  3. headers = ['类型','英文名','可变性','示例']
  4. for i,h in enumerate(headers):
  5.     table.rows[0].cells[i].text = h
  6. data = [['整数','int','不可变','42'],['字符串','str','不可变','"hello"'],['列表','list','可变','[1,2,3]'],['字典','dict','可变','{"a":1}']]
  7. for ri,row in enumerate(data,1):
  8.     for ci,val in enumerate(row):
  9.         table.rows[ri].cells[ci].text = val
  10. # 合并与新增行
  11. t2 = doc.add_table(rows=3, cols=3)
  12. t2.cell(0,0).merge(t2.cell(0,2))
  13. t2.cell(0,0).text = "合并区域"
  14. row_new = t2.add_row()
  15. for j in range(3):
  16.     row_new.cells[j].text = f"新列{j}"
  17. 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等。注意中文字体设置必须同时指定西文字体和东亚字体:
  1. from docx.shared import Pt, RGBColor
  2. from docx.oxml.ns import qn
  3. run = p.add_run("宋体中文")
  4. run.font.name = '宋体'
  5. run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')  # 关键:设置eastAsia属性,否则中文不生效
复制代码

2.5 样式系统

使用内置段落样式(共36种,如Normal、Heading1~9、Title、Subtitle、Quote、List Bullet等):
  1. doc.add_paragraph("引用样式", style='Quote')
  2. # 修改默认样式
  3. style = doc.styles['Normal']
  4. style.font.size = Pt(11)
  5. style.font.name = 'Times New Roman'
复制代码

2.6 文档属性与批量生成

通过core_properties设置标题、作者、创建时间等元数据,循环生成多份文档(例如4份入职通知书,每份约36KB):
  1. doc.core_properties.title = "批量文档"
  2. users = ["张三","李四"]
  3. for user in users:
  4.     doc = Document()
  5.     doc.add_heading(f"{user}入职通知", level=1)
  6.     doc.add_paragraph(f"尊敬的{user}:恭喜入职。")
  7.     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真彩色
  1. colors = [("红",0xFF,0,0),("绿",0,0x80,0)]
  2. for name,r,g,b in colors:
  3.     run = p.add_run(f"[{name}]")
  4.     run.font.color.rgb = RGBColor(r,g,b)
复制代码

2.9 段落间距与行距
  1. p.paragraph_format.space_before = Pt(6)
  2. p.paragraph_format.space_after = Pt(6)
  3. p.paragraph_format.line_spacing = 1.5   # 倍数
  4. p.paragraph_format.line_spacing = Pt(24) # 固定值
复制代码

2.10 页面设置与分节符混排

通过sections[0]设置A4页面,add_section()创建新节,可单独设置横向:
  1. from docx.shared import Cm
  2. from docx.enum.section import WD_ORIENT
  3. section = doc.sections[0]
  4. section.page_width = Cm(21)
  5. section.page_height = Cm(29.7)
  6. section.top_margin = Cm(2.54)
  7. doc.add_section()
  8. sec2 = doc.sections[1]
  9. sec2.orientation = WD_ORIENT.LANDSCAPE
  10. sec2.page_width = Cm(29.7)
  11. 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域:
  1. footer = doc.sections[0].footer
  2. p = footer.paragraphs[0]
  3. p.text = "第 "
  4. # 插入PAGE域(需要begin、instrText、end三段)
  5. run = p.add_run()
  6. fldChar = OxmlElement('w:fldChar')
  7. fldChar.set(qn('w:fldCharType'), 'begin')
  8. run._r.append(fldChar)
  9. run2 = p.add_run()
  10. instrText = OxmlElement('w:instrText')
  11. instrText.set(qn('xml:space'), 'preserve')
  12. instrText.text = ' PAGE '
  13. run2._r.append(instrText)
  14. # … 类似插入NUMPAGES域 …
  15. p.add_run(" 页 / 共 ")
  16. p.add_run(" 页")
  17. p.alignment = 1  # 居中
复制代码

常用域代码:PAGE、NUMPAGES、DATE、TOC(需Word打开后更新域)、HYPERLINK。

2.12 页眉与目录
  1. header = doc.sections[0].header
  2. header.paragraphs[0].text = "手册标题"
  3. # TOC域只能写入代码,目录内容需Word打开后右键→更新域才能渲染
复制代码

2.13 综合Demo:列表、图片、表格

支持无序列表(List Bullet)、有序列表(List Number),插入图片(add_picture),也可用zipfile解压docx提取media目录中的图片。

三、openpyxl:Excel电子表格编程

3.1 核心架构

Workbook(工作簿)包含多个Worksheet(工作表),每个工作表由Cells(单元格)组成,支持行/列操作、样式、保护、属性等。

3.2 基础工作流
  1. from openpyxl import Workbook
  2. wb = Workbook()
  3. ws = wb.active
  4. ws.title = "数据表"
  5. ws['A1'] = '姓名'
  6. ws['B1'] = '年龄'
  7. data = [['张三',28,'深圳',15000],['李四',32,'北京',22000]]
  8. for i,row in enumerate(data,2):
  9.     for j,val in enumerate(row):
  10.         ws.cell(row=i, column=j+1, value=val)
  11. # 公式
  12. ws['D7'] = '=AVERAGE(D2:D6)'
  13. wb.save("basic.xlsx")
  14. # 回读
  15. wb2 = openpyxl.load_workbook("basic.xlsx")
  16. ws2 = wb2.active
  17. for row in ws2.iter_rows(min_row=1, max_row=7, values_only=True):
  18.     print(row)
复制代码

注意:openpyxl的行列索引从1开始(与Excel一致),公式以字符串形式写入,Excel打开后自动计算。

3.3 工作表操作:CRUD、移动、复制
  1. wb = Workbook()
  2. for name in ['Q1','Q2','Q3','Q4']:
  3.     wb.create_sheet(name)
  4. del wb['Sheet']  # 删除默认Sheet,如果只剩一个会报错:ValueError
  5. print(wb.sheetnames)  # ['Q1','Q2','Q3','Q4']
  6. # 复制
  7. wb.copy_worksheet(wb['Q1'])
  8. wb['Q1 Copy'].title = 'Q1备份'
  9. # 移动
  10. wb.move_sheet('Q4', offset=-2)
  11. # 创建时指定位置
  12. wb.create_sheet("新表", 0)
复制代码

关键方法速查:create_sheet(name, index)、copy_worksheet(ws)、del wb[sheetname]、move_sheet(sheet, offset)、wb.active、wb.worksheets[0]。

3.4 工作表属性:标签颜色、显示比例、冻结窗格、自动筛选
  1. ws.sheet_properties.tabColor = "FF6B35"  # 十六进制颜色
  2. ws.sheet_view.zoomScale = 120  # 120%缩放
  3. ws.sheet_view.showGridLines = False  # 隐藏网格线
  4. ws.freeze_panes = 'A2'  # 冻结首行
  5. ws.auto_filter.ref = "A1:F6"
复制代码

3.5 样式综合演示

openpyxl样式组件包括Font、PatternFill、Border、Side、Alignment等。构建企业级表格时,可设置表头样式、数据边框、隔行变色、条件着色:
  1. from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
  2. header_font = Font(name='微软雅黑', size=11, bold=True, color='FFFFFF')
  3. header_fill = PatternFill(start_color='4472C4', end_color='4472C4', fill_type='solid')
  4. thin_border = Border(left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin'))
  5. for r_idx, row in enumerate(data, 2):
  6.     for c_idx, val in enumerate(row):
  7.         cell = ws.cell(row=r_idx, column=c_idx+1, value=val)
  8.         cell.border = thin_border
  9.         cell.alignment = Alignment(horizontal='center', vertical='center')
  10.         if r_idx % 2 == 0:
  11.             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文档的利器,掌握本文全部实验,即可独立完成合同批量生成、数据报表自动化、样式控制等任务。代码可直接套用,注意根据实际环境调整中文字体设置和镜像源。
回复

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: python-docx与openpyxl办公自动化实战:24个实验批量处理Word和Excel

感谢分享,很详细的实战教程!python-docx 的 Run 属性设置那段特别实用,尤其是中文东亚字体必须用 `qn('w:eastAsia')` 这个坑,之前踩过几次才明白。期待后续 openpyxl 部分,标题说是 24 个实验,目前只看到 python-docx 的,希望能继续补充 Excel 批量处理的案例,比如公式写入和图表生成。Ubuntu 24.04 加 `--break-system-packages` 这个提示对新手也很友好,省得折腾虚拟环境。
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: python-docx与openpyxl办公自动化实战:24个实验批量处理Word和Excel

楼主总结得很全面,特别是中文乱码的字体设置方法,之前一直困扰我。请问批量生成word文档时,如果需要根据模板替换占位符,有什么好方法吗?再次感谢!
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: python-docx与openpyxl办公自动化实战:24个实验批量处理Word和Excel

感谢楼主分享这么详细的实战经验!从环境搭建到代码示例都很清晰,特别是中文字体设置时eastAsia属性的说明,还有EMU单位换算表,这些细节在实际开发中很容易踩坑。你提到还有公式计算和性能坑点等实验,请问后续会继续补充吗?期待看到批量生成和性能优化的部分。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-7-2 12:57 , Processed in 0.034338 second(s), 17 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部