elapouya / python-docx-template

Use a docx as a jinja2 template
GNU Lesser General Public License v2.1
2.01k stars 392 forks source link

Subdoc with InlineImage no longer works #374

Open sknutsonsf opened 3 years ago

sknutsonsf commented 3 years ago

Describe the bug

It is no longer possible to create multiple subdoc with each having a separate image, where the subdocuments are from a detail template.

This used to work with docxtpl==0.6.3 and python-docx==0.8.7 and python 3.6 But now fails with docxtpl==0.11.5 and python-docx==0.8.11 and python 3.9

Documentation It is not clear if the InlineImage intended for the subdocument should be part of the Outer document, or rendered in the per-page subdocument. It does not work either way.

If the Inline image is part of the subdocument, then it does not show up in the report (see attached "BAD-multipage-report.dox").

The old version wanted the InlineImage attached to the OUTER document, but that now results in the exception shown below:

/opt/agmonitor/lib/python3.9/site-packages/docxtpl/__init__.py in _insert_image(self)
    835
    836     def _insert_image(self):
--> 837         pic = self.tpl.current_rendering_part.new_pic_inline(
    838             self.image_descriptor,
    839             self.width,

AttributeError: 'NoneType' object has no attribute 'new_pic_inline'

To Reproduce

I've attached the relevant file and templates. THey should be put into the "tests" directory of the repo to run them. BAD-multipage_report.docx

Expected behavior

There should be a documented way to create multipage reports with separate image on each page. The attached python file and templates provides a starting point for that documentation.

The code that worked with older version should still work or a clear subdoc_multipage_images.zip way provide.

Screenshots

See attached "BAD-mutlipage-report.docx"

Additional context

I've created a branch in https://github.com/sknutsonsf/python-docx-template with this test case added.

sknutsonsf commented 3 years ago

The bug appears to be related to Python 3.9 in some way. It still occurs with the older versions but in the python 3.9 environment.

The requirement is for a "summary" page followed by detailed pages.
We used to be do it all with docxtpl.

The branch https://github.com/sknutsonsf/python-docx-template/tree/issue_374 shows the workaround in tests/multipage_report_docxcompose.py. It uses docxtpl to create 3 documents then merge them. It would be better if the subdoc_multipage_images.py case worked.

I added the result of the workaround which is the "expected" result and the "failed" result from using multiple subdocs.

The failed report stopped after the first page included, and the image was not included. There should have been two detail pages, as shown in the workaround result.

multipage_report_failed.docx multipage_report_workaround.docx

elapouya commented 3 years ago

The actual implementation of subdoc in docxtpl is very limited : it's original goal was only to create empty python-docx object and attach to the template object, thus subdoc inheritate the _part from the template. All style, images, footer, header will be those created AFTER the subdoc object has been created and initialized. This means that if you specify a docx file at subdoc creation, the images, styles, header, footer should be lost : Only body text is kept. There is actually no merge done on _part between template object and subdoc objects with docx file specified at creation time. If you look at my tests/subdoc.py there is no docx file specified in tpl.new_subdoc() : that was the planed usage. The possibility to specify a docx file was more a bonus than a functional feature. As many people think docxtpl.Subdoc is a way to merge many documents, I may have to develop that more seriously or at least modify the documentation to explain this is not the case actually.