Python docx书写的通用设置

本文档详细介绍了如何使用Python的docx库创建和格式化Word文档,包括Document的创建、保存及格式设置,Paragraph的基本操作如字体、对齐、插入图片等,并探讨了换行符与回车符在不同平台的识别问题,提供了解决方案。
摘要由CSDN通过智能技术生成


前言

在之前完成的一个项目中,有一个模块需要用到Python的docx库来自动生成对应格式的word文档,但是实际操作发现docx的格式调整花费不少时间,在此总结和分享个人的使用心得


一、依赖库

from docx import Document
from docx.shared import Pt, Cm, Mm
from docx.oxml.ns import qn
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT

二、Document

(1)创建document

#书写word的第一层,创建一个空白的文档
document = Document()   

(2)保存document

document.save(savepath)

一个建议:
要生成一个新的文档时,都需要一个空白的模板文档。如果第一次创建文档,并在上面修改,保存的时候也只会保存自身,这样在创建第二个文档的时候又要创建一个空白文档,比较麻烦。因此个人会预先指定一个空白文档给后面的文件做模板,具体代码如下:

demo_path = os.path.join(abspath, 'demo.docx')
if not os.path.exists(demo_path):
    document = Document()
    # document.add_paragraph(' ')# 如果报错试试先写入内容
    document.save(demo_path)
doc = Document(demo_path)

这样当我们保存doc在别的地方时,不会影响到模板文件的内容。

(3)document的格式设置

documnet层对应word文档的全局设置,一经设置,整篇生效
下面是一些 通用的设置(doc对应Document类)

# 在doc开头调用进行设置
def docxinitial(doc):
    # 设置正文字体类型、大小
    doc.styles["Normal"].font.name = u'宋体'
    doc.styles["Normal"].font.size = Pt(12)
    doc.styles["Normal"]._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
    # 设置页眉
    header = doc.sections[0].header
    pheader = header.paragraphs[0]  # 获取页眉的第一个段落
    ph = pheader.add_run('权利要求书')
    ph.font.name = u'黑体'  # 设置页眉字体样式
    ph._element.rPr.rFonts.set(qn('w:eastAsia'), u'黑体')
    ph.font.size = Pt(16)  # 设置页眉字体大小
    ph.bold = True  # 页眉字体加粗
    pheader.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER  # 页眉对齐方式设为居中

# 在doc结尾处调用进行设置
# 通过sections(节)进行设置时,节对应文档中的每一页
# 每个节在没输入内容之前是不存在的,因此在最后才对每个节逐一进行设置
def setsectionformat(doc):
    for sec in doc.sections:
        # 设置页面边距(左上25毫米,右下15毫米)
        sec.top_margin = Cm(2.5)
        sec.left_margin = Cm(2.5)
        sec.right_margin = Cm(1.5)
        sec.bottom_margin = Cm(1.5)
        # 设置纸张大小(A4)
        sec.page_height = Mm(297)
        sec.page_width = Mm(210)
        # 设置页眉页脚距离
        sec.header_distance = Cm(1.5)
        sec.footer_distance = Cm(0.2)

# 例如:
doc = Document(demo_path)
docxinitial(doc)
doc.add_run('需要填充的内容')
setsectionformat(doc)

三、Paragraph

paragraph(以下简称para)是往文档中写入内容的基础,每一个para对应section中的段落

(1)para的基本设置:

# 往doc中添加段落
para = doc.add_paragraph()
# 设置行前后间距,行间距(前后间距和行间距效果不相同,具体自行测试)
para.paragraph_format.space_before = Pt(0)
para.paragraph_format.space_after = Pt(0)
para.paragraph_format.line_spacing = Pt(24)
# 设置首行缩进
para.first_line_indent = para.style.font.size * 2

(2)单独设置para的格式

前面我们设置document的时候,对整篇文档的字体类型、大小进行了设置,那么我们创建的para也会依照这个设置。如果我们对其中一些para有别的要求,比如标题,就需要另设一个para进行单独的设置。如下:

# 写标题
title = '这里是要居中、改变大小、加粗的标题'
ti = doc.add_paragraph()
ti.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
ti1 = ti.add_run(title)
ti1.font.size = Pt(16)  # 添加页面内容
ti1.bold = True

(3)add_run()

paragraph的add_run()是往段落中添加内容

para.add_run(u'本行的内容')

若想要改变写入内容的格式也可加上:

para.add_run(u'本行的内容').bold = True
# 或者:
run = para.add_run(u'本行的内容')
run.font.bold = True  # 把字体改为粗体
run.font.italic = True  # 把字体改为斜体
run.font.underline = True  # 下划线
run.font.strike = True  # 删除线
run.font.shadow = True  # 阴影

add_run()会将里面的内容原封不动写入。这代表,在一个para中,每一次add_run()不会自动换行,因此我们需要手动添加换行符

para.add_run(u'本行的内容\n')

但还有一种情况,就是要写入的内容中本身包含多段,如果我们在前面的doc设置中设置了首行缩进或在add_run()中手动缩进,写入的内容也只会在开头缩进,对后面的段落不会有缩进,这时需要我们对内容进行处理:

# 通过换行符检测有几段,再切开手动缩进
def checkchangeline(con, para):
    linenum = con.count('\n')
    lines = []
    if linenum > 0:
        lines = con.split('\n')
    if len(lines) > 1:
        for i, line in enumerate(lines):
            para.add_run('    ' + line + '\n')
    else:
        para.add_run('    ' + con + '\n')

(4)插入图片add_picture()

doc.add_picture(path)用于在段落中插入图片,path为图片的路径。
需要注意的是,直接插入的图片是按照默认设置摆放的
如果需要设置图片居中可以这样操作:

doc.add_picture(pngpath)
last_paragraph = doc.paragraphs[-1]  # 这里的paragraphs为单独创建,用于放图片
last_paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

为图片添加图片序号

para = doc.add_paragraph()
para.add_run('                                      图1').bold = True

(5)换行符与回车符

当我们想把生成的文档导入一些平台时,会发现自动生成换行的文档中的换行全部失效了,导入系统的文本变成了一大串文本拼接在一起。但是手动输入换行的文档却能正确识别换行。出现这种问题原因是:
这些平台会自动将文档中的换行符给去掉,但是对于回车符却能正确识别
也就是我们自动生成的文档用于换行的全是换行符\n,但是系统能正确识别的是回车符**\r\r\n**

1、如何知道一个docx中的换行用的是换行符还是回车符?

我们打开一个docx文档:
在这里插入图片描述
选择“开始”的红圈位置,会出现“开始/隐藏段落标记”,将它√上就可以在正文处看见各种段落的隐藏符号。
如果每一段的换行处为一个向左拐的箭头,说明是回车符,也就是正常手动编辑word时回车键得到的,在word中可以用^P表示
如果为一个向下的箭头,说明是换行符,在word中可以用^I表示

2、如果是换行符的问题,那么我们在add_run()中直接将\n换成\r或者\r\n不就可以了吗?

很遗憾,在Python-docx 0.8.11的add_run()的说明中有这么一段。
在这里插入图片描述
也就是说,不管你用:
add_run(‘\r’)
add_run(‘\n\r’)
还是:
add_run().add_break()
对文本进行换行,最终在生成的docx中全都会变为换行符

3、一个解决办法为:

利用add_paragraph(),在每一个换行处,不用add_run()中加换行符/回车符来换行,而是直接新起一个para,这样既能达到换行效果,文本换行处用的也是回车符

para = doc.add_paragraph()
para.add_run(text1)
para = doc.add_paragraph()
para.add_run(text2)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值