python-docx-template
python-docx-template copied to clipboard
inline image support for bytes from file or network
Is your feature request related to a problem? Please describe.
I want to render a docx which contains some images from network, I find it is difficult to do it.
I have to download and save as a temp file, use the current InlineImage and then I have to remember to remove it.
Why not directly support image contents as input?
Describe the solution you'd like
Support the image contents when using InlineImage.
Describe alternatives you've considered
n.a.
Additional context
n.a.
I noticed that python-docx
is used, and it seems it only support file path instead of file contents.
https://github.com/elapouya/python-docx-template/blob/5d9bba118ac3c0c0f3af3242884945e526a5d4c9/docxtpl/inline_image.py#L23-L30
https://github.com/python-openxml/python-docx/blob/36cac78de080d412e9e50d56c2784e33655cad59/docx/parts/story.py#L50
Maybe we could save the image contents in a file, generate docx and do some cleanup internal.
I found the upstream project python-docx support stream
of image.
See:
- https://python-docx.readthedocs.io/en/latest/user/quickstart.html#adding-a-picture
- https://github.com/python-openxml/python-docx/blob/36cac78de080d412e9e50d56c2784e33655cad59/docx/document.py#L58-L72
- https://github.com/python-openxml/python-docx/blob/36cac78de080d412e9e50d56c2784e33655cad59/tests/image/test_image.py#L43-L66
I hope this feature to be added too👏
Hello, Its possible to pass an io.BytesIO(bytes) to the InlineImage() function. Perhaps there needs to be a new example leveraging this method: @cw0516 @liudonghua123
fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16]) #plotly Image example
img_bytes = fig.to_image(format="png",width=600, height=350) # plotly image generate bytes
main_visualization = io.BytesIO(img_bytes) # convert bytes to File obj
context = { 'main_visualization': docxtpl.InlineImage(doc, main_visualization) } # python-docx-template will believe this is a File and run seek on it.
Hello, Its possible to pass an io.BytesIO(bytes) to the InlineImage() function. Perhaps there needs to be a new example leveraging this method: @cw0516 @liudonghua123
fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16]) #plotly Image example img_bytes = fig.to_image(format="png",width=600, height=350) # plotly image generate bytes main_visualization = io.BytesIO(img_bytes) # convert bytes to File obj context = { 'main_visualization': docxtpl.InlineImage(doc, main_visualization) } # python-docx-template will believe this is a File and run seek on it.
Yeah, I found new_pic_inline
in upstream project docx
support IO[bytes]
, see https://github.com/python-openxml/python-docx/blob/57d3b9ee9cb778e76258653c6dc464d5598ca80b/src/docx/parts/story.py#L60-L65.
And I tested, it worked as expected!
import io
from docxtpl import DocxTemplate, InlineImage
from docx.shared import Mm
doc = DocxTemplate("test.docx")
context = { 'company_name' : "World company", 'inline_image': InlineImage(doc, io.BytesIO(open('test.png', 'rb').read()), width=Mm(10), height=Mm(10))}
doc.render(context)
doc.save("generated_doc.docx")
I can also use file like object as the second argument of InlineImage.