乐于分享
好东西不私藏

偷懒必备之用Python搞定Word文档

偷懒必备之用Python搞定Word文档
写在前面:怀念从来不是软弱,爱自己才是王道(我又不是什么廉价的人,别自以为是了)。
前几天做了个表,发给对方被批量生成了一样模板的文档合同,感觉也是跑脚本或者写代码生成的,所以就……在网上偷师搞一下~(闲来无事做)
目录
一、安装
二、创建
三、标题(主标题+9级标题)
四、段落(段落样式、自定义样式、分页、段落布局、文字样式)
五、修改(区分标题与段落、样式保留)
六、图片(大小)
七、表格(数据填充、加行、合并、行高列宽、对齐方式、表格样式)

官方链接(这里不让插其他链接,复制到浏览器看吧):

https://python-docx.readthedocs.io/en/latest/

直接复制粘贴里面的一段代码,来看看我们都可以通过Python在Word文档中实现哪些东西:
如图,可以添加标题、段落、图片、表格、分页符,代码如下(同官网,注意改一下图片名称即可,代码中的id有警告,所以换成了r_id):
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().cells    row_cells[0].text = str(qty)    row_cells[1].text = r_id    row_cells[2].text = descdocument.add_page_break()document.save('demo.docx')
一、安装
要怎么实现上面介绍的这些基本功能呢?当然需要先安装一下python-docx库啦,不然直接贴代码会报错的哟~
python-docx库是Python用来编辑Word文档最常用的库,可以创建、修改、读取.docx格式的Word文档。
我们可以通过pip命令安装:
pip install python-docx
安装成功后导入docx包就不会报错咯~
二、创建
接下来我们就可以一步一步实现这些基础功能啦(当时咋没想到直接照着官网做呢,纯·梦到哪里学哪里。就想着:根据Excel表格里的数据自动生成Word文档,首先得会创建、修改,当然图表功能也不能少,最后还想实现个超链接…一键直达,打住!!),先从第一个最基本的创建开始:可以使用Python的python-docx‌库创建一个‌全新的空白Word文档对象‌。
from docx import Document# 创建一个新的文档doc = Document()# 保存文档doc.save('空白文档.docx')
啥也不干,只是创建一个空白的Word文档。第一行代码先导入类;第五行代码初始化一个Document实例,该实例在内存中代表一个空的、包含默认样式和结构的.docx文件;最后执行doc.save('空白文档.docx')将内存中的文档保存为物理文件(注意:如果没有调用save()方法,文档内容仅存在于内存中,关闭程序后会丢失哦,往下翻看第五部分修改中的“注意4”有示例)。   
三、标题
调用Document对象的add_heading‌方法,可以在文档末尾添加一个包含文本的标题段落,默认样式为一级标题Heading 1‌。
from docx import Document# 创建一个新的文档doc = Document()# 添加标题doc.add_heading('这只是一个标题')# 保存文档doc.save('非空白文档.docx')
其他标题样式(0主标题,1-9对应级别的标题):
从源码中可以看出标题的等级一共有0-9这十个等级,依次看下:
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')
如果样式设置大于9会报错的(职业病犯了,想要测试边界值…):
四、段落
调用Document对象的add_paragraph方法,可以将指定的文本内容作为新的普通段落插入到文档末尾,也支持自定义设计样式哦。
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 = 1        print(style.name, end=" "*6)        n += 1
是不是还看到了几个标题样式(Heading1-9、Title),这里可以先说一下,标题和段落的本质是一样的,具体的解释可以看第五部分修改中的“注意”。
我们可以试几个段落样式看看效果(通过名称直接访问就可以应用哦,一定要注意大小写!!):
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')
自定义段落样式
如果上面的这些段落样式无法满足需求,还可以通过add_style自定义创建新的段落样式‌。但是调用时必须指定第二个参数样式类型style_type=WD_STYLE_TYPE.PARAGRAPH来表明这是一个段落样式(其他样式类型可以看WD_STYLE_TYPE 枚举值,详见第七部分表格中的“表格样式”);第一个参数name‌样式名称(传字符串),必须确保名称唯一性。源码:

摩拳擦掌、跃跃欲试中,结果自定义出来的段落样式竟然长这副德行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控制,避免孤行。

文字样式
通过获取段落中的run对象可以直接对段落内的文字进行加粗或倾斜;也可通过run.font对象设置字体的其他属性样式:
1、基础样式:bold加粗、italic斜体、size字体大小(需配合 Pt()一起使用)、name字体名称(对汉字不生效,不知道为啥…);
2、线条位置:strike删除线、double_strike双删除线、superscript上标、subscript下标;
3、文字形态的特殊视觉效果:all_caps全大写、small_caps小型大写字母、outline轮廓、shadow阴影、emboss浮雕、imprint凹刻。
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')
五、修改
“修改”同上面介绍过的“创建”,也是用python-docx‌中的Document类来创建和修改Word文件(.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')
注意:
1、add_paragraph和add_heading的对象类型是一致‌的,返回的都是Paragraph对象‌,只不过add_paragraph创建的是"Normal"样式的普通段落,而add_heading创建的是应用了特定样式的段落标题(如"Heading 1"或"Title")。
2、可以直接通过遍历doc.paragraphs来遍历标题和普通段落,如果需要区分,可以对para.style.name进行判断,如下图。
3、从上面的示例代码和运行结果图可以看出:因为第二个段落是普通样式,直接替换一个Paragraph段落的文本会导致原有的样式消失,所以在文案替换后原有的字体样式就都没有了。
4、注释掉最后一行的物理保存代码,文档中的内容并不会被覆盖掉重新创建,但是在内存里会有4个段落:
样式保留
想保留住原有的样式,可使用run.text进行文本替换而不是直接替换段落。方式:遍历段落中的每个run(一个run通常包含连续的文本片段,但是可能包含不同的样式),这样就可以只替换段落内的文本内容,并且保留住原有的样式。
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')
六、图片
使用add_picture方法可以向Word文档中插入图片,插入的图片是作为一个新的段落添加到文档末尾,并且可以指定图片的宽度参数width或高度height来设置图片形状的大小,单位包括:Inches、Cm和Pt(需要导入对应的模块哦)。

如图,第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')
附源码:
七、表格
使用add_table方法可以向Word文档中添加表格,参数rows、cols用于指定表格的行数和列数,返回的是一个Table对象。源码:
新建一个Word文档,并插入一个两行三列的空表格:
from docx import Document# 创建一个Word文档对象doc = Document()# 添加一个表格到文档中,rows:表格的行数,cols:表格的列数table = doc.add_table(rows=3, cols=2)# 保存文档doc.save('非空白文档.docx')
数据填充
可以通过table.cell(row, col)获取指定的第(row+1)行(col+1)列的单元格(注意索引是从0开始的哦),并设置.text属性填充单元格内容。
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')
其他填充方式
也可以通过table.rows[0].cells获取第一行的单元格,再根据索引可获取对应列的单元格;table.columns[n].cells获取的是第(n+1)列的单元格,再根据索引可以获取对应行的单元格;也可以直接使用table.rows[n].cells[n].text来设置第(n+1)行n列的单元格内容。
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')
加新行
如果表格的行数不确定,就可以使用table.add_row动态地向表格末尾追加新的空白行。
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().cells    row_cells[0].text = data[0]    row_cells[1].text = data[1]    row_cells[2].text = str(data[2])# 保存文档doc.save('非空白文档.docx')
第8行代码:往文档中插入一个两行三列的表格;
11-14行的代码:表示只在第一行的三个单元格中设置内容;
第19行代码:表示在表格的最后面添加新的空白行;
20-22行的代码:表示在新插入的行中对应列的单元格内填充内容。
因为使用for循环遍历的data_list,跑了两遍,所以一共在表格末尾插入了两个新行。
合并单元格
使用cell1.merge(cell2) 合并cell1到cell2的所有单元格,合并后的单元格内容包含所合并单元格内所有值(不同单元格的内容换行展示)。示例中合并的是1行2列到2行3列的单元格,原来的三个单元格(1行2列、1行3列、2行3列)内有值,合并后的单元格会依次换行展示这三个值。未合并的其他单元格和对应内容则正常展示。
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')
行高列宽
使用table.rows[0].height设置第一行单元格的高度;使用Table.cells属性访问所有单元格(可以使用for循环遍历某一列的所有单元格),然后使用cell.width设置列宽或者将某一列所有的单元格都设置一下宽度(使用table.columns[0].width直接设置宽列宽不生效,不知道为啥)。
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')
如果设置的单元格宽度值不同,只会取最大的值设置,和代码的位置无关。下面的示例中创建了含有一个2行2列表格的Word文档(自己试着创建一下吧),然后加载该文档再更改行高列宽(生效的列宽是5英寸和2英寸):
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这种对齐方式        continue    para = 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)

表格样式

我们在使用add_table(rows, cols)来添加表格时,可以直接设置style参数来指定表格样式(不指定则使用默认样式)。也可以通过设置.style属性来应用内置的表格样式(将文末列举模板中的任意一种表格样式直接赋值给table.style就行啦)或自定义样式(可参考第四部分段落中的“自定义段落样式”,类型要设置为表格哦)。
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 = 1    print(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_style    doc.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 = 1    print(tp.name, tp.value, end=" "*6)    n += 1
源码:
终于…终于勉勉强强弄完啦,但是还有一些超链接、从Excel表格中获取数据并写入到Word文档等内容都还没有介绍呢,下次吧……(太晚啦…)
快要被冻死在大东北了,这哪是立秋啊…(立不立秋都想喝奶茶,想喝奶茶的第五七天,#干活哪有不疯的)前天停电,昨天时间点不好(猜猜为啥是今天,太搞笑啦)。今天依然很冷。真·喵一天狗一天。
百无聊赖+1

相关学习资料