2

I am trying to prepend a full page image, no margins, to an existing docx, using python-docx.

It is my understanding that the code should go something like this (using the solution suggested previously)

from docx import Document
from docx.shared import Inches

document = Document('existing.docx')
new_doc = Document()
new_section = new_doc.add_section()
new_section.left_margin = Inches(0.3)
new_doc.add_picture('frontpage.jpg', width=Inches(8.0))
for element in document.element.body:
     new_doc.element.body.append(element)
# for section in new_doc.sections[1:]:
#   section.left_margin = Inches(1.0)
new_doc.save('new.docx')

There are two problems with this:

  1. As-is, the script changes the left margin for the whole document. With the last two lines uncommented, the margin for the front page changes back to 1in.
  2. The new section created a the beginning of the script creates a blank page at the beginning of the document.

How do I do it correctly? Thx.

celaeno
  • 682
  • 1
  • 5
  • 13

1 Answers1

3

Calling .add_section() appends a new section to the end of the document, separated by a page break.

Use the existing section to set the properties of the first section, then add the second section and adjust its properties for what you want for the remainder of the document.

The existing single section in a new default document is available on document.sections[0].

from docx import Document
from docx.shared import Inches

target_document = Document()
target_document.sections[0].left_margin = Inches(0.3)
target_document.add_picture('frontpage.jpg', width=Inches(8.0))

new_section = target_document.add_section()
new_section.left_margin = Inches(1.0)

source_document = Document('existing.docx')
for paragraph in source_document.paragraphs:
     target_document.add_paragraph(paragraph.text)
new_doc.save('new.docx')
scanny
  • 26,423
  • 5
  • 54
  • 80
  • Thanks @scanny. I still cannot make it work, though. Or perhaps I don't understand what you are telling me. Coulld you modify the above snippet to something you think should work? – celaeno May 04 '20 at 13:59
  • I've added code that should work. Part of the problem is you're adding XML elements at the end of the body, _after_ the sentinel `` element. That would screw up the `sectPr` element's interpretation because it's expected to be at the end. I used `document.add_paragraph()` instead, which inserts the paragraph elements where they belong (in front of the `sectPr` element), but does not accommodate tables and does not preserve character formatting. You'll need to dig deeper into the XML aspects if you want to use internals like that. – scanny May 04 '20 at 19:02
  • OK, thank you very much, this works except that I am getting "AttributeError: 'Document' object has no attribute 'paragraph'" in the iteration over paragraphs. But if I use elements as in the original code it gives me pretty much what I was trying to achieve. Thanks. – celaeno May 04 '20 at 19:11
  • Apologies, line 12 should be `for paragraph in source_document.paragraphs:`, I fixed the code example. – scanny May 05 '20 at 16:57