6

I'd like to open an existing word document where I already added page numbers and just add some text and headline to it.

Here's a basic example of how I tried to accomplish my goal

#!/usr/bin/env python 
from docx import Document
document = Document('report-template.docx')
document.add_heading('Headline No. 1', level=1)
document.add_paragraph('Test No. 1')
document.add_heading('Heading No. 2', level=2)
document.add_paragraph('Test No. 2')
document.save('example.docx')

When I do the above mentioned with a complete fresh document everything works fine - when doing this with the already existing file it fails with the following error

Traceback (most recent call last):
  File "create-report-test.py", line 6, in <module>
    document.add_heading('Headline No. 1', level=1)
  File "/usr/lib/python2.7/site-packages/docx/document.py", line 43, in add_heading
    return self.add_paragraph(text, style)
  File "/usr/lib/python2.7/site-packages/docx/document.py", line 63, in add_paragraph
    return self._body.add_paragraph(text, style)
  File "/usr/lib/python2.7/site-packages/docx/blkcntnr.py", line 38, in add_paragraph
    paragraph.style = style
  File "/usr/lib/python2.7/site-packages/docx/text/paragraph.py", line 111, in style
    style_or_name, WD_STYLE_TYPE.PARAGRAPH
  File "/usr/lib/python2.7/site-packages/docx/parts/document.py", line 75, in get_style_id
    return self.styles.get_style_id(style_or_name, style_type)
  File "/usr/lib/python2.7/site-packages/docx/styles/styles.py", line 113, in get_style_id
    return self._get_style_id_from_name(style_or_name, style_type)
  File "/usr/lib/python2.7/site-packages/docx/styles/styles.py", line 143, in _get_style_id_from_name
    return self._get_style_id_from_style(self[style_name], style_type)
  File "/usr/lib/python2.7/site-packages/docx/styles/styles.py", line 57, in __getitem__
    raise KeyError("no style with name '%s'" % key)
KeyError: u"no style with name 'Heading 1'"

I read the documention under http://python-docx.readthedocs.org/en/latest/user/documents.html but it seems I'm missing something - anyone got an idea?

Thanks in advance

mat1010
  • 756
  • 1
  • 9
  • 17

2 Answers2

5

python-docx can only work with styles that are already defined in the document. This error indicates that the Heading 1 paragraph style is not defined. Word starts out with no styles defined (ok, a couple like Normal, but that's all), then it adds built-in styles to the file the first time they're used.

Two options:

  1. Add a Heading 1 paragraph to the document by hand and then delete it. After that, the Heading 1 paragraph style will be defined in the document. Once Word adds a style it doesn't remove it, even if all paragraphs using that style are deleted.

  2. Use python-docx to define Heading 1 yourself. See the documentation here on how to do that: http://python-docx.readthedocs.org/en/latest/user/styles-using.html#define-paragraph-formatting

This page is probably also worth a quick read to fill in some style concepts: http://python-docx.readthedocs.org/en/latest/user/styles-understanding.html

scanny
  • 26,423
  • 5
  • 54
  • 80
  • Great - this is exactly the issue. Now it's working when I'm defining all the styles manually. But is it possibly to load those style with the default properties? That's what I did, but the styles are just "plain" paragraphs: `styles = document.styles` `styles.add_style('Heading 1', WD_STYLE_TYPE.PARAGRAPH, builtin=True)` My hope was that the `builtin` flag will fix this. – mat1010 Jun 24 '15 at 08:09
  • No. There's no "built-in" defaults for the built-in styles. You would have to work out what properties each of them needs and apply them yourself. You can use opc-diag to browse the styles.xml part in a .docx package where they're defined to see what settings are needed. The built-in styles vary based on default themes, Word versions, and so forth, so there's not one universal set. The headings are pretty simple though; maybe three or four settings each, like font size, space before, and based-on. I would try that unless you can determine the starting document. – scanny Jun 24 '15 at 08:25
  • Thank you very much for your help. I will work on figuring out the properties of those default styles and apply them by myself. – mat1010 Jun 24 '15 at 08:38
  • @scanny I tried adding the styles manually as suggested by you, but it still gives me the same error. I am not using word, I am using LibreOffice Writer could this be an issue?? – Arnab Jan 31 '18 at 13:23
  • @StarLord If you ask this as a separate question and include all the details of your specific case I'll take a look. If you mark it with the 'python-docx' tag I'll see it. – scanny Jan 31 '18 at 20:57
  • Sorry for waking up this topic, but for me, only the _Option 1_ is working (but this is the most dirty solution I've ever seen). _Option 2_ doesn't work (with tables at least since I'm trying to apply "Table Grid" style on a table), and yes I've read the linked pages, followed the instructions, but nothings works. `add_style()` adds just an entry in the style list but this style is never taken into account when being assigned to my table style. – Fareanor Sep 03 '20 at 13:13
0

Remove level = 1 and level = 2

It should be given as:

document.add_heading('Headline No. 1', 1)

document.add_heading('Heading No. 2', 2)

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – user11717481 Feb 22 '22 at 14:50