更改python-docx中的段落格式

时间:2018-01-08 12:22:25

标签: python python-docx

我正在尝试使用Python的python-docx模块更改多个段落的格式。

from docx import Document
from docx.shared import Pt
from docx.shared import Inches
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.enum.section import WD_ORIENTATION
from content import report_content, provinces, report_date, introduction, intro_content

alignment_dict = {'justify': WD_PARAGRAPH_ALIGNMENT.JUSTIFY,
                  'center': WD_PARAGRAPH_ALIGNMENT.CENTER,
                  'centre': WD_PARAGRAPH_ALIGNMENT.CENTER,
                  'right': WD_PARAGRAPH_ALIGNMENT.RIGHT,
                  'left': WD_PARAGRAPH_ALIGNMENT.LEFT}

orientation_dict = {'portrait': WD_ORIENTATION.PORTRAIT,
                    'landscape': WD_ORIENTATION.LANDSCAPE}

document = Document()


def change_orientation(orientation='portrait', set_left_margin=1.0, set_right_margin=1.0):
    section = document.sections[-1]
    new_width, new_height = section.page_height, section.page_width
    section.orientation = orientation_dict[orientation]
    section.page_width = new_width
    section.page_height = new_height
    section.left_margin = Inches(set_left_margin)
    section.right_margin = Inches(set_right_margin)


def add_logo(path, align):
    document.add_picture(path, width=Inches(4.5), height=Inches(1.5))
    last_paragraph = document.paragraphs[-1]
    last_paragraph.alignment = alignment_dict[align]


def add_content(content, space_after, font_name='Arial', font_size=11, line_spacing=0, space_before=0,
                align='justify', keep_together=True, keep_with_next=False, page_break_before=False,
                widow_control=False, set_bold=False, set_italic=False, set_underline=False, set_all_caps=False):
    paragraph = document.add_paragraph(content)
    style = document.styles['Normal']
    font = style.font
    font.name = font_name
    font.size = Pt(font_size)
    font.bold = set_bold
    font.italic = set_italic
    font.all_caps = set_all_caps
    font.underline = set_underline
    paragraph_format = paragraph.paragraph_format
    paragraph_format.alignment = alignment_dict.get(align.lower())
    paragraph_format.space_before = Pt(space_before)
    paragraph_format.space_after = Pt(space_after)
    paragraph_format.line_spacing = line_spacing
    paragraph_format.keep_together = keep_together
    paragraph_format.keep_with_next = keep_with_next
    paragraph_format.page_break_before = page_break_before
    paragraph_format.widow_control = widow_control


def create_numbered_list():
    pass


def add_subheading(subheading, level):
    document.add_heading(subheading, level)


change_orientation(orientation='landscape', set_left_margin=0.5, set_right_margin=0.5)
add_logo('logo.png', 'center')
add_content(report_content, align='Center', space_before=40, space_after=20, line_spacing=1, font_name='Arial',
            set_bold=True, set_all_caps=True)
add_content(provinces, align='Center', space_before=20, space_after=20, line_spacing=1, font_name='Arial',
            set_bold=True, set_all_caps=True)
add_content(report_date, align='Center', space_before=20, space_after=20, line_spacing=1, font_name='Arial',
            set_bold=True, set_all_caps=True)
document.add_page_break()

add_subheading(introduction, level=1)

add_content(intro_content, space_after=20, space_before=20)

document.save('demo.docx')

问题是每次我通过add_content方法向新的段落块添加格式时,旧块的格式会被更改为当前块的格式。

为什么我无法保留格式,为什么它会重置为最新块的格式?

2 个答案:

答案 0 :(得分:2)

试试这段代码。使用add_style添加新样式。 document.styles [' Normal']是一种系统风格 我测试好了

from docx.enum.style import WD_STYLE_TYPE
#.........................
def add_content(content, space_after, font_name='Arial', font_size=16, line_spacing=0, space_before=0,
                align='justify', keep_together=True, keep_with_next=False, page_break_before=False,
                widow_control=False, set_bold=False, set_italic=False, set_underline=False, set_all_caps=False,style_name=""):
    paragraph = document.add_paragraph(content)
    paragraph.style = document.styles.add_style(style_name, WD_STYLE_TYPE.PARAGRAPH)
    font = paragraph.style.font
    font.name = font_name
    font.size = Pt(font_size)
    font.bold = set_bold
    font.italic = set_italic
    font.all_caps = set_all_caps
    font.underline = set_underline
    paragraph_format = paragraph.paragraph_format
    paragraph_format.alignment = alignment_dict.get(align.lower())
    paragraph_format.space_before = Pt(space_before)
    paragraph_format.space_after = Pt(space_after)
    paragraph_format.line_spacing = line_spacing
    paragraph_format.keep_together = keep_together
    paragraph_format.keep_with_next = keep_with_next
    paragraph_format.page_break_before = page_break_before
    paragraph_format.widow_control = widow_control

add_content("1234", align='Center', space_before=40, space_after=20, line_spacing=1, font_name='Arial', font_size=16,
            set_bold=True, set_all_caps=True,style_name ="Normal1")
add_content("12345", align='Center', space_before=20, space_after=20, line_spacing=1, font_name='Arial',font_size=14,
            set_bold=True, set_all_caps=True,style_name ="Normal2")

答案 1 :(得分:1)

你的问题在这里:

style = document.styles['Normal']
font = style.font

样式适用于具有该样式的所有段落。这是一份全球性的文件。因此,您对style.font进行的任何更改都会影响具有该样式的所有段落(在这种情况下,这是您的所有段落)。

请务必阅读文档中的此页面以及随后的文档:
http://python-docx.readthedocs.io/en/latest/user/styles-understanding.html

字符格式(例如粗体,大小,字体)在运行级别发生(在段落下面,段落由运行组成)。因此,如果您想直接应用字符格式,而不是使用样式,则需要对每次运行执行此操作。

通过调用document.add_paragraph(content)向段落添加内容会将所有内容放在一次运行中。所以快速修复可能是:

font = paragraph.runs[0].font

可能值得一试。但是,花一点时间处理文档的概念部分以理解Word对象模型可能也是一个好主意。表面看起来很简单,这很复杂。这个页面是一个很好的起点:
http://python-docx.readthedocs.io/en/latest/user/text.html