elapouya / python-docx-template

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

can not insert a inline image and a subdoc with an image #474

Open MWMWM opened 1 year ago

MWMWM commented 1 year ago

Describe the bug

I have a template that is supposed to render an inline image and a sub template containing an image but it fails (rendering only with a sub template or an inline image works great, rendering an inline image and a sub template NOT containing an image is also working)

To Reproduce

index

template1.docx template2.docx

from docxtpl import DocxTemplate, InlineImage

doc = DocxTemplate("template2.docx")
subdoc = doc.new_subdoc('template1.docx')
photo = InlineImage(doc, image_descriptor='index.jpeg')
doc.render({"template": subdoc, "photo": photo}, autoescape=True)

Current behavior

The following error happens

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "xxx/site-packages/docxtpl/template.py", line 343, in render
    xml_src = self.build_xml(context, jinja_env)
  File "xxx/site-packages/docxtpl/template.py", line 290, in build_xml
    xml = self.render_xml_part(xml, self.docx._part, context, jinja_env)
  File "xxx/site-packages/docxtpl/template.py", line 239, in render_xml_part
    dst_xml = template.render(context)
  File "xxx/site-packages/jinja2/environment.py", line 1301, in render
    self.environment.handle_exception()
  File "/xxx/site-packages/jinja2/environment.py", line 936, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "<template>", line 4, in top-level template code
  File "xxx/site-packages/docxtpl/inline_image.py", line 39, in __html__
    return self._insert_image()
  File "xxx/site-packages/docxtpl/inline_image.py", line 24, in _insert_image
    pic = self.tpl.current_rendering_part.new_pic_inline(
  File "xxx/site-packages/docx/parts/story.py", line 57, in new_pic_inline
    cx, cy = image.scaled_dimensions(width, height)
AttributeError: 'ImageWrapper' object has no attribute 'scaled_dimensions'

Expected behavior

Template is rendered

sanjass commented 1 year ago

I'm having the same issue. Based on some investigation the bug seems to happen only for some images and is coming from the python-docx package. For example, I don't get the bug if I use this image from the python-docx test images

What fixed it in my case is opening and saving the image with PIL:

from PIL import Image
f = Image.open('sample_image.jpeg')
f.save('new_sample_image.jpeg')    
f.close()
myimage = InlineImage(tpl, image_descriptor="new_sample_image.jpeg", width=Mm(100), height=Mm(100))
context["myimage"] = myimage

this might not work in all cases, so I'm still hoping there's a better fix here

MWMWM commented 1 year ago

@sanjass so maybe it's a different case - image from this image from the python-docx test images is not working in my case (the same image has to be present in template and added as an InlineImage)

theodore86 commented 2 months ago

did anyone noticed that the Inline image class is changing the docx template format? Seems like that the final format is letter rather than e.g A4