官方链接(这里不让插其他链接,复制到浏览器看吧):
https://python-docx.readthedocs.io/en/latest/

from docx import Documentfrom docx.shared import Inchesdocument = Document()document.add_heading('Document Title', 0)p = document.add_paragraph('A plain paragraph having some ')p.add_run('bold').bold = Truep.add_run(' and some ')p.add_run('italic.').italic = Truedocument.add_heading('Heading, level 1', level=1)document.add_paragraph('Intense quote', style='Intense Quote')document.add_paragraph('first item in unordered list', style='List Bullet')document.add_paragraph('first item in ordered list', style='List Number')document.add_picture('pic.jpg', width=Inches(1.25))records = ((3, '101', 'Spam'),(7, '422', 'Eggs'),(4, '631', 'Spam, spam, eggs, and spam'))table = document.add_table(rows=1, cols=3)hdr_cells = table.rows[0].cellshdr_cells[0].text = 'Qty'hdr_cells[1].text = 'Id'hdr_cells[2].text = 'Desc'for qty, r_id, desc in records:row_cells = table.add_row().cellsrow_cells[0].text = str(qty)row_cells[1].text = r_idrow_cells[2].text = descdocument.add_page_break()document.save('demo.docx')

pip install python-docx


from docx import Document# 创建一个新的文档doc = Document()# 保存文档doc.save('空白文档.docx')


from docx import Document# 创建一个新的文档doc = Document()# 添加标题doc.add_heading('这只是一个标题')# 保存文档doc.save('非空白文档.docx')


from docx import Document# 创建一个新的文档doc = Document()# 添加标题doc.add_heading('这只是一个标题,默认样式H1')doc.add_heading('level=0,样式为主标题Title', level=0)for n in range(1, 10):doc.add_heading('标题:当level为{}时,样式设置为H{}'.format(n, n), level=n)# doc.add_heading('标题:当level为10时,报错', level=10)# 保存文档doc.save('非空白文档.docx')


from docx import Documentdocument = Document()# 添加段落document.add_paragraph('这是一个段落哦'*10)document.add_paragraph(('这是一个包含换行的段落哦'*5 + "\n")*3)# 保存文档document.save('非空白文档.docx')

通过源码可以看出:使用第二个参数style能够指定段落样式,官网中给出的样式包括:项目符号列表List Bullet、项目数字列表List Number、引用样式Intense Quote;text文本是支持特殊字符的,比如:换行符\n、制表符\t、回车符\r等,这些字符都可以被自动转换为Word文档对应的格式。

from docx import Document# 创建一个新的文档doc = Document()# 添加五级标题doc.add_heading('这是一个五级标题', 5)# 添加段落doc.add_paragraph('这是一个项目符号列表List Bullet的段落哦转义\\n换行符:\n'*3, style='List Bullet')doc.add_paragraph('这是一个项目数字列表List Number的段落哦转义\\r回车符:\r'*3, style='List Number')doc.add_paragraph('这是一个项目数字列表List Number的段落哦编号2转义\\n:\n'*2, style='List Number')doc.add_paragraph('这是一个引用样式Intense Quote的段落哦制表符\\t:\t'*3, style='Intense Quote')doc.add_paragraph('这是一个引用样式Intense Quote的段落哦转义\\r:\r'*3, style='Intense Quote')# 保存文档doc.save('非空白文档.docx')
除了官网中列举的这三种段落样式,还有没有其他样式呢?当然有啦~
python-docx库中的WD_STYLE_TYPE.PARAGRAPH枚举常量中定义了很多段落样式(在docx.enum.style模块中),我们可以把所有能用到的内置段落样式全部打印出来看一下:
from docx import Documentfrom docx.enum.style import WD_STYLE_TYPEdoc = Document()n = 1print("段落样式:")for style in doc.styles:if style.type == WD_STYLE_TYPE.PARAGRAPH: # 筛选出所有类型为PARAGRAPH的样式if n > 5: # 每五个换行展示一下print()n = 1print(style.name, end=" "*6)n += 1


from docx import Document# 创建一个新的文档doc = Document()# 段落样式para_styles = ["Footer", "Subtitle", "Body Text", "List 3","List Bullet 2", "List Number", "List Continue 3", "Quote"]for n, para_style in enumerate(para_styles):# 添加段落并应用内置段落样式doc.add_paragraph(f'{n}测试段落样式{para_style}'*3, style=para_style)doc.add_paragraph(f'{n}测试段落样式{para_style}' * 3, style=para_style)# 保存文档doc.save('非空白文档.docx')

摩拳擦掌、跃跃欲试中,结果自定义出来的段落样式竟然长这副德行hahaha…

from docx import Documentfrom docx.enum.style import WD_STYLE_TYPEfrom docx.shared import Ptfrom docx.enum.text import WD_ALIGN_PARAGRAPHdoc = Document()# 添加一个段落doc.add_paragraph('这是一个测试段落。AyuthayaChalkduster')# 创建自定义段落样式heading_style = doc.styles.add_style("new_parastyle", WD_STYLE_TYPE.PARAGRAPH)heading_style.font.name = "Chalkduster"heading_style.font.size = Pt(25)heading_style.font.bold = Trueheading_style.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER# 应用样式到段落p = doc.add_paragraph("自定义段落样式AyuthayaChalkduster")p.style = "new_parastyle"# 保存文档doc.save('非空白文档.docx')
示例代码中可以看出:除了调用add_paragraph方法时直接指定style参数设置段落样式;还可以通过访问文档中的段落对象修改其style属性来改变段落样式(第20行代码:paragraph.style)。
分页符
对于批量生成的合同,第一个人的内容完成了,不管下面空了多少都需要新增一页处理其他人员的数据内容,这时候就需要介绍一下分页符了。python-docx库的add_page_break方法就可以在Word文档中插入一个分页符,强制后续内容从新的一页开始。适用于:章节分隔、报表分页或强制特定内容(如多人合同、封面与正文等)分开显示。

from docx import Documentdoc = Document()# 添加分页符,后续内容将出现在第二页doc.add_page_break()# 添加分页后的内容doc.add_paragraph('这是第二页。')# 保存文档doc.save('非空白文档.docx')
add_page_break可以直接由Document对象调用,不需要任何参数。它会在文档当前位置插入一个分页符,并返回一个包含该分页符的段落对象。源码:

如果我们需要调整段落的行间距、缩进等布局时,就需要使用ParagraphFormat对Word文档的段落布局属性进行设置,包括:行距、缩进、对齐、间距及分页控制。可通过paragraph.paragraph_format属性访问对应内容。

from docx import Documentfrom docx.enum.text import WD_ALIGN_PARAGRAPH, WD_LINE_SPACINGfrom docx.shared import Cmdoc = Document()# 添加一个段落doc.add_paragraph('这是一个测试段落1。'*5)# 添加第二个段落,设置行间距为2倍行距p = doc.add_paragraph('这是一个测试段落2。'*5)p.paragraph_format.line_spacing = 2# 添加第三个段落,设置1.5倍行间距p = doc.add_paragraph('这是一个测试段落3。'*5)# SINGLE(单倍)、ONE_POINT_FIVE(1.5倍)、DOUBLE(双倍)、EXACTLY(固定值)、MULTIPLE(多倍)等p.paragraph_format.line_spacing_rule = WD_LINE_SPACING.ONE_POINT_FIVE# 添加第四个段落,设置左缩进为2厘米,右缩进为1厘米p = doc.add_paragraph('这是一个测试段落4。'*5)p.paragraph_format.left_indent = Cm(2)p.paragraph_format.right_indent = Cm(1)# 添加第五个段落,设置首行缩进1厘米p = doc.add_paragraph('这是一个测试段落5。'*5)p.paragraph_format.first_line_indent = Cm(1)# 添加第六个段落,设置段落水平对齐为右对齐p = doc.add_paragraph('这是一个测试段落6。'*5)# LEFT(左对齐)、CENTER(居中)、RIGHT(右对齐)和 JUSTIFY(两端对齐)等p.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.RIGHT# 添加第七个段落,设置段前间距和段后间距p = doc.add_paragraph('这是一个测试段落7。'*5)p.paragraph_format.space_before = Cm(2)p.paragraph_format.space_after = Cm(1)# 添加一个普通段落doc.add_paragraph('这是一个测试段落8。'*5)# 添加第九个段落,在段落前插入分页符。还可以设置:keep_with_next、keep_together、widow_control、page_break_beforep = doc.add_paragraph('防止段落内部分页9。'*15)p.paragraph_format.keep_together = Truep = doc.add_paragraph('在段落前插入分页符10。'*5)p.paragraph_format.page_break_before = True# 保存文档doc.save('非空白文档.docx')
详细介绍一下这些内容:
行距:
line_spacing:可设置为固定值(如代码中的倍数2),常配合下面的规则使用,当规则为EXACTLY或AT_LEAST时需传入Pt()长度对象;当规则为MULTIPLE时传入浮点数;
line_spacing_rule:行间距的规则类型包括WD_LINE_SPACING.SINGLE(单倍)、ONE_POINT_FIVE(1.5倍)、DOUBLE(双倍)、AT_LEAST(最小行高)、EXACTLY(固定值)、MULTIPLE(多倍)。
WD_LINE_SPACING枚举所包含的常用行间距值如图:

缩进设置:
left_indent/right_indent:可以设置左缩进/右缩进,单位可以是:Pt、Inches或Cm;
first_line_indent:可以设置首行缩进(正值)或悬挂缩进(负值)。
对齐方式:
alignment用来设置段落的水平对齐,比如:WD_ALIGN_PARAGRAPH.LEFT(左对齐)、CENTER(居中)、RIGHT(右对齐)。详见下面第七部分表格中的“对齐方式”,WD_ALIGN_PARAGRAPH = WD_PARAGRAPH_ALIGNMENT。
间距:
space_before/space_after:设置段前间距/段后间距(相邻段落间的实际间距取两者最大值),单位可以是:Pt、Inches或Cm。
分页与布局控制:
keep_with_next:保持当前段落与下一段在同一页,如果不在同一页会强制插入到下一页;
keep_together:防止段落内部分页,如果出现分页会强制在下一页插入该段落;
page_break_before:在段落前插入分页符,该段落会自动出现在下一页。
widow_control:启用widow/orphan控制,避免孤行。

from docx import Documentfrom docx.shared import RGBColor, Pt# 创建一个新的文档doc = Document()# 添加五级标题doc.add_heading('这是一个五级标题', 5)# 添加段落para = doc.add_paragraph('这是一个普通段落文案')para.add_run('加粗了').bold = Truepara.add_run('普通的')para.add_run('倾斜的').italic = Truepara.add_run('蓝色的').font.color.rgb = RGBColor(0, 0, 255)para.add_run('Ayuthaya字体').font.name = "Ayuthaya"para.add_run('putong字体')para.add_run('下划线').font.underline = Truepara.add_run('删除线').font.strike = Truepara.add_run('字号20像素').font.size = Pt(20)para.add_run('双删除线').font.double_strike = Truepara.add_run('上标').font.superscript = Truepara.add_run('下标').font.subscript = Truepara.add_run('全大写quanbuDAxie').font.all_caps = Truepara.add_run('小型大写字母QuanbudaXIE').font.small_caps = Truepara.add_run('轮廓outline').font.outline = Truepara.add_run('阴影shadow').font.shadow = Truepara.add_run('浮雕emboss').font.emboss = Truepara.add_run('凹刻imprint').font.imprint = True# 保存文档doc.save('非空白文档.docx')

1、加载现有文件:传入.docx文件的路径字符串或文件对象,就可以返回对应的Document对象进行编辑。
2、创建新文档:若不传入任何参数(或传入None),会自动加载内置的默认模板,返回一个空的Document对象,常用于创建新文档。
from docx import Document# 加载已存在的Word文档doc = Document('非空白文档.docx')# 添加文档末尾加一个新段落para = doc.add_paragraph('这是新加的一个段落文本,在文档末尾哦~')# 修改文档中第一个段落的文本if doc.paragraphs:fir_para = doc.paragraphs[0]# 直接赋值修改第一个段落的标题fir_para.text = "第一段标题已改,原标题是:" + fir_para.text# 可以选择性替换第二个段落中的部分文本doc.paragraphs[1].text = doc.paragraphs[1].text.replace("一个", "被替换的")# 保存文档doc.save('非空白文档.docx')


from docx import Document# 加载现有文档doc = Document('非空白文档.docx')for paragraph in doc.paragraphs:for run in paragraph.runs:if '蓝色' in run.text:# 替换文本并保持原有样式run.text = run.text.replace('蓝色', '保留蓝色')if '浮雕' in run.text:# 替换文本并保持原有样式run.text = run.text.replace('浮雕', '保留浮雕')# 保存文档doc.save('非空白文档.docx')


如图,第9行代码:只需提供图片的本地路径、未指定大小时图片按原始分辨率显示;第12行代码:只设置一个宽度,另一个参数就会根据比例自动调整,这样可以保持图片的原始形状比例(相当于Word文档中的锁定纵横比),当然只设置一个高度也是可以的(示例中width=Cm(5)表示图片宽度设置为5厘米,高度按比例自动调整);第14行代码:同时指定图片的宽width和高height(图片就已经变形啦);第17/18行代码:使用其他单位来设置图片的大小(width=Inches(1)表示图片宽度设置为1英寸、Pt(100)宽度和高度都为100像素点)。
from docx import Documentfrom docx.shared import Cm, Inches, Pt# 创建一个新的文档doc = Document()# 在文档中添加一个图片,指定图片路径,默认使用原尺寸图片doc.add_picture('pic.jpg')# 在文档中添加一个图片,指定宽度,高度按比例自动调整doc.add_picture('pic.jpg', width=Cm(5))# 在文档中添加一个图片,指定宽度和高度doc.add_picture('pic.jpg', width=Cm(3), height=Cm(3))# 在文档中添加一个图片,使用其他单位指定大小doc.add_picture('pic.jpg', width=Inches(1))doc.add_picture('pic.jpg', width=Pt(100), height=Pt(100))# 保存文档doc.save('非空白文档.docx')


from docx import Document# 创建一个Word文档对象doc = Document()# 添加一个表格到文档中,rows:表格的行数,cols:表格的列数table = doc.add_table(rows=3, cols=2)# 保存文档doc.save('非空白文档.docx')


from docx import Document# 创建一个Word文档对象doc = Document()# 添加一个表格到文档中,rows:表格的行数,cols:表格的列数table = doc.add_table(rows=3, cols=2)# 填充表格数据for row in range(3): # 行数for col in range(2): # 列数cell = table.cell(row, col)cell.text = f'第{row+1}行&第{col+1}列的单元格数据' # 填充数据# 保存文档doc.save('非空白文档.docx')

from docx import Document# 创建一个Word文档对象doc = Document()# 添加一个表格到文档中,rows:表格的行数,cols:表格的列数table = doc.add_table(rows=3, cols=4)# 获取第一行单元格row_cells = table.rows[0].cells# 设置第一行第一列的单元格内容row_cells[0].text = "第一行第一列有内容哦"# 设置第一行第三列的单元格内容row_cells[2].text = "一行三列"# 设置第二行第二列的单元格内容table.rows[1].cells[1].text = "第2行第2列"# 获取第四列单元格col_cells = table.columns[3].cells# 设置第四列第三行的单元格内容col_cells[2].text = "第四列第三行的单元格也是有内容的哦~\n"*2# 保存文档doc.save('非空白文档.docx')

from docx import Document# 创建一个Word文档对象doc = Document()# 添加一个表格到文档中,rows:表格的行数,cols:表格的列数table = doc.add_table(rows=2, cols=3)# 填充row_cells = table.rows[0].cellsrow_cells[0].text = "一行一列"row_cells[1].text = "一行二列"row_cells[2].text = "一行三列"# 加数据行data_list = [["31", "32", 33], ["41", "42", 43]]for data in data_list:row_cells = table.add_row().cellsrow_cells[0].text = data[0]row_cells[1].text = data[1]row_cells[2].text = str(data[2])# 保存文档doc.save('非空白文档.docx')

from docx import Document# 新建doc = Document()# 添加一个表格到文档中,rows:表格的行数,cols:表格的列数table = doc.add_table(rows=3, cols=4)# 填充row_cells = table.rows[0].cellsrow_cells[0].text = "一行一列"row_cells[1].text = "一行二列"row_cells[2].text = "一行三列"table.rows[1].cells[2].text = "2行3列"table.rows[2].cells[3].text = "3行4列"# 合并row_cells[1].merge(table.rows[1].cells[2])# 保存文档doc.save('非空白文档.docx')

from docx import Documentfrom docx.shared import Inches# 创建一个Word文档对象doc = Document()# 添加一个表格到文档中,rows:表格的行数,cols:表格的列数table = doc.add_table(rows=3, cols=2)table.rows[0].height = Inches(3) # 设置第一行高度为3英寸table.rows[2].height = Inches(1) # 设置第三行高度为1英寸for cell in table.columns[0].cells:cell.width = Inches(1) # 设置第一列的宽度为1英寸# 保存文档doc.save('非空白文档.docx')

from docx import Documentfrom docx.shared import Inches# 创建一个Word文档对象doc = Document('非空白文档.docx')# 获取文档中的第一个表格table = doc.tables[0]table.rows[0].height = Inches(2) # 设置第一行高度为3英寸# # 设置整列的宽度,不生效# table.columns[0].width = Inches(2)# table.columns[1].width = Inches(1)# 只能把这一列所有单元格都设置一下宽度才可以(推荐使用for循环)table.columns[0].cells[0].width = Inches(5)table.columns[0].cells[1].width = Inches(3)table.columns[1].cells[0].width = Inches(1)table.columns[1].cells[1].width = Inches(2)# 保存文档doc.save('非空白文档.docx')
对齐方式
设置单元格的对齐方式可以通过访问单元格的paragraph属性,并设置其alignment属性。alignment属性可以是:居左LEFT=0、居中CENTER=1、居右RIGHT=2、两端对齐(完全两端对齐,最后一行左对齐)JUSTIFY=3、分散对齐(强制字符/单词拉伸填满整行)DISTRIBUTE=4。

from docx import Documentfrom docx.shared import Cm# 创建一个Word文档对象doc = Document()# 添加一个表格到文档中,rows:表格的行数,cols:表格的列数table = doc.add_table(rows=5, cols=2)# 填充表格数据for row in range(5):for col in range(2):cell = table.cell(row, col)cell.text = f'{row+1}行, {col+1}列' # 填充数据cell.width = Cm(7) # 设置单元格宽度为7厘米cell.paragraphs[0].alignment = row # 设置文本对齐方式(0居左,1为居中,2居右,3两端对齐,4分散对齐,等)# 保存文档doc.save('非空白文档.docx')
其他类型的文本对齐方式,还包括:
mediumKashida中等拉伸对齐JUSTIFY_MED=5:两端对齐(中度压缩字符间距),段落文本同时靠左右边界对齐,通过适度压缩字符间距实现视觉平衡,压缩强度介于“低”与“高”之间;
highKashida最大拉伸对齐JUSTIFY_HI=7:两端对齐(高度压缩字符间距),在阿拉伯语等需字符连写语言的对齐排版中,允许在字母间插入最长间距连接线(Kashida),以最大化拉伸单词间距达成两端对齐效果;
lowKashida低度拉伸对齐JUSTIFY_LOW=8:两端对齐(轻微压缩字符间距),段落左右边缘整齐,字间距略微缩小(相比“完全两端对齐”压缩程度更低,比“中/高压缩比”更宽松);
thaiDistribute泰语格式对齐THAI_JUSTIFY=9:两端对齐(针对泰语段落的两端对齐),根据泰语格式配置进行左右两端对齐,强制段落(除最后一行外)首尾字符分别贴合左右边距,通过增加或减少单词之间的空格来填充行宽,严禁拉伸单词内部字符(区别于justify或distribute)。

WD_PARAGRAPH_ALIGNMENT/WD_ALIGN_PARAGRAPH是python-docx库中用于指定段落水平对齐方式的枚举常量集合,共9种模式。可以简单看下这九种对齐方式(后四种我没用过,注意枚举值中没有6!!):

from docx import Document# 创建一个Word文档对象doc = Document()# 填充表格数据for n in range(10):if n == 6: # 没有6这种对齐方式continuepara = doc.add_paragraph("这是第{}段文字内容哦, This is a paragraph .".format(n)*2)para.alignment = n # 设置文本对齐方式(0居左,1为居中,2居右,3两端对齐,4分散对齐,等)# 保存文档doc.save('非空白文档.docx')
再来看下源码:

可以通过循环遍历查看这些枚举成员的名称和值:
from docx.enum.text import WD_PARAGRAPH_ALIGNMENTfor a in WD_PARAGRAPH_ALIGNMENT:print(a.name, a.value)

表格样式


from docx import Document# 创建一个Word文档对象doc = Document()# 添加表格table = doc.add_table(rows=2, cols=2)table.rows[1].cells[0].text = "测试文本"# 可以单独设置表格样式table.style = 'Light Shading Accent 1'doc.add_paragraph()# 添加表格,通过参数指定表格样式table1 = doc.add_table(rows=1, cols=2, style='Dark List')table1.rows[0].cells[0].text = "测试文本1"# 保存文档doc.save('非空白文档.docx')

WD_STYLE_TYPE是python-docx库中用于定义样式类型的枚举类,位于docx.enum.style模块中。该枚举包含以下四种主要的样式类型,对应Word中的不同格式对象:
WD_STYLE_TYPE.PARAGRAPH:段落样式;
WD_STYLE_TYPE.CHARACTER:字符样式;
WD_STYLE_TYPE.TABLE:表格样式;
WD_STYLE_TYPE.LIST:列表样式。

from docx import Documentfrom docx.enum.style import WD_STYLE_TYPEdoc = Document()# 筛选出所有类型为TABLE的样式table_styles = [s.name for s in doc.styles if s.type == WD_STYLE_TYPE.TABLE]n = 1print("可用的表格样式包括:")for style_name in table_styles:if n > 5:print()n = 1print(style_name, end=" "*6)n += 1

基础通用类:Normal Table、Table Grid;
浅色底纹系列:Light Shading、Light Shading Accent 1~6;
浅色列表系列:Light List、Light List Accent 1~6;
浅色网格系列:Light Grid、Light Grid Accent 1~6;
中等底纹系列:Medium Shading 1、Medium Shading 1 Accent 1~6、Medium Shading 2、Medium Shading 2 Accent 1~6;
中等列表系列:Medium List 1、Medium List 1 Accent 1~6、Medium List 2、Medium List 2 Accent 1~6;
中等网格系列:Medium Grid 1、Medium Grid 1 Accent 1~6、Medium Grid 2、Medium Grid 2 Accent 1~6、Medium Grid 3、Medium Grid 3 Accent 1~6;
深色系列:Dark List、Dark List Accent 1~6、Colorful Shading、Colorful Shading Accent 1~6、Colorful List、Colorful List Accent 1~6、Colorful Grid、Colorful Grid Accent 1~6。

from docx import Documentdoc = Document()table_styles = ["Normal Table", "Table Grid", "Light Shading Accent 6", "Light List Accent 1", "Light Grid Accent 3","Medium Shading 1 Accent 1", "Medium Shading 2", "Medium List 1", "Medium List 2 Accent 5","Medium Grid 1", "Medium Grid 2", "Medium Grid 3 Accent 3", "Dark List Accent 4","Colorful Shading", "Colorful List Accent 5", "Colorful Grid Accent 2"]# 未设置样式table = doc.add_table(rows=2, cols=5)doc.add_paragraph()for table_style in table_styles:table = doc.add_table(rows=2, cols=2, style=table_style)table.rows[0].cells[0].text = table_styledoc.add_paragraph()# 保存文档doc.save('非空白文档.docx')
from docx.enum.style import WD_BUILTIN_STYLEn = 1# 添加表格for tp in WD_BUILTIN_STYLE:if n > 5:print()n = 1print(tp.name, tp.value, end=" "*6)n += 1


(太晚啦…)

夜雨聆风