Issue #197 - Add support for file-like objects for replace_media

This commit is contained in:
ericdufresne 2019-05-22 15:15:19 -04:00
parent 8472d4ed55
commit cd77712b5e
2 changed files with 42 additions and 8 deletions

View File

@ -370,10 +370,14 @@ class DocxTemplate(object):
return Subdoc(self,docpath) return Subdoc(self,docpath)
@staticmethod @staticmethod
def get_file_crc(filename): def get_file_crc(file_obj):
with open(filename, 'rb') as fh: if hasattr(file_obj, 'read'):
buf = fh.read() buf = file_obj.read()
crc = (binascii.crc32(buf) & 0xFFFFFFFF) else:
with open(file_obj, 'rb') as fh:
buf = fh.read()
crc = (binascii.crc32(buf) & 0xFFFFFFFF)
return crc return crc
def replace_media(self,src_file,dst_file): def replace_media(self,src_file,dst_file):
@ -382,17 +386,24 @@ class DocxTemplate(object):
This has been done mainly because it is not possible to add images in This has been done mainly because it is not possible to add images in
docx header/footer. docx header/footer.
With this function, put a dummy picture in your header/footer, With this function, put a dummy picture in your header/footer,
then specify it with its replacement in this function then specify it with its replacement in this function using the file path
or file-like objects.
Syntax: tpl.replace_media('dummy_media_to_replace.png','media_to_paste.jpg') Syntax: tpl.replace_media('dummy_media_to_replace.png','media_to_paste.jpg')
-- or --
tpl.replace-media(io.BytesIO(image_stream), io.BytesIO(new_image_stream))
Note: for images, the aspect ratio will be the same as the replaced image Note: for images, the aspect ratio will be the same as the replaced image
Note2 : it is important to have the source media file as it is required Note2 : it is important to have the source media file as it is required
to calculate its CRC to find them in the docx to calculate its CRC to find them in the docx
""" """
with open(dst_file, 'rb') as fh:
crc = self.get_file_crc(src_file) crc = self.get_file_crc(src_file)
self.crc_to_new_media[crc] = fh.read() if hasattr(dst_file, 'read'):
self.crc_to_new_media[crc] = dst_file.read()
else:
with open(dst_file, 'rb') as fh:
self.crc_to_new_media[crc] = fh.read()
def replace_pic(self,embedded_file,dst_file): def replace_pic(self,embedded_file,dst_file):
"""Replace embedded picture with original-name given by embedded_file. """Replace embedded picture with original-name given by embedded_file.

View File

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
'''
Created : 2019-05-22
@author: Eric Dufresne
'''
from docxtpl import DocxTemplate
import io
DEST_FILE = 'output/header_footer_image_file_obj.docx'
tpl=DocxTemplate('templates/header_footer_image_tpl.docx')
context = {
'mycompany' : 'The World Wide company',
}
dummy_pic = io.BytesIO(open('templates/dummy_pic_for_header.png', 'rb').read())
new_image = io.BytesIO(open('templates/python.png', 'rb').read())
tpl.replace_media(dummy_pic, new_image)
tpl.render(context)
tpl.save(DEST_FILE)