V0.12.0
This commit is contained in:
parent
b7d782ab20
commit
61c8924663
11
CHANGES.rst
11
CHANGES.rst
@ -1,8 +1,17 @@
|
|||||||
0.12.0 (2021-07-31)
|
0.12.0 (2021-08-15)
|
||||||
-------------------
|
-------------------
|
||||||
- Code has be split into many files for better readability
|
- Code has be split into many files for better readability
|
||||||
- Use docxcomposer to attach parts when a docx file is given to create a subdoc
|
- Use docxcomposer to attach parts when a docx file is given to create a subdoc
|
||||||
Images, styles etc... must now be taken in account in subdocs
|
Images, styles etc... must now be taken in account in subdocs
|
||||||
|
- Some internal XML IDs are now renumbered to avoid collision, thus images are not randomly disapearing anymore.
|
||||||
|
- fix #372
|
||||||
|
- fix #374
|
||||||
|
- fix #375
|
||||||
|
- fix #369
|
||||||
|
- fix #368
|
||||||
|
- fix #347
|
||||||
|
- fix #181
|
||||||
|
- fix #61
|
||||||
|
|
||||||
0.11.5 (2021-05-09)
|
0.11.5 (2021-05-09)
|
||||||
-------------------
|
-------------------
|
||||||
|
|||||||
@ -229,7 +229,16 @@ Sub-documents
|
|||||||
-------------
|
-------------
|
||||||
|
|
||||||
A template variable can contain a complex and built from scratch with python-docx word document.
|
A template variable can contain a complex and built from scratch with python-docx word document.
|
||||||
To do so, get first a sub-document object from template object and use it as a python-docx document object, see example in `tests/subdoc.py`.
|
To do so, get first a sub-document object from template object and use it as a python-docx document object,
|
||||||
|
see example in `tests/subdoc.py`.
|
||||||
|
|
||||||
|
Since docxtpl V0.12.0, it is now possible to merge an exsting .docx as a subdoc, just specify its path when
|
||||||
|
calling method `new_subdoc()` ::
|
||||||
|
|
||||||
|
tpl = DocxTemplate('templates/merge_docx_master_tpl.docx')
|
||||||
|
sd = tpl.new_subdoc('templates/merge_docx_subdoc.docx')
|
||||||
|
|
||||||
|
see `tests/merge_docx.py` for full code
|
||||||
|
|
||||||
Escaping, newline, new paragraph, Listing
|
Escaping, newline, new paragraph, Listing
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
|
|||||||
@ -4,7 +4,7 @@ Created : 2015-03-12
|
|||||||
|
|
||||||
@author: Eric Lapouyade
|
@author: Eric Lapouyade
|
||||||
"""
|
"""
|
||||||
__version__ = '0.12.0.dev1'
|
__version__ = '0.12.0'
|
||||||
|
|
||||||
# flake8: noqa
|
# flake8: noqa
|
||||||
from .inline_image import InlineImage
|
from .inline_image import InlineImage
|
||||||
@ -12,4 +12,3 @@ from .listing import Listing
|
|||||||
from .richtext import RichText, R
|
from .richtext import RichText, R
|
||||||
from .subdoc import Subdoc
|
from .subdoc import Subdoc
|
||||||
from .template import DocxTemplate
|
from .template import DocxTemplate
|
||||||
import docxtpl.docx_patch
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
Created : 2021-08-14
|
|
||||||
|
|
||||||
@author: Eric Lapouyade
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
from docx.parts.story import BaseStoryPart
|
|
||||||
|
|
||||||
|
|
||||||
class DocxTplBaseStoryPart:
|
|
||||||
next_id_cptr = 0
|
|
||||||
|
|
||||||
@property
|
|
||||||
def docx_next_id(self):
|
|
||||||
id_str_lst = self._element.xpath('//@id')
|
|
||||||
used_ids = [int(id_str) for id_str in id_str_lst if id_str.isdigit()]
|
|
||||||
if not used_ids:
|
|
||||||
DocxTplBaseStoryPart.next_id_cptr += 1 # global counter
|
|
||||||
return DocxTplBaseStoryPart.next_id_cptr
|
|
||||||
return max(used_ids) + 1
|
|
||||||
|
|
||||||
|
|
||||||
# Patch python_docx next_id() to have no collision on default value
|
|
||||||
BaseStoryPart.next_id = DocxTplBaseStoryPart.docx_next_id
|
|
||||||
@ -4,7 +4,6 @@ Created : 2021-07-30
|
|||||||
|
|
||||||
@author: Eric Lapouyade
|
@author: Eric Lapouyade
|
||||||
"""
|
"""
|
||||||
from copy import deepcopy
|
|
||||||
|
|
||||||
from docx import Document
|
from docx import Document
|
||||||
from docx.oxml import CT_SectPr
|
from docx.oxml import CT_SectPr
|
||||||
@ -34,7 +33,6 @@ class SubdocComposer(Composer):
|
|||||||
for element in doc.element.body:
|
for element in doc.element.body:
|
||||||
if isinstance(element, CT_SectPr):
|
if isinstance(element, CT_SectPr):
|
||||||
continue
|
continue
|
||||||
# element = deepcopy(element)
|
|
||||||
self.add_referenced_parts(doc.part, self.doc.part, element)
|
self.add_referenced_parts(doc.part, self.doc.part, element)
|
||||||
self.add_styles(doc, element)
|
self.add_styles(doc, element)
|
||||||
self.add_numberings(doc, element)
|
self.add_numberings(doc, element)
|
||||||
|
|||||||
@ -5,7 +5,6 @@ Created : 2015-03-12
|
|||||||
@author: Eric Lapouyade
|
@author: Eric Lapouyade
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
from .subdoc import Subdoc
|
from .subdoc import Subdoc
|
||||||
import functools
|
import functools
|
||||||
import io
|
import io
|
||||||
@ -43,6 +42,7 @@ class DocxTemplate(object):
|
|||||||
self.pics_to_replace = {}
|
self.pics_to_replace = {}
|
||||||
self.pic_map = {}
|
self.pic_map = {}
|
||||||
self.current_rendering_part = None
|
self.current_rendering_part = None
|
||||||
|
self.docx_ids_index = 1000
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
return getattr(self.docx, name)
|
return getattr(self.docx, name)
|
||||||
@ -319,6 +319,10 @@ class DocxTemplate(object):
|
|||||||
# fix tables if needed
|
# fix tables if needed
|
||||||
tree = self.fix_tables(xml_src)
|
tree = self.fix_tables(xml_src)
|
||||||
|
|
||||||
|
# fix docPr ID's
|
||||||
|
self.fix_docpr_ids(tree)
|
||||||
|
|
||||||
|
# Replace body xml tree
|
||||||
self.map_tree(tree)
|
self.map_tree(tree)
|
||||||
|
|
||||||
# Headers
|
# Headers
|
||||||
@ -421,6 +425,12 @@ class DocxTemplate(object):
|
|||||||
|
|
||||||
return tree
|
return tree
|
||||||
|
|
||||||
|
def fix_docpr_ids(self, tree):
|
||||||
|
# some Ids may have some collisions : so renumbering all of them :
|
||||||
|
for elt in tree.xpath('//wp:docPr', namespaces=docx.oxml.ns.nsmap):
|
||||||
|
self.docx_ids_index += 1
|
||||||
|
elt.attrib['id'] = str(self.docx_ids_index)
|
||||||
|
|
||||||
def new_subdoc(self, docpath=None):
|
def new_subdoc(self, docpath=None):
|
||||||
return Subdoc(self, docpath)
|
return Subdoc(self, docpath)
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,12 @@ from docx.shared import Mm
|
|||||||
tpl = DocxTemplate('templates/header_footer_inline_image_tpl.docx')
|
tpl = DocxTemplate('templates/header_footer_inline_image_tpl.docx')
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'inline_image': InlineImage(tpl, 'templates/django.png', height=Mm(10))
|
'inline_image': InlineImage(tpl, 'templates/django.png', height=Mm(10)),
|
||||||
|
'images': [
|
||||||
|
InlineImage(tpl, 'templates/python.png', height=Mm(10)),
|
||||||
|
InlineImage(tpl, 'templates/python.png', height=Mm(10)),
|
||||||
|
InlineImage(tpl, 'templates/python.png', height=Mm(10))
|
||||||
|
]
|
||||||
}
|
}
|
||||||
tpl.render(context)
|
tpl.render(context)
|
||||||
tpl.save('output/header_footer_inline_image.docx')
|
tpl.save('output/header_footer_inline_image.docx')
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user