diff --git a/CHANGES.rst b/CHANGES.rst index 14b4d3a..a4e09e5 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,7 @@ +0.4.2 (2017-10-05) +------------------ +- Add replace_pic() method to replace pictures from its filename (Thanks to Riccardo Gusmeroli) + 0.4.1 (2017-09-10) ------------------ - Improve image attachment for InlineImage ojects diff --git a/docs/index.rst b/docs/index.rst index 734ca99..839dccf 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -165,12 +165,29 @@ in your python code :: in your docx template just use ``{{ mylisting }}`` With ``Listing()``, you will keep the current character styling (except after a ``\a`` as you start a new paragraph). -Replace docx medias -------------------- +Replace docx pictures +--------------------- It is not possible to dynamically add images in header/footer, but you can change them. The idea is to put a dummy picture in your template, render the template as usual, then replace the dummy picture with another one. You can do that for all medias at the same time. +Note: the aspect ratio will be the same as the replaced image +Note2 : Specify the filename that has been used to insert the image in the docx template (only its basename, not the full path) + +Syntax to replace dummy_header_pic.jpg:: + + tpl.replace_pic('dummy_header_pic.jpg','header_pic_i_want.jpg') + + +The replacement occurs in headers, footers and the whole document's body. + + +Replace docx medias +------------------- + +It is not possible to dynamically add other medias than images in header/footer, but you can change them. +The idea is to put a dummy media in your template, render the template as usual, then replace the dummy media with another one. +You can do that for all medias at the same time. Note: for images, the aspect ratio will be the same as the replaced image Note2 : it is important to have the source media files as they are required to calculate their CRC to find them in the docx. (dummy file name is not important) @@ -180,8 +197,9 @@ Syntax to replace dummy_header_pic.jpg:: tpl.replace_media('dummy_header_pic.jpg','header_pic_i_want.jpg') -dummy_header_pic.jpg must exist in the template directory when rendering and saving the generated docx. It must be the same +WARNING : unlike replace_pic() method, dummy_header_pic.jpg MUST exist in the template directory when rendering and saving the generated docx. It must be the same file as the one inserted manually in the docx template. +The replacement occurs in headers, footers and the whole document's body. Replace embedded objects ------------------------ @@ -193,8 +211,9 @@ Syntax to replace embedded_dummy.docx:: tpl.replace_embedded('embdded_dummy.docx','embdded_docx_i_want.docx') -embdded_dummy.docx must exist in the template directory when rendering and saving the generated docx. It must be the same +WARNING : unlike replace_pic() method, embdded_dummy.docx MUST exist in the template directory when rendering and saving the generated docx. It must be the same file as the one inserted manually in the docx template. +The replacement occurs in headers, footers and the whole document's body. Jinja custom filters -------------------- diff --git a/docxtpl/__init__.py b/docxtpl/__init__.py index c70fff4..8893356 100644 --- a/docxtpl/__init__.py +++ b/docxtpl/__init__.py @@ -5,7 +5,7 @@ Created : 2015-03-12 @author: Eric Lapouyade ''' -__version__ = '0.4.1' +__version__ = '0.4.2' from lxml import etree from docx import Document @@ -33,7 +33,7 @@ class DocxTemplate(object): self.docx = Document(docx) self.crc_to_new_media = {} self.crc_to_new_embedded = {} - self.media_to_replace = {} + self.pic_to_replace = {} def __getattr__(self, name): return getattr(self.docx, name) @@ -213,15 +213,13 @@ class DocxTemplate(object): def replace_pic(self,embedded_file,dst_file): """Replace embedded picture with original-name given by embedded_file. + (give only the file basename, not the full path) The new picture is given by dst_file. Notes: 1) embedded_file and dst_file must have the same extension/format 2) the aspect ratio will be the same as the replaced image - 3) There is no need to keep the original file name (compare - function replace_embedded). - - Oct 2017 - Riccardo Gusmeroli - riccardo.gusmeroli@polimi.it + 3) There is no need to keep the original file (this is not the case for replace_embedded and replace_media) """ emp_path,emb_ext=os.path.splitext(embedded_file) @@ -231,7 +229,7 @@ class DocxTemplate(object): raise ValueError('replace_pic: extensions must match') with open(dst_file, 'rb') as fh: - self.media_to_replace[embedded_file]=fh.read() + self.pic_to_replace[embedded_file]=fh.read() def replace_embedded(self,src_file,dst_file): """Replace one embdded object by another one into a docx @@ -267,7 +265,7 @@ class DocxTemplate(object): def pre_processing(self): - if self.media_to_replace: + if self.pic_to_replace: pic_map={} @@ -281,7 +279,9 @@ class DocxTemplate(object): pic_map.update(self._img_filename_to_part(rel.target_part)) # Do the actual replacement - for embedded_file,stream in self.media_to_replace.iteritems(): + for embedded_file,stream in self.pic_to_replace.iteritems(): + if embedded_file not in pic_map: + raise ValueError('Picture "%s" not found in the docx template' % embedded_file) pic_map[embedded_file][1]._blob=stream def _img_filename_to_part(self,doc_part): diff --git a/tests/replace_picture.py b/tests/replace_picture.py new file mode 100644 index 0000000..5160b38 --- /dev/null +++ b/tests/replace_picture.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +''' +Created : 2017-09-03 + +@author: Eric Lapouyade +''' + +from docxtpl import DocxTemplate + +DEST_FILE = 'test_files/replace_picture.docx' + +tpl=DocxTemplate('test_files/replace_picture_tpl.docx') + +context = {} + +tpl.replace_pic('python_logo.png','test_files/python.png') +tpl.render(context) +tpl.save(DEST_FILE) \ No newline at end of file diff --git a/tests/test_files/cellbg.docx b/tests/test_files/cellbg.docx index 44d82f9..546ab82 100644 Binary files a/tests/test_files/cellbg.docx and b/tests/test_files/cellbg.docx differ diff --git a/tests/test_files/dummy_pic_for_header.png b/tests/test_files/dummy_pic_for_header.png new file mode 100644 index 0000000..cd49a06 Binary files /dev/null and b/tests/test_files/dummy_pic_for_header.png differ diff --git a/tests/test_files/dynamic_table.docx b/tests/test_files/dynamic_table.docx index d96b96a..d93107c 100644 Binary files a/tests/test_files/dynamic_table.docx and b/tests/test_files/dynamic_table.docx differ diff --git a/tests/test_files/embedded.docx b/tests/test_files/embedded.docx new file mode 100644 index 0000000..f52533e Binary files /dev/null and b/tests/test_files/embedded.docx differ diff --git a/tests/test_files/embedded_dummy.docx b/tests/test_files/embedded_dummy.docx new file mode 100644 index 0000000..48a2663 Binary files /dev/null and b/tests/test_files/embedded_dummy.docx differ diff --git a/tests/test_files/embedded_dummy2.docx b/tests/test_files/embedded_dummy2.docx new file mode 100644 index 0000000..6bcc9df Binary files /dev/null and b/tests/test_files/embedded_dummy2.docx differ diff --git a/tests/test_files/embedded_embedded_docx.docx b/tests/test_files/embedded_embedded_docx.docx new file mode 100644 index 0000000..3c21a96 Binary files /dev/null and b/tests/test_files/embedded_embedded_docx.docx differ diff --git a/tests/test_files/embedded_embedded_docx_tpl.docx b/tests/test_files/embedded_embedded_docx_tpl.docx new file mode 100644 index 0000000..1d71099 Binary files /dev/null and b/tests/test_files/embedded_embedded_docx_tpl.docx differ diff --git a/tests/test_files/embedded_main_tpl.docx b/tests/test_files/embedded_main_tpl.docx new file mode 100644 index 0000000..0a8d1a5 Binary files /dev/null and b/tests/test_files/embedded_main_tpl.docx differ diff --git a/tests/test_files/embedded_static_docx.docx b/tests/test_files/embedded_static_docx.docx new file mode 100644 index 0000000..59d3cc9 Binary files /dev/null and b/tests/test_files/embedded_static_docx.docx differ diff --git a/tests/test_files/escape.docx b/tests/test_files/escape.docx index 42fa407..fd85530 100644 Binary files a/tests/test_files/escape.docx and b/tests/test_files/escape.docx differ diff --git a/tests/test_files/header_footer.docx b/tests/test_files/header_footer.docx index 1ea1c61..274ff9d 100644 Binary files a/tests/test_files/header_footer.docx and b/tests/test_files/header_footer.docx differ diff --git a/tests/test_files/header_footer_entities.docx b/tests/test_files/header_footer_entities.docx index 189831a..c45320a 100644 Binary files a/tests/test_files/header_footer_entities.docx and b/tests/test_files/header_footer_entities.docx differ diff --git a/tests/test_files/header_footer_image.docx b/tests/test_files/header_footer_image.docx new file mode 100644 index 0000000..a5951ab Binary files /dev/null and b/tests/test_files/header_footer_image.docx differ diff --git a/tests/test_files/header_footer_image_tpl.docx b/tests/test_files/header_footer_image_tpl.docx new file mode 100644 index 0000000..888d544 Binary files /dev/null and b/tests/test_files/header_footer_image_tpl.docx differ diff --git a/tests/test_files/header_footer_utf8.docx b/tests/test_files/header_footer_utf8.docx index 9b67a1e..f00472b 100644 Binary files a/tests/test_files/header_footer_utf8.docx and b/tests/test_files/header_footer_utf8.docx differ diff --git a/tests/test_files/inline_image.docx b/tests/test_files/inline_image.docx index ab24944..a825e8c 100644 Binary files a/tests/test_files/inline_image.docx and b/tests/test_files/inline_image.docx differ diff --git a/tests/test_files/nested_for.docx b/tests/test_files/nested_for.docx index 6f997a2..73261d2 100644 Binary files a/tests/test_files/nested_for.docx and b/tests/test_files/nested_for.docx differ diff --git a/tests/test_files/order.docx b/tests/test_files/order.docx index 82e9ddf..106c8f4 100644 Binary files a/tests/test_files/order.docx and b/tests/test_files/order.docx differ diff --git a/tests/test_files/python.png b/tests/test_files/python.png new file mode 100644 index 0000000..09e086d Binary files /dev/null and b/tests/test_files/python.png differ diff --git a/tests/test_files/replace_picture.docx b/tests/test_files/replace_picture.docx new file mode 100644 index 0000000..58e68be Binary files /dev/null and b/tests/test_files/replace_picture.docx differ diff --git a/tests/test_files/replace_picture_tpl.docx b/tests/test_files/replace_picture_tpl.docx new file mode 100644 index 0000000..3d76d98 Binary files /dev/null and b/tests/test_files/replace_picture_tpl.docx differ diff --git a/tests/test_files/richtext.docx b/tests/test_files/richtext.docx index a4ac36e..49fa0ea 100644 Binary files a/tests/test_files/richtext.docx and b/tests/test_files/richtext.docx differ diff --git a/tests/test_files/richtext_and_if.docx b/tests/test_files/richtext_and_if.docx index 813560a..4744491 100644 Binary files a/tests/test_files/richtext_and_if.docx and b/tests/test_files/richtext_and_if.docx differ diff --git a/tests/test_files/subdoc.docx b/tests/test_files/subdoc.docx index 08c9ab5..5d5f6aa 100644 Binary files a/tests/test_files/subdoc.docx and b/tests/test_files/subdoc.docx differ