'''
Manipulation des formulaires PDF
@author: olivier.massot, sept. 2017
'''
import codecs
import subprocess
from path import Path
PDFTK_PATH = Path(__file__).parent.parent / r"bin\pdftk.exe"
def gen_xfdf(filename, datas={}):
''' Generates a temp XFDF file suited for fill_form function, based on dict input data '''
fields = []
for key, value in datas.items():
fields.append("""%s""" % (key, _normalize(value)))
tpl = """
%s
""" % "\n\t\t\t".join(fields)
filename = Path(filename)
with open(filename, 'w') as f:
f.write(tpl)
convert_to_utf8(filename)
return filename
def convert_to_utf8(filename):
f = codecs.open(filename, 'r', 'cp1252', errors='ignore')
u = f.read() # now the contents have been transformed to a Unicode string
out = codecs.open(filename, 'w', 'utf-8', errors='ignore')
out.write(u) # and now the contents have been output as UTF-8
f.close()
out.close()
def fill_form(pdfname, xfdfname, out_file, flatten=True):
'''
Fills a PDF form with given dict input data.
Return temp file if no out_file provided.
'''
cmd = "%s %s fill_form %s output %s need_appearances" % (PDFTK_PATH, pdfname, xfdfname, out_file)
if flatten:
cmd += ' flatten'
run_command(cmd, True)
return out_file
def check_output(*popenargs, **kwargs):
if 'stdout' in kwargs:
raise ValueError('stdout argument not allowed, it will be overridden.')
process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
output, unused_err = process.communicate()
retcode = process.poll()
if retcode:
cmd = kwargs.get("args")
if cmd is None:
cmd = popenargs[0]
raise subprocess.CalledProcessError(retcode, cmd)
return output
def _normalize(value):
return str(value).replace("\"", "'").replace("<", "<").replace(">", ">")
def run_command(command, shell=False):
''' run a system command and yield output '''
p = check_output(command, shell=shell)
return str(p).split('\n')