python-docx生成目录方法探索及汇总整理

前言

  • 工具:python-docx == 0.8.11
  • 环境:Linux/windows
  • 需求:使用python自动生成word文档时,生成目录。
  • 先放结论:如果项目需求必须要基于linux环境,不能基于win32com等依赖于windows系统的库,目前没有找到完美的方案直接自动生成带标题页码的目录,只能通过一些折中或者间接的方式,尽可能简单实现,且“像”一个完整的目录。

背景-使用python-docx生成报告思路简述

使用python-docx生成word报告一般可以有两种思路:

  1. 直接使用python-docx逐段生成内容,如:
from docx import Document

doc = Document() 
doc.add_paragraph('文档标题')

doc.add_paragraph('第一部分',style='Heading 1')
doc.add_paragraph('1.二级标题',style='Heading 2', )
# 任意生成些段落
for i in range(15):
    doc.add_paragraph(str(i))
doc.add_paragraph('第二部分', style='Heading 1')
doc.add_paragraph('1.二级标题', style='Heading 2')
for i in range(15):
    doc.add_paragraph(str(i))
doc.add_paragraph('2.二级标题', style='Heading 2')
for i in range(15):
    doc.add_paragraph(str(i))
doc.add_paragraph( '3.二级标题', style='Heading 2')
doc.save('result.docx')
  1. 基于docx文件,事先准备.docx模板, 可采用特定的占位标记,遍历文档的paragraphs对象,向文件中填充内容。该方法适用于word内容大纲相对固定的报告生成,优点是方便设置文档的排版及内容格式等,因此在目录生成上可以直接在模板文档中插入目录,需要解决的问题是页码更新。
    *.docx模板文档示例如下:
    在这里插入图片描述
    生成内容代码如下:
from docx import Document

doc = Document('template.docx')  # 参数为.docx模板文件路径

def write_to_paragraph(paragraph, text):
	# 该方法替换的文字内容可保持原段落格式
	paragraph.runs[0].text = text
    for i in par.runs[1:]:
        i.clear()

for p in doc.paragraphs:
	if p.text == '<<p1>>':
		# write_to_paragraph(p, text)
		p.text = 'replace p1 text'
	elif p.text == '<<p2>>':
		# write_to_paragraph(p, text)
		p.text = 'replace p2 text'
	# 其他段落略
doc.save('result.docx')

生成目录方法

使用python-docx生成目录(或者说基于修改xml的方式生成或处理docx文档的工具)的难点主要在于页码的生成和更新,目录需要获取的标题所在的页码,是通过布局引擎提供的分页功能实现的,布局引擎是Word 客户端中内置的一个非常复杂的软件,用 Python 编写页面布局引擎并不是一个好主意。
因此,简化折中的方式可以包括:

  1. 只包含各级标题,无页码;
  2. 包含各级标题且可点击链接至标题所在位置,无页码;
  3. 包含各级标题和页码,但需手动或半自动更新目录域。

不包含页码

1.遍历Document对象的paragraph列表,通过paragraph对象的style.name属性判断标题级别,并获取标题文字,生成目录。

from docx import Document

doc = Document('result.docx')
for paragraph in doc.paragraphs:
    if 'Heading' in paragraph.style.name:
    	text = paragraph.text
    	# level = int(paragraph.style.name[-1])		
		new_p = doc.add_paragraph('text')
doc.save('result1.docx')

2.标题增加链接:标题添加bookmark书签,生成目录时添加超链接至书签位置。

  • 方式一:使用python-docx生成标题

from docx import Document

def add_title_with_bookmark(doc, text, style, bookmark_id):

	paragraph = doc.add_paragraph(text, style=style)
	
    run = paragraph.add_run()
    tag = run._r
    start = OxmlElement('w:bookmarkStart')
    start.set(qn('w:id'), str(bookmark_id))
    start.set(qn('w:name'), bookmark_text)
    tag.append(start)

    tr = OxmlElement('w:r')
    tr.text = ''
    tag.append(tr)

    end = OxmlElement('w:bookmarkEnd')
    end.set(qn('w:id'), str(bookmark_id))
    end.set(qn('w:name'), bookmark_text)
    tag.append(end)
  
doc = Document() 
doc_title 
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值