First running version
This commit is contained in:
parent
d8a33febe0
commit
e9b9a8bf3f
17
.project
Normal file
17
.project
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>python-docx-template</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.python.pydev.PyDevBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.python.pydev.pythonNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
5
.pydevproject
Normal file
5
.pydevproject
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?eclipse-pydev version="1.0"?><pydev_project>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
|
||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
|
||||
</pydev_project>
|
||||
2
.settings/org.eclipse.core.resources.prefs
Normal file
2
.settings/org.eclipse.core.resources.prefs
Normal file
@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//docxtpl/__init__.py=utf-8
|
||||
@ -7,10 +7,64 @@ Created : 2015-03-12
|
||||
|
||||
__version__ = '0.1.1'
|
||||
|
||||
from lxml import etree
|
||||
from docx import Document
|
||||
from jinja2 import Template
|
||||
import copy
|
||||
import re
|
||||
|
||||
class DocxTemplate(object):
|
||||
""" Class for managing docx files as they were jinja2 templates """
|
||||
pass
|
||||
def __init__(self, docx):
|
||||
self.docx = Document(docx)
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.docx, name)
|
||||
|
||||
def build_xml(self,context):
|
||||
src_xml = etree.tostring(self.docx._element.body, pretty_print=True)
|
||||
|
||||
with open('/tmp/docx1.xml','w') as fh:
|
||||
fh.write(src_xml)
|
||||
|
||||
# strip all xml tags inside {% %} and {{ }}
|
||||
# that Microsoft word can insert into xml code for this part of the document
|
||||
def striptags(m):
|
||||
return re.sub('</w:t>.*?(<w:t>|<w:t [^>]*>)','',m.group(0),flags=re.DOTALL)
|
||||
src_xml = re.sub(r'{%(?:(?!%}).)*|{{(?:(?!}}).)*',striptags,src_xml,flags=re.DOTALL)
|
||||
|
||||
# manage table cell background color
|
||||
def cellbg(m):
|
||||
cell_xml = m.group(1) + m.group(3)
|
||||
cell_xml = re.sub(r'<w:r[ >](?:(?!<w:r[ >]).)*<w:t></w:t>.*?</w:r>','',cell_xml,flags=re.DOTALL)
|
||||
return re.sub(r'(<w:shd[^/]*w:fill=")[^"]*("[^/]*/>)',r'\1{{ %s}}\2' % m.group(2), cell_xml)
|
||||
src_xml = re.sub(r'(<w:tc[ >](?:(?!<w:tc[ >]).)*){%\s*cellbg\s+([^%]*)\s*%}(.*?</w:tc>)',cellbg,src_xml,flags=re.DOTALL)
|
||||
|
||||
# replace xml code corresponding to the paragraph containing {{{ xxx }}} by {{ xxx }}
|
||||
src_xml = re.sub(r'<w:p[ >](?:(?!<w:p[ >]).)*{{{([^}]*)}}}.*?</w:p>',r'{{\1}}',src_xml,flags=re.DOTALL)
|
||||
|
||||
# replace xml code corresponding to the row containing {% tr-xxx template tag by {% xxx template tag itself
|
||||
src_xml = re.sub(r'<w:tr[ >](?:(?!<w:tr[ >]).)*{%\s*tr-([^%]*%}).*?</w:tr>',r'{% \1',src_xml,flags=re.DOTALL)
|
||||
|
||||
# replace xml code corresponding to the paragraph containing {% p-xxx template tag by {% xxx template tag itself
|
||||
src_xml = re.sub(r'<w:p[ >](?:(?!<w:p[ >]).)*{%\s*p-([^%]*%}).*?</w:p>',r'{% \1',src_xml,flags=re.DOTALL)
|
||||
|
||||
with open('/tmp/docx2.xml','w') as fh:
|
||||
fh.write(src_xml)
|
||||
|
||||
template = Template(src_xml)
|
||||
dst_xml = template.render(context)
|
||||
|
||||
return dst_xml
|
||||
|
||||
def map_xml(self,xml):
|
||||
root = self.docx._element
|
||||
body = root.body
|
||||
root.replace(body,etree.fromstring(xml))
|
||||
|
||||
def render(self,context):
|
||||
xml = self.build_xml(context)
|
||||
self.map_xml(xml)
|
||||
|
||||
class Subdoc(object):
|
||||
""" Class for subdocumentation insertion into master document """
|
||||
|
||||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
19
tests/order.py
Normal file
19
tests/order.py
Normal file
@ -0,0 +1,19 @@
|
||||
from docxtpl import DocxTemplate
|
||||
|
||||
tpl=DocxTemplate('test_files/order_tpl.docx')
|
||||
|
||||
context = {
|
||||
'customer_name' : 'Eric',
|
||||
'items' : [
|
||||
{'desc' : 'Python interpreters', 'qty' : 2, 'price' : 'FREE' },
|
||||
{'desc' : 'Django projects', 'qty' : 5403, 'price' : 'FREE' },
|
||||
{'desc' : 'Guido', 'qty' : 1, 'price' : '100,000,000.00' },
|
||||
],
|
||||
'in_europe' : True,
|
||||
'is_paid': False,
|
||||
'company_name' : 'The World Wide company',
|
||||
'total_price' : '100,000,000.00'
|
||||
}
|
||||
|
||||
tpl.render(context)
|
||||
tpl.save('test_files/order.docx')
|
||||
BIN
tests/test_files/order.docx
Normal file
BIN
tests/test_files/order.docx
Normal file
Binary file not shown.
BIN
tests/test_files/order_tpl.docx
Normal file
BIN
tests/test_files/order_tpl.docx
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user