目录
- 引言
- 打开文档
- 正文应用字符样式(字体,大小,颜色)
- 添加标题
- 操作段落
- 添加段落
- 删除段落
- 替换文字
- 设置段落对齐方式
- 字体格式
- 添加分页符
- 添加表
- 添加图片
- 图像大小
- 应用段落样式
- 应用粗体和斜体
- 应用字符样式
- 指定路径并保存文件
- 实际案例
引言
入门python-docx很容易。让我们来看一下基础知识。
打开文档
你需要的第一件事是工作的文档。最简单的方法是:
from docx import Document | |
document = Document() |
这将打开一个基于默认“模板”的空白文档,您可以打开并使用现有的Word文档的工作python-docx,我们会让事情变得简单。
正文应用字符样式(字体,大小,颜色)
# 设置正文字型 英文字型:Times New Roman; 中文字型:宋体 | |
document.styles['Normal'].font.name = 'Times New Roman' | |
document.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体') | |
# 设置正文字体大小 | |
document.styles['Normal'].font.size = Pt(12) | |
# 设置正文字体颜色 | |
document.styles['Normal'].font.color.rgb = RGBColor(0, 0, 0) |
添加标题
document.add_heading('The REAL meaning of the universe')
默认情况下,这会添加顶级标题,Word中显示为“标题1”。当您需要子节的标题时,只需指定所需的级别为1到9之间的整数:
document.add_heading('The role of dolphins', level=2)
level代表word文档内的标题等级,从0开始。
操作段落
添加段落
段落是Word的基础。它们用于正文文本,但也用于标题和列表项目(如项目符号)。
这里是添加一个最简单的方法:
paragraph_format= document.add_paragraph('床前明月光\n疑是地上霜\n举头望明月\n低头思故乡', style='') | |
paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER #文本居中 | |
#左缩进 | |
from docx.shared import Inches | |
paragraph_format.left_indent = Inches(0.3) | |
#首行缩进 | |
paragraph_format.first_line_indent = Inches(0.3) | |
#上行间距 | |
from docx.shared import Pt | |
paragraph_format.space_before = Pt(18) | |
#下行间距 | |
paragraph_format.space_after = Pt(12) | |
#增加分页 | |
document.add_page_break() |
style设置段落样式,有两种类型:
- ①List Bullet:项目符号
- ②List Number:列表编号
此方法返回对段落的引用,新添加的段落在文档的结尾。
还可以使用一个段落作为“光标”,并在其上直接插入一个新段落:
prior_paragraph = paragraph.insert_paragraph_before('Lorem ipsum')
删除段落
python-docx中并没有提供delete()
方法, github上给出了解决方法:
def delete_paragraph(paragraph): | |
p = paragraph._element | |
p.getparent().remove(p) | |
# p._p = p._element = None | |
paragraph._p = paragraph._element = None |
经试验, 此方法对删除段落,表格,标题, 图片都是管用的:
from docx import Document | |
docx = Document('word_file.docx') | |
def delete_docx_prefix_description(docx): | |
delete_paragraph(docx.tables[0]) # 删除word中第一个table | |
for p in docx.paragraphs: | |
delete_paragraph(p) | |
if ''.join(p.text.split(' ')).lower()=='header_keyword': | |
break | |
for p in docx.paragraphs: | |
if p.text.lower()=='': # 删除word中在开始部分的空白段落 | |
delete_paragraph(p) | |
else: | |
break |
替换文字
# 将想要替换的内容写成字典的形式, | |
# dict = {"想要被替换的字符串": "新的字符串"} | |
replace_dict = { | |
"苹果":"apple", | |
"香蕉":"banana", | |
"猕猴桃":"Kiwi fruit", | |
"火龙果":"pitaya", | |
} | |
def check_and_change(document, replace_dict): | |
""" | |
遍历word中的所有 paragraphs,在每一段中发现含有key 的内容,就替换为 value 。 | |
(key 和 value 都是replace_dict中的键值对。) | |
""" | |
for para in document.paragraphs: | |
for i in range(len(para.runs)): | |
for key, value in replace_dict.items(): | |
if key in para.runs[i].text: | |
print(key+"->"+value) | |
para.runs[i].text = para.runs[i].text.replace(key, value) | |
return document |
设置段落对齐方式
paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
这里使用了CENTER这个枚举值。
字体格式
这里引用一下官方文档的说明:
In order to understand how bold(粗体) and italic(斜体) work, you need to understand a little about what goes on inside a paragraph. The short version is this:
- A paragraph holds all the block-level(块级元素) formatting, like indentation(缩进), line height, tabs, and so forth.
- Character-level formatting, such as bold and italic, are applied at the run level(运行级别). All content within a paragraph must be within a run, but there can be more than one. So a paragraph with a bold word in the middle would need three runs, a normal one, a bold one containing the word, and another normal one for the text after.
When you add a paragraph by providing text to the method, it gets put into a single run. You can add more using the method on the paragraph:.add_paragraph().add_run()
为此需要设置第一次运行的正常文本,这个文本可以为空。
P = document.add_paragraph('') | |
run = P.add_run("静夜思") | |
run.font.color.rgb = RGBColor(255, 0, 0) | |
run.font.size = Pt(14) | |
run.bold = True | |
run.italic = False | |
P.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER | |
#加粗 | |
paragraph.add_run(u'粗体').bold = True | |
#斜体 | |
paragraph.add_run(u'斜体、').italic = True | |
#设置中文字体 | |
paragraph.add_run(u'设置中文字体,') | |
run.font.name=u'宋体' | |
r = run._element | |
r.rPr.rFonts.set(qn('w:eastAsia'), u'宋体') | |
#字号 | |
paragraph.add_run(u'设置字号').font.size=Pt(24) | |
#增加引用 | |
document.add_paragraph('Intense quote', style='Intense Quote') | |
#增加有序列表 | |
document.add_paragraph( | |
u'有序列表元素1',style='List Number' | |
) | |
document.add_paragraph( | |
u'有序列别元素2',style='List Number' | |
) | |
#增加无序列表 | |
document.add_paragraph( | |
u'无序列表元素1',style='List Bullet' | |
) | |
document.add_paragraph( | |
u'无序列表元素2',style='List Bullet' | |
) | |
#增加图片 | |
document.add_picture('jdb.jpg',width=Inches(1.25)) | |
#增加表格 | |
table = document.add_table(rows=3,cols=3) | |
hdr_cells=table.rows[0].cells | |
hdr_cells[0].text="第一列" | |
hdr_cells[1].text="第二列" | |
hdr_cells[2].text="第三列" | |
hdr_cells = table.rows[1].cells | |
hdr_cells[0].text = '2' | |
hdr_cells[1].text = 'aerszvfdgx' | |
hdr_cells[2].text = 'abdzfgxfdf' | |
hdr_cells = table.rows[2].cells | |
hdr_cells[0].text = '3' | |
hdr_cells[1].text = 'cafdwvaef' | |
hdr_cells[2].text = 'aabs zfgf' |
添加分页符
你想要下一个文本在一个单独的页面
document.add_page_break()
添加表
一个经常遇到的内容,它自己的表格呈现,排列在整齐的行和列。
以下是添加表格的方法:
table = document.add_table(rows=2, cols=2)
表具有几个属性和方法,您将需要它们来填充它们。访问单个单元格可能是一个好的开始的地方。
作为基线,我们可以始终按其行和列指示访问单元格:
cell = table.cell(0, 1) | |
cell.text = 'parrot, possibly dead' |
通常,一次访问一行单元格更容易,例如,当从数据源填充可变长度的表时。在.rows 一个表中的属性提供给单独的行,每个都具有一个 .cells属性。该.cells两个物业Row和Column 支持索引访问,就像一个列表:
row = table.rows[1] | |
row.cells[0].text = 'Foo bar to you.' | |
row.cells[1].text = 'And a hearty foo bar to you too sir!' |
在.rows
和.columns
桌子上的集合是可迭代的,这样你就可以直接在使用它们for循环。
相同的.cells上行或列序列:
for row in table.rows: | |
for cell in row.cells: | |
print(cell.text) |
如果你想在表中的行或列的计数,只要使用len()
的顺序:
row_count = len(table.rows) | |
col_count = len(table.columns) |
您还可以以递增方式向表中添加行,如下所示:
row = table.add_row()
这对于我们上面提到的可变长度表场景非常方便:
# get table data ------------- | |
items = get_things_from_database_or_something() | |
# add table ------------------ | |
table = document.add_table(1, 3) | |
# populate header row -------- | |
heading_cells = table.rows[0].cells | |
heading_cells[0].text = 'Qty' | |
heading_cells[1].text = 'SKU' | |
heading_cells[2].text = 'Description' | |
# add a data row for each item | |
for item in items: | |
cells = table.add_row().cells | |
cells[0].text = str(item.qty) | |
cells[1].text = item.sku | |
cells[2].text = item.desc |
同样的工作对列,虽然我还没有看到它的一个用例。Word具有一组预格式化的表格样式,您可以从其表格样式库中选择。您可以将其中的一个应用于表格,
如下所示:
table.style = 'LightShading-Accent1'
通过从表样式名称中删除所有空格形成样式名称。通过将鼠标悬停在Word的表样式库中的缩略图上,可以找到表样式名称。
添加图片
Word中,您可以将图像使用的文档中的菜单项
document.add_picture('image-filename.png')
此示例使用路径,从本地文件系统加载图像文件。你也可以使用一个类文件对象,本质上就像一个打开的文件的任何对象。如果您从数据库或网络检索图像,并且不想获取涉及的文件系统,这可能很方便。
图像大小
默认情况下,添加图像出现在本地的大小。这通常比你想要的更大。本机大小的计算方法。因此,具有300dpi分辨率的300×300像素图像出现在一平方英寸。问题是大多数图像不包含dpi属性,它默认为72 dpi。这将使同一图像在一边,在一半左右的某处出现4.167英寸。pixels / dpi
要获得所需的图像大小,您可以以方便的单位指定其宽度或高度,如英寸或厘米:
from docx.shared import Inches | |
document.add_picture('image-filename.png', width=Inches(1.0)) |
你可以自由地指定宽度和高度,但通常你不想要。如果仅指定一个,python-docx用它来计算出其他的适当换算值。这样的高宽比是保留的,你的图像看起来不拉伸。
在Inches和Cm提供课程,让你指定派上用场单位进行测量。在内部,python-docx使用英语公制单位,914400为英寸。所以,如果你忘记了,只是把喜欢的东西width=2,你会得到一个非常小的图像:)。你需要从导入docx.shared 子包。你可以在算术中使用它们,就像它们是一个整数,事实上它们是。因此,像一个表达式的作品就好了。width = Inches(3) /thing_count
应用段落样式
如果你不知道一个Word段落风格是你应该肯定检查出来。基本上,它允许您将一整套格式化选项立即应用到段落。这很像CSS样式,如果你知道那些是。
您可以在创建段落时应用段落样式:
document.add_paragraph('Lorem ipsum dolor sit amet.', style='ListBullet')
这种特殊的风格导致段落显示为一个子弹,一个非常方便的东西。您也可以在之后应用样式。
这两行相当于上面的一行:
paragraph = document.add_paragraph('Lorem ipsum dolor sit amet.') | |
paragraph.style = 'ListBullet' |
在此示例中,样式使用其样式ID“ListBullet”指定。通常,通过去除样式名称中出现在Word用户界面(UI)中的空格来形成样式ID。所以风格’列表3号’将被指定为’ListNumber3’。但是,请注意,如果您使用的是本地化版本的Word,则样式ID可能来自英语样式名称,并且可能不会完全对应于其在Word UI中的样式名称。
应用粗体和斜体
paragraph = document.add_paragraph('Lorem ipsum ') | |
paragraph.add_run('dolor sit amet.') |
Run对象既有.bold和.italic属性,您可以设置其值为运行:
paragraph = document.add_paragraph('Lorem ipsum ') | |
run = paragraph.add_run('dolor') | |
run.bold = True | |
paragraph.add_run(' sit amet.') |
其产生的文字,看起来像这样:'Lorem存有悲坐阿梅德。“
请注意,您可以对结果集粗体或斜体正确的.add_run(),如果你不需要它为别的:
paragraph.add_run('dolor').bold = True | |
# is equivalent to: | |
run = paragraph.add_run('dolor') | |
run.bold = True | |
# except you don't have a reference to `run` afterward |
它不是必须提供的文字给.add_paragraph()方法。
这可以使你的代码更简单,如果你从建立段从运行反正:
paragraph = document.add_paragraph() | |
paragraph.add_run('Lorem ipsum ') | |
paragraph.add_run('dolor').bold = True | |
paragraph.add_run(' sit amet.') |
应用字符样式
除了段落样式,其中指定一组段落级别设置,Word有字符样式其指定一组运行级别设置。一般来说,您可以将字符样式视为指定字体,包括其字体,大小,颜色,粗体,斜体等。
像段落样式,字符样式必须已经与你在打开的文档中定义的Document()调用(参见 了解样式)。
添加新运行时可以指定字符样式:
paragraph = document.add_paragraph('Normal text, ') | |
paragraph.add_run('text with emphasis.', 'Emphasis') |
您还可以在运行创建后将样式应用于运行。
此代码产生的结果与上面的行相同:
paragraph = document.add_paragraph('Normal text, ') | |
run = paragraph.add_run('text with emphasis.') | |
run.style = 'Emphasis' |
与段落样式一样,通过删除名称中出现在Word UI中的空格形成样式ID。所以风格’微妙强调’将被指定为’SubtleEmphasis’。请注意,如果您使用的是本地化版本的Word,则样式ID可能来自英语样式名称,并且可能不对应于其在Word UI中的样式名称。
document.add_page_break()
指定路径并保存文件
document.save(filename)
实际案例
案例1
config.py
# -*- encoding: utf-8 -*- | |
# @File : config.py | |
# @Author : 安替 | |
# @Time : 2022/9/26 11:45 | |
# @Software : PyCharm | |
# Python版本:3.6.3 | |
list_files = ["./test1.docx", "./test2.docx"] | |
final_path = "./test3.docx" | |
# 插入位置 | |
insert_text = "aaaa" | |
#插入内容 | |
insert_content = ["", "", ""] | |
#主标题 | |
replace_text_title_dict = {"", ""} | |
#二级标题 | |
replace_text_second_dict = {} | |
# 三级标题 | |
replace_text_third_dict = {} | |
# 四级标题 | |
replace_text_forth_dict = {} |
main.py
# -*- encoding: utf-8 -*- | |
# @File : test.py | |
# @Software : PyCharm | |
# Python版本:3.6.3 | |
from config import * | |
from docx.oxml.ns import qn | |
from docx.shared import Pt | |
from docx import Document | |
from docx.shared import Inches | |
from docx.shared import RGBColor | |
from docxcompose.composer import Composer | |
from docx.enum.text import WD_ALIGN_PARAGRAPH | |
def combine_docx(): | |
""" | |
Returns | |
------- | |
合并多个docx文档 | |
""" | |
new_document = Document() | |
composer = Composer(new_document) | |
for fn in list_files: | |
composer.append(Document(fn)) | |
composer.save(final_path) | |
print("docx合并完成") | |
def delete_paragraph(paragraph): | |
""" | |
Parameters | |
---------- | |
paragraph : 段落 | |
Returns | |
------- | |
删除指定段落 | |
""" | |
p = paragraph._element | |
p.getparent().remove(p) | |
paragraph._p = paragraph._element = None | |
def delete_docx_prefix_description(line, new_line, level, fontsize, alignment, isDelete = True): | |
docx = Document(final_path) | |
for p in docx.paragraphs: | |
if line in p.text: | |
ss = p.insert_paragraph_before(new_line) | |
ss.alignment = alignment | |
ss.style = docx.styles[level] | |
for run in ss.runs: | |
run.font.size = Pt(fontsize) | |
run.font.name = 'Times New Roman' # 控制是西文时的字体 | |
run.element.rPr.rFonts.set(qn('w:eastAsia'), '宋体') # 控制是中文时的字体 | |
run.font.color.rgb = RGBColor(100, 149, 237) | |
run.first_line_indent = Inches(0.0) | |
run.italic = False | |
run.bold = False | |
if(isDelete): | |
delete_paragraph(p) | |
docx.styles['Normal'].font.name = 'Times New Roman' | |
docx.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体') | |
docx.save(final_path) | |
def add_content(): | |
""" | |
Returns | |
------- | |
在指定位置添加段落 | |
""" | |
for i in range(len(insert_content)): | |
if i != 2: | |
delete_docx_prefix_description(insert_text, insert_content[i], "Heading 1", 14, WD_ALIGN_PARAGRAPH.LEFT, False) | |
else: | |
delete_docx_prefix_description(insert_text, insert_content[i], "Heading 2", 13, WD_ALIGN_PARAGRAPH.LEFT, False) | |
def modify_styles(): | |
""" | |
Returns | |
------- | |
修改段落字体等样式 | |
""" | |
for key ,value in replace_text_title_dict.items(): | |
delete_docx_prefix_description(key, value, "Heading 1", 26, WD_ALIGN_PARAGRAPH.CENTER) | |
for key ,value in replace_text_second_dict.items(): | |
delete_docx_prefix_description(key, value, "Heading 2", 13, WD_ALIGN_PARAGRAPH.LEFT) | |
for key ,value in replace_text_third_dict.items(): | |
delete_docx_prefix_description(key, value, "Heading 3", 11, WD_ALIGN_PARAGRAPH.LEFT) | |
for key ,value in replace_text_forth_dict.items(): | |
delete_docx_prefix_description(key, value, "Heading 4", 11, WD_ALIGN_PARAGRAPH.LEFT) | |
def main(): | |
combine_docx() | |
add_content() | |
modify_styles() | |
if __name__ == '__main__': | |
main() |
案例2
from docx import Document | |
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT | |
from docx.oxml.ns import qn | |
from docx.shared import Pt, RGBColor | |
document = Document() | |
# 设置正文字型 英文字型:Times New Roman; 中文字型:宋体 | |
document.styles['Normal'].font.name = 'Times New Roman' | |
document.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体') | |
# 设置正文字体大小 | |
document.styles['Normal'].font.size = Pt(12) | |
# 设置正文字体颜色 | |
document.styles['Normal'].font.color.rgb = RGBColor(0, 0, 0) | |
"""标题比较特殊需要单独设置""" | |
P = document.add_paragraph('') | |
run = P.add_run("静夜思") | |
run.font.color.rgb = RGBColor(255, 0, 0) | |
run.font.size = Pt(14) | |
run.bold = True | |
P.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER | |
# 添加段落 | |
p_1 = document.add_paragraph('床前明月光\n疑是地上霜\n举头望明月\n低头思故乡') | |
# 段落居中对齐 | |
p_1.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER | |
filename = '静夜思' | |
document.save('D:\桌面\{}.docx'.format(filename)) |
附表1——字号磅值对应表
附表2——常用颜色RGB值对照表
附表3——Word内置字符样式中英文对照表