Python-docx库详解:自动化生成与处理Word文档
2026/9/12 23:31:20 网站建设 项目流程

1. Python-docx库概述与核心功能

python-docx是一个纯Python实现的第三方库,专门用于创建和修改Microsoft Word的.docx格式文档。这个库最大的优势在于它不需要依赖Microsoft Word软件即可运行,具备优秀的跨平台特性,可以在Windows、Mac、Linux等系统上使用。

需要注意的是,python-docx仅兼容.docx格式(对应Word 2007及以上版本),不支持旧版的.doc格式文件。这是因为.docx是基于XML的开放压缩格式,而.doc是二进制私有格式,前者体积更小、兼容性更优。

1.1 安装与基本使用

安装python-docx非常简单,只需要执行以下命令:

pip install python-docx

安装完成后,就可以开始使用这个强大的库了。下面是一个最基本的示例,展示如何创建一个简单的Word文档:

from docx import Document # 创建一个新的文档对象 doc = Document() # 添加一个标题 doc.add_heading('我的第一个Python生成的Word文档', level=1) # 添加一个段落 doc.add_paragraph('这是一个使用python-docx创建的简单文档。') # 保存文档 doc.save('my_first_document.docx')

1.2 文档对象模型

python-docx采用树状结构分层映射Word文档元素,使得程序能够精准控制文档的内容、格式与布局。理解这个对象模型对于高效使用python-docx至关重要:

Document(文档) ├── Sections(节) ├── Paragraphs(段落) │ ├── Runs(文本片段) │ └── InlineShapes(内联形状,如图片) ├── Tables(表格) │ ├── Rows(行) │ │ └── Cells(单元格) │ │ └── Paragraphs(单元格内的段落) └── Core Properties(文档属性)

2. 文档内容操作详解

2.1 段落与文本处理

段落是Word文档中最基本的文本容器。在python-docx中,我们可以灵活地操作段落和其中的文本内容。

2.1.1 基本段落操作
from docx import Document doc = Document() # 添加简单段落 doc.add_paragraph("这是一个普通段落。") # 添加带格式的段落 para = doc.add_paragraph("这是一个") para.add_run("加粗").bold = True para.add_run("和") para.add_run("斜体").italic = True para.add_run("的文本组合。") # 插入段落到特定位置 first_para = doc.add_paragraph("这是第一个段落") second_para = first_para.insert_paragraph_before("这个段落会出现在第一个段落前面") doc.save('paragraph_demo.docx')
2.1.2 文本格式控制

python-docx允许我们对文本进行精细的格式控制:

from docx import Document from docx.shared import Pt, RGBColor from docx.enum.text import WD_UNDERLINE doc = Document() # 创建段落并添加不同格式的文本 para = doc.add_paragraph() run1 = para.add_run("红色文本 ") run1.font.color.rgb = RGBColor(255, 0, 0) run2 = para.add_run("大号加粗文本 ") run2.font.size = Pt(14) run2.bold = True run3 = para.add_run("带下划线的文本") run3.underline = WD_UNDERLINE.DOUBLE doc.save('text_formatting.docx')

2.2 表格操作

表格是文档中常见的数据展示方式,python-docx提供了丰富的表格操作功能。

2.2.1 创建和填充表格
from docx import Document doc = Document() # 创建一个3行4列的表格 table = doc.add_table(rows=3, cols=4) # 填充表头 heading_cells = table.rows[0].cells heading_cells[0].text = '序号' heading_cells[1].text = '姓名' heading_cells[2].text = '年龄' heading_cells[3].text = '部门' # 填充数据 data_rows = [ [1, '张三', 28, '研发部'], [2, '李四', 32, '市场部'], [3, '王五', 25, '人力资源部'] ] for i, row_data in enumerate(data_rows, 1): row_cells = table.rows[i].cells for j, cell_data in enumerate(row_data): row_cells[j].text = str(cell_data) doc.save('table_demo.docx')
2.2.2 表格样式与合并单元格
from docx import Document doc = Document() # 创建一个表格并应用样式 table = doc.add_table(rows=4, cols=3) table.style = 'Light Shading Accent 1' # 使用内置表格样式 # 合并单元格示例 # 合并第一行的前两个单元格 cell_0_0 = table.cell(0, 0) cell_0_1 = table.cell(0, 1) cell_0_0.merge(cell_0_1) cell_0_0.text = "合并的标题单元格" # 填充其他内容 table.cell(1, 0).text = "数据1" table.cell(1, 1).text = "数据2" table.cell(1, 2).text = "数据3" doc.save('table_style_merge.docx')

3. 高级文档功能

3.1 页眉页脚设置

页眉和页脚是专业文档的重要组成部分,python-docx可以方便地设置它们:

from docx import Document doc = Document() # 获取第一个节的页眉 header = doc.sections[0].header header.is_linked_to_previous = False # 确保这是一个独立的页眉 # 添加页眉内容 header_para = header.paragraphs[0] header_para.text = "\t公司机密文档\t页码:{PAGE}/{NUMPAGES}" header_para.style = doc.styles["Header"] # 获取第一个节的页脚 footer = doc.sections[0].footer footer.is_linked_to_previous = False # 添加页脚内容 footer_para = footer.paragraphs[0] footer_para.text = "文档生成日期:2026-01-01" footer_para.style = doc.styles["Footer"] doc.add_paragraph("这是文档正文内容。") doc.save('header_footer_demo.docx')

3.2 图片插入与处理

在文档中插入图片是常见的需求,python-docx提供了灵活的图片插入功能:

from docx import Document from docx.shared import Inches doc = Document() # 添加标题 doc.add_heading('图片插入示例', level=1) # 添加图片(自动调整大小) doc.add_paragraph("下面是一张自动调整大小的图片:") doc.add_picture('example.jpg', width=Inches(4)) # 设置宽度为4英寸,高度按比例自动调整 # 添加固定尺寸的图片 doc.add_paragraph("\n下面是固定尺寸的图片:") doc.add_picture('example.jpg', width=Inches(2), height=Inches(1.5)) # 图文混排 para = doc.add_paragraph() para.add_run("图片左侧文本 ") run = para.add_run() run.add_picture('example.jpg', width=Inches(1)) para.add_run(" 图片右侧文本") doc.save('image_demo.docx')

3.3 样式管理

样式是Word文档格式化的核心,python-docx允许我们创建和应用自定义样式:

from docx import Document from docx.enum.style import WD_STYLE_TYPE from docx.shared import Pt doc = Document() # 创建一个新的段落样式 styles = doc.styles my_style = styles.add_style('MyStyle', WD_STYLE_TYPE.PARAGRAPH) my_style.font.name = '微软雅黑' my_style.font.size = Pt(12) my_style.font.color.rgb = (0, 0, 255) # 蓝色 my_style.paragraph_format.line_spacing = 1.5 my_style.paragraph_format.space_after = Pt(12) # 应用自定义样式 doc.add_paragraph("这是默认样式的段落。") doc.add_paragraph("这是自定义样式的段落。", style='MyStyle') # 创建字符样式 char_style = styles.add_style('MyCharStyle', WD_STYLE_TYPE.CHARACTER) char_style.font.bold = True char_style.font.italic = True char_style.font.underline = True # 应用字符样式 para = doc.add_paragraph() run = para.add_run("这部分文本使用自定义字符样式") run.style = 'MyCharStyle' doc.save('style_demo.docx')

4. 实战应用案例

4.1 自动化报告生成

下面是一个自动化生成项目报告的完整示例:

from docx import Document from docx.shared import Inches, Pt from docx.enum.text import WD_ALIGN_PARAGRAPH from docx.enum.table import WD_TABLE_ALIGNMENT import datetime def generate_project_report(project_data): # 创建文档对象 doc = Document() # 设置默认字体 doc.styles['Normal'].font.name = '微软雅黑' # 添加标题 title = doc.add_heading(project_data['title'], level=0) title.alignment = WD_ALIGN_PARAGRAPH.CENTER # 添加基本信息 doc.add_heading('项目基本信息', level=1) info_table = doc.add_table(rows=4, cols=2) info_table.style = 'Light Shading Accent 1' # 填充基本信息表 info_rows = [ ['项目编号', project_data['id']], ['项目经理', project_data['manager']], ['开始日期', project_data['start_date']], ['预计工期', project_data['duration']] ] for i, (label, value) in enumerate(info_rows): info_table.cell(i, 0).text = label info_table.cell(i, 1).text = value # 添加项目进度 doc.add_heading('项目进度', level=1) progress_table = doc.add_table(rows=len(project_data['tasks']) + 1, cols=3) progress_table.alignment = WD_TABLE_ALIGNMENT.CENTER # 填充表头 header_cells = progress_table.rows[0].cells header_cells[0].text = '任务名称' header_cells[1].text = '负责人' header_cells[2].text = '完成百分比' # 填充任务数据 for i, task in enumerate(project_data['tasks'], 1): row_cells = progress_table.rows[i].cells row_cells[0].text = task['name'] row_cells[1].text = task['owner'] row_cells[2].text = f"{task['progress']}%" # 添加总结 doc.add_heading('项目总结', level=1) doc.add_paragraph(project_data['summary']) # 添加页脚 footer = doc.sections[0].footer footer_para = footer.paragraphs[0] footer_para.text = f"报告生成时间:{datetime.datetime.now().strftime('%Y-%m-%d %H:%M')}" footer_para.alignment = WD_ALIGN_PARAGRAPH.CENTER # 保存文档 doc.save(project_data['output_file']) print(f"报告已生成:{project_data['output_file']}") # 示例数据 project_data = { 'title': '企业数字化转型项目季度报告', 'id': 'XM2026001', 'manager': '张伟', 'start_date': '2026-01-01', 'duration': '6个月', 'tasks': [ {'name': '需求分析', 'owner': '李娜', 'progress': 100}, {'name': '系统设计', 'owner': '王强', 'progress': 90}, {'name': '开发实现', 'owner': '赵敏', 'progress': 75}, {'name': '测试验证', 'owner': '刘芳', 'progress': 30} ], 'summary': '项目整体进展顺利,需求分析和系统设计阶段已完成,开发工作正在进行中。测试工作已开始准备,预计下月进入全面测试阶段。', 'output_file': 'project_report.docx' } # 生成报告 generate_project_report(project_data)

4.2 批量处理Word文档

python-docx不仅可以创建文档,还可以批量修改现有文档:

from docx import Document import os def batch_process_documents(input_folder, output_folder, process_func): """ 批量处理文件夹中的Word文档 :param input_folder: 输入文件夹路径 :param output_folder: 输出文件夹路径 :param process_func: 处理函数,接收Document对象作为参数 """ # 确保输出文件夹存在 os.makedirs(output_folder, exist_ok=True) # 遍历输入文件夹中的所有.docx文件 for filename in os.listdir(input_folder): if filename.endswith('.docx'): input_path = os.path.join(input_folder, filename) output_path = os.path.join(output_folder, filename) # 打开文档并处理 doc = Document(input_path) process_func(doc) # 保存处理后的文档 doc.save(output_path) print(f"已处理并保存:{output_path}") # 示例处理函数:为所有文档添加统一页眉 def add_standard_header(doc): for section in doc.sections: header = section.header header.is_linked_to_previous = False header_para = header.paragraphs[0] header_para.text = "\t公司标准文档\t机密等级:内部使用" header_para.style = doc.styles["Header"] # 示例处理函数:替换文档中的特定文本 def replace_text(doc): replacements = { "旧公司名称": "新公司名称", "旧地址": "新地址", "旧电话": "新电话" } for para in doc.paragraphs: for old_text, new_text in replacements.items(): if old_text in para.text: para.text = para.text.replace(old_text, new_text) for table in doc.tables: for row in table.rows: for cell in row.cells: for para in cell.paragraphs: for old_text, new_text in replacements.items(): if old_text in para.text: para.text = para.text.replace(old_text, new_text) # 使用示例 input_folder = 'input_docs' output_folder = 'output_docs' # 批量添加页眉 batch_process_documents(input_folder, output_folder, add_standard_header) # 批量替换文本 batch_process_documents(input_folder, output_folder, replace_text)

5. 常见问题与解决方案

5.1 中文显示问题

在使用python-docx处理中文时,可能会遇到字体显示不正确的问题。解决方案是明确设置中文字体:

from docx import Document from docx.oxml.ns import qn doc = Document() # 设置文档默认字体 doc.styles['Normal'].font.name = '微软雅黑' doc.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), '微软雅黑') # 添加中文内容 doc.add_paragraph("这是一段中文文本,现在应该能正确显示了。") doc.save('chinese_demo.docx')

5.2 表格内容溢出

当表格内容过多时,可能会出现内容显示不全的问题。可以通过调整单元格宽度和自动换行来解决:

from docx import Document from docx.shared import Inches doc = Document() # 创建表格并设置列宽 table = doc.add_table(rows=1, cols=3) table.autofit = False # 禁用自动调整 # 设置列宽 for col in table.columns: col.width = Inches(2) # 每列2英寸宽 # 添加长文本 cell = table.cell(0, 0) cell.text = "这是一段很长的文本,应该会自动换行显示在单元格内。" doc.save('table_autofit.docx')

5.3 文档格式不一致

在不同电脑上打开生成的文档时,可能会遇到格式不一致的问题。这通常是由于缺少特定字体或样式定义造成的。解决方案包括:

  1. 使用常见字体(如微软雅黑、宋体、Arial等)
  2. 在文档中嵌入字体(需要Word软件支持)
  3. 提供PDF版本作为最终交付格式
from docx import Document from docx.shared import Pt from docx.oxml.ns import qn doc = Document() # 定义一组安全字体 safe_fonts = { 'en': 'Arial', # 英文使用Arial 'zh': '微软雅黑' # 中文使用微软雅黑 } # 创建安全样式 safe_style = doc.styles.add_style('SafeStyle', WD_STYLE_TYPE.PARAGRAPH) safe_style.font.name = safe_fonts['en'] safe_style._element.rPr.rFonts.set(qn('w:eastAsia'), safe_fonts['zh']) safe_style.font.size = Pt(12) # 使用安全样式 doc.add_paragraph("This is English text. 这是中文文本。", style='SafeStyle') doc.save('safe_format.docx')

6. 性能优化技巧

当处理大型或复杂的Word文档时,可能会遇到性能问题。以下是一些优化建议:

6.1 批量操作减少保存次数

from docx import Document # 不推荐的写法:频繁保存 doc = Document() for i in range(100): doc.add_paragraph(f"段落 {i}") doc.save('inefficient.docx') # 每次循环都保存 # 推荐的写法:一次性保存 doc = Document() for i in range(100): doc.add_paragraph(f"段落 {i}") doc.save('efficient.docx') # 最后统一保存

6.2 使用内存中的文档处理

对于需要多次修改的文档,可以使用内存中的BytesIO对象,减少磁盘I/O:

from docx import Document from io import BytesIO # 创建内存中的文档 in_memory_doc = BytesIO() # 创建并保存文档到内存 doc = Document() doc.add_paragraph("这是一个内存中的文档示例") doc.save(in_memory_doc) # 从内存重新加载文档 in_memory_doc.seek(0) doc2 = Document(in_memory_doc) doc2.add_paragraph("新增的内容") doc2.save('from_memory.docx')

6.3 预定义样式减少重复设置

from docx import Document from docx.shared import Pt doc = Document() # 预定义常用样式 styles = { 'heading1': doc.styles.add_style('MyHeading1', WD_STYLE_TYPE.PARAGRAPH), 'body': doc.styles.add_style('MyBody', WD_STYLE_TYPE.PARAGRAPH) } # 配置样式 styles['heading1'].font.size = Pt(16) styles['heading1'].font.bold = True styles['body'].font.size = Pt(12) # 使用预定义样式 doc.add_paragraph("章节标题", style='MyHeading1') doc.add_paragraph("正文内容", style='MyBody') doc.save('predefined_styles.docx')

7. 与其他工具的集成

7.1 与Pandas结合处理数据

python-docx可以很好地与Pandas等数据分析库结合,将数据分析结果直接输出到Word文档:

from docx import Document import pandas as pd # 创建示例数据 data = { '产品': ['A', 'B', 'C', 'D'], '销量': [120, 150, 90, 200], '增长率': [0.1, 0.15, -0.05, 0.2] } df = pd.DataFrame(data) # 创建Word文档 doc = Document() doc.add_heading('销售数据分析报告', level=1) # 添加数据表格 doc.add_heading('销售数据概览', level=2) table = doc.add_table(df.shape[0]+1, df.shape[1]) # 添加表头 for j, col in enumerate(df.columns): table.cell(0, j).text = str(col) # 添加数据行 for i in range(df.shape[0]): for j in range(df.shape[1]): table.cell(i+1, j).text = str(df.iloc[i, j]) # 添加分析结论 doc.add_heading('分析结论', level=2) total_sales = df['销量'].sum() growth_products = df[df['增长率'] > 0].shape[0] doc.add_paragraph(f"总销量:{total_sales},其中{growth_products}个产品呈现正增长。") doc.save('sales_report.docx')

7.2 与Matplotlib结合插入图表

虽然python-docx不能直接插入Matplotlib图表,但可以通过将图表保存为图片再插入文档:

from docx import Document import matplotlib.pyplot as plt from io import BytesIO # 创建图表 plt.figure(figsize=(6, 4)) plt.bar(['A', 'B', 'C', 'D'], [120, 150, 90, 200]) plt.title('产品销量') plt.ylabel('销量') # 将图表保存到内存 img_data = BytesIO() plt.savefig(img_data, format='png') img_data.seek(0) # 创建Word文档并插入图表 doc = Document() doc.add_heading('产品销量图表', level=1) doc.add_picture(img_data, width=Inches(5)) doc.save('chart_demo.docx') plt.close()

8. 实际项目中的最佳实践

8.1 文档生成模板化

对于需要频繁生成的标准化文档,建议采用模板化的方法:

from docx import Document class ReportGenerator: def __init__(self, template_path=None): self.template_path = template_path def create_document(self): if self.template_path: return Document(self.template_path) return Document() def generate_report(self, data, output_path): doc = self.create_document() # 添加标题 self._add_title(doc, data['title']) # 添加基本信息 self._add_basic_info(doc, data['info']) # 添加主要内容 self._add_content(doc, data['sections']) # 保存文档 doc.save(output_path) return output_path def _add_title(self, doc, title_text): title = doc.add_heading(title_text, level=0) title.alignment = WD_ALIGN_PARAGRAPH.CENTER def _add_basic_info(self, doc, info_data): doc.add_heading('基本信息', level=1) table = doc.add_table(rows=len(info_data), cols=2) for i, (key, value) in enumerate(info_data.items()): table.cell(i, 0).text = str(key) table.cell(i, 1).text = str(value) def _add_content(self, doc, sections): for section in sections: doc.add_heading(section['title'], level=2) doc.add_paragraph(section['content']) # 使用示例 generator = ReportGenerator() report_data = { 'title': '项目月度报告', 'info': { '项目名称': '数字化转型项目', '报告周期': '2026年1月', '项目经理': '张伟' }, 'sections': [ {'title': '项目进展', 'content': '项目按计划推进,已完成需求分析和设计阶段。'}, {'title': '存在问题', 'content': '开发资源紧张,需要增加人手。'}, {'title': '下月计划', 'content': '完成核心模块开发,开始测试准备。'} ] } generator.generate_report(report_data, 'monthly_report.docx')

8.2 文档版本控制

当需要维护文档的多个版本时,可以结合python-docx和版本控制逻辑:

from docx import Document from datetime import datetime import os class VersionedDocument: def __init__(self, base_path): self.base_path = base_path self.version = 1 self._ensure_directory() def _ensure_directory(self): os.makedirs(self.base_path, exist_ok=True) def _get_versioned_path(self, filename): name, ext = os.path.splitext(filename) timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') return os.path.join(self.base_path, f"{name}_v{self.version}_{timestamp}{ext}") def create_new_version(self, input_path, modifications): # 读取原文档 doc = Document(input_path) # 应用修改 modifications(doc) # 生成版本化文件名并保存 output_path = self._get_versioned_path(os.path.basename(input_path)) doc.save(output_path) # 更新版本号 self.version += 1 return output_path # 使用示例 def add_review_notes(doc): doc.add_heading('审阅意见', level=1) doc.add_paragraph("1. 需要补充项目风险分析") doc.add_paragraph("2. 预算部分需要更详细") versioned_doc = VersionedDocument('document_versions') new_version_path = versioned_doc.create_new_version( 'original.docx', add_review_notes ) print(f"新版本已保存为:{new_version_path}")

8.3 文档质量检查

可以编写自动化脚本来检查生成的文档是否符合公司标准:

from docx import Document class DocumentChecker: def __init__(self, rules): self.rules = rules def check_document(self, doc_path): doc = Document(doc_path) results = { 'errors': [], 'warnings': [] } # 检查标题 if self.rules.get('require_title') and not self._has_title(doc): results['errors'].append("文档缺少标题") # 检查页眉页脚 if self.rules.get('require_header_footer'): if not self._has_header(doc): results['warnings'].append("文档缺少页眉") if not self._has_footer(doc): results['warnings'].append("文档缺少页脚") # 检查字体 if self.rules.get('font_checks'): font_issues = self._check_fonts(doc) results['warnings'].extend(font_issues) return results def _has_title(self, doc): return any(para.style.name.startswith('Heading') for para in doc.paragraphs) def _has_header(self, doc): return any(section.header.is_linked_to_previous is False for section in doc.sections) def _has_footer(self, doc): return any(section.footer.is_linked_to_previous is False for section in doc.sections) def _check_fonts(self, doc): issues = [] allowed_fonts = self.rules['font_checks'].get('allowed_fonts', []) for para in doc.paragraphs: for run in para.runs: if run.font.name and run.font.name not in allowed_fonts: issues.append(f"使用了不允许的字体:{run.font.name}") return issues # 使用示例 rules = { 'require_title': True, 'require_header_footer': True, 'font_checks': { 'allowed_fonts': ['微软雅黑', 'Arial', 'Times New Roman'] } } checker = DocumentChecker(rules) results = checker.check_document('sample.docx') print("检查结果:") print("错误:", results['errors']) print("警告:", results['warnings'])

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询