Как изменить размер и размер шрифта заголовка в python -docx? - PullRequest
1 голос
/ 30 марта 2020

Я подал это как python -docx: https://github.com/python-openxml/python-docx/issues/805, но мне было предложено открыть обсуждение здесь.

https://python-docx.readthedocs.io/en/latest/user/styles-using.html подразумевает, что Я должен быть в состоянии изменить стили шрифта заголовка следующим образом:

font = doc.styles['Heading 1'].font
font.name = 'Times New Roman'
font.size = docx.shared.Pt(16)

Но это не сработает: полученный документ использует Calibri для всех заголовков. (Они также синего цвета, а в заголовке 1 есть подчеркивание, которое мне также необходимо как-то исключить.)

Также не работает ни изменение шрифта в указанном заголовке c, ни удаление latent_styles для заголовков.

Вот тестовая программа, которая пробует все три метода, но заголовки 1 и 2 по-прежнему выглядят как синие калибры, несмотря на все попытки изменить их на Times New Roman:

import docx

doc = docx.Document()

# Deleting heading latent styles seems to do nothing:
latent_styles = doc.styles.latent_styles
latent_styles['Heading 1'].delete()
latent_styles['Heading 2'].delete()

# Setting the Normal font works:
font = doc.styles['Normal'].font
font.name = 'Times New Roman'
font.size = docx.shared.Pt(12)

# Setting heading styles doesn't do anything:
# they all still end up as blue Calibri.
font = doc.styles['Heading 1'].font
font.name = 'Times New Roman'
font.size = docx.shared.Pt(16)

font = doc.styles['Heading 2'].font
font.name = 'Times New Roman'
font.size = docx.shared.Pt(14)

doc.add_heading("Heading 0", 0)
doc.add_paragraph('Here is a paragraph of text.')
doc.add_heading("Heading 1", 1)
doc.add_paragraph('Here is a paragraph of text.')
doc.add_heading("Heading 2", 2)
doc.add_paragraph('Here is a paragraph of text.')

# It also doesn't work to change the style of a specific heading:
heading = doc.add_heading("Another Heading 1", 1)
heading.style.font.name = "Times New Roman"
doc.add_paragraph('Here is a paragraph of text.')

doc.save('test.docx')

Невозможно изменить имя шрифта "заголовок 1", используя docx , упоминает об этом как об ошибке и предлагает создать новый стиль в качестве обходного пути. Более простой обходной путь - создать прогоны внутри обычного текста абзаца, а затем стилизовать эти прогоны. Но кажется, что было бы лучше использовать стандартные элементы, такие как «Заголовок 1», если бы можно было стилизовать эти заголовки как что-то отличное от синего Calibri ... и документация предполагает, что это возможно.

1 Ответ

0 голосов
/ 30 марта 2020

Как вы заметили, обычно изменение шрифта (font.name) для стиля "просто работает". По причинам, которые я не до конца понимаю, Title и, возможно, Heading 1, Heading 2 и т. Д. 1043 *. стили являются исключением. Я ожидаю, что это связано с тем, что их выбор шрифта определяется темой. Возможно, это связано с их особой ролью в формировании оглавления.

Для начала пара замечаний:

  • Стиль, применяемый document.add_heading("0th-level Heading", 0): Title. Полагаю, в этом есть какой-то смысл, поскольку заголовок самого высокого уровня дает право на весь документ. Стили Heading 1, Heading 2, et c. применяются, когда 1 и 2 используются в вызове этой функции соответственно.

  • Если мы применяем имя шрифта "Times New Roman" к стилю Title и затем, сгенерировав XML, мы видим следующее:

>>> heading = document.add_heading("Title", 0)
>>> title_style = heading.style
>>> title_style.font.name = "Times New Roman"
>>> title_style.element.xml
<w:style xmlns:w=... w:type="paragraph" w:styleId="Title">
  <w:name w:val="Title"/>
  <w:basedOn w:val="Normal"/>
  <w:next w:val="Normal"/>
  <w:link w:val="TitleChar"/>
  <w:uiPriority w:val="10"/>
  <w:qFormat/>
  <w:rsid w:val="00FC693F"/>
  <w:pPr>
    <w:pBdr>
      <w:bottom w:val="single" w:sz="8" w:space="4" w:color="4F81BD" w:themeColor="accent1"/>
    </w:pBdr>
    <w:spacing w:after="300" w:line="240" w:lineRule="auto"/>
    <w:contextualSpacing/>
  </w:pPr>
  <w:rPr>
    <w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia"
              w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi"
              w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
    <w:color w:val="17365D" w:themeColor="text2" w:themeShade="BF"/>
    <w:spacing w:val="5"/>
    <w:kern w:val="28"/>
    <w:sz w:val="52"/>
    <w:szCs w:val="52"/>
  </w:rPr>
</w:style>
  • Из этого мы можем многое увидеть, если интересные предметы, но наше внимание на данный момент может быть ограничено к элементу <w:rFonts>:
>>> title_style.element.rPr.rFonts.xml
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia"
          w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi"
          w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>

Мы можем видеть, что «Times New Roman» действительно применен к двум настройкам шрифта, но название все равно появляется в Calibri, который как бы происходит то, на что "majorHAnsi" отображается.

Чтобы перейти к решению, если мы установим для шрифта w:asciiTheme значение "Times New Roman", заголовок будет выглядеть так:

from docx.oxml.ns import qn

rFonts = title_style.element.rPr.rFonts
rFonts.set(qn("w:asciiTheme"), "Times New Roman")

Я ожидаю, что такая же процедура будет работать с другими стилями заголовков.

Обратите внимание, что если вы генерируете документ «с нуля», а не редактируете существующий, может быть легче начать с пустой документ, который уже имеет нужные вам стили:

* 104 2 *
...