Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[Django] Generating PDF with PDFForm

[Django] Generating PDF with PDFForm

Sébastien Fievet

April 16, 2011
Tweet

More Decks by Sébastien Fievet

Other Decks in Programming

Transcript

  1. 1

  2. 2

  3. import subprocess ... def fill_form(fields, src, pdftk_bin): ... cmd =

    ' '.join([pdftk_bin, src, 'fill_form', '-', 'output', '-', 'flatten']) try: process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) return process.communicate(input=fdf_stream) except OSError, e: return None, e
  4. But... utf8 support broken on Ubuntu 10.10(binary package, v1.41) Use

    the source luke (v1.44) wget && make && make install
  5. 3

  6. Template loading PDFs are binary file We don't care about

    the file content But we ALWAYS need the template path
  7. import codecs from django.template.loader import find_template def get_template(template_name): def strict_errors(exception):

    raise exception def fake_strict_errors(exception): return (u'', -1) codecs.register_error('strict', fake_strict_errors) template, origin = find_template(template_name) codecs.register_error('strict', strict_errors) return template
  8. from django.template import loader, Template ... def get_template_from_string(source, origin=None, name=None):

    if name and name.endswith('.pdf'): return PdfTemplate('pdf', origin, name) return Template(source, origin, name) loader.get_template_from_string = get_template_from_string
  9. from django.template import Template ... class PdfTemplate(Template): def __init__(self, template_string,

    origin=None, name='<Unknown Template>'): self.origin = origin def render(self, context): context = context.items() output, err = fill_form(context, self.origin.name) if err: raise PdfTemplateError(err) return output
  10. 4

  11. from django.http import HttpResponse from pdf import get_template def pdf_view(request,

    template_name='pdf/awesome.pdf'): context = { 'foo': 'bar', 'bar': 'baz', 'awesome': True, 'user': request.user, } response = HttpResponse(mimetype='application/pdf') response['Content-Disposition'] = 'attachment; filename=awesome.pdf' template = get_template(template_name) response.write(template.render(context)) return response