Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
[Django] Generating PDF with PDFForm
Search
Sébastien Fievet
April 16, 2011
Programming
0
76
[Django] Generating PDF with PDFForm
Sébastien Fievet
April 16, 2011
Tweet
Share
More Decks by Sébastien Fievet
See All by Sébastien Fievet
Introduction to Flask
zyegfryed
0
56
Django Round-Up – Meetup Django CH #28
zyegfryed
0
54
Django Round-Up – Meetup Django CH #25
zyegfryed
0
50
Django Round-Up – Meetup Django CH #23
zyegfryed
0
44
Django Round-Up – Meetup Django CH #21
zyegfryed
0
62
Django Round-Up – Meetup Django CH #20
zyegfryed
0
58
Django Round-Up – Meetup Django CH #19
zyegfryed
2
79
[Django] URL prefix with runserver
zyegfryed
0
1.3k
[Django] RESTful API
zyegfryed
1
200
Other Decks in Programming
See All in Programming
Komplexe Oberflächen mit SVG und der Web Animation API
joergneumann
0
680
2 週間で Twitter Bot を作ってみた
contour_gara
0
790
OpenAPIを中心に考えるAPI開発入門 / Introduction to API Development with a Focus on OpenAPI
seike460
PRO
2
180
業務ツールとして使うPostman
msys75
0
110
見た目から始める生産性向上
ikumatadokoro
10
1.5k
初心者のためのRubyKaigi入門/RubyKaigi Introduction
a_matsuda
10
1.5k
Amazon SQSコンシューマー疎結合への旅 - 出張! #DevelopersIO IT技術ブログの中の人が語る勉強会 #3
quiver
0
330
PHPはいつから死んでいるかの調査
chiroruxx
2
420
検証も兼ねて個人開発でHonoとかと向き合った話
hanetsuki
1
1.3k
Direct Style Effect Systems The Print[A] ExampleA Comprehension Aid
philipschwarz
PRO
0
120
Domain-Driven Transformation
hschwentner
2
1.5k
デフォルトにして至高、RubyMineの大好きな所
ruzia
0
930
Featured
See All Featured
Art, The Web, and Tiny UX
lynnandtonic
290
19k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
66
14k
Optimising Largest Contentful Paint
csswizardry
13
2.4k
We Have a Design System, Now What?
morganepeng
43
6.8k
Atom: Resistance is Futile
akmur
260
25k
VelocityConf: Rendering Performance Case Studies
addyosmani
321
23k
Code Reviewing Like a Champion
maltzj
515
39k
Rebuilding a faster, lazier Slack
samanthasiow
74
8.2k
Large-scale JavaScript Application Architecture
addyosmani
504
110k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
8
3.4k
10 Git Anti Patterns You Should be Aware of
lemiorhan
649
58k
Building Your Own Lightsaber
phodgson
100
5.7k
Transcript
Generating PDF with PDFForm Sébastien Fievet Djangocong Marseille April 16,
2011
Case study: outputting “simple” PDFs
Simple things should remain simple
Focus on skills
Designer == templating
Developper == rendering
The solution ?
None
None
1
pip install fdfgen
from fdfgen import forge_fdf def fill_form(fields, src, pdftk_bin): ... fdf_stream
= forge_fdf(fdf_data_strings=fields) ...
Issue
Issue Breaks on accentuated character
“ ” Fork it, fix it, contribute it. -- a
DVCS convinced guy
2
aptitude install pdftk
pdftk <PDF input> dump_data_fields
pdftk <PDF input> fill_form <FDF file> output <PDF output> flatten
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
But...
But... utf8 support broken on Ubuntu 10.10(binary package, v1.41)
But... utf8 support broken on Ubuntu 10.10(binary package, v1.41) Use
the source luke (v1.44)
But... utf8 support broken on Ubuntu 10.10(binary package, v1.41) Use
the source luke (v1.44) wget && make && make install
3
Django template engine == The challenge
Template loading
Template loading PDFs are binary file
Template loading PDFs are binary file We don't care about
the file content
Template loading PDFs are binary file We don't care about
the file content But we ALWAYS need the template path
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
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
Template origin * Paranoiac mode
Template origin TEMPLATE_DEBUG = True * Paranoiac mode
Template origin TEMPLATE_DEBUG = True Or monkey-patch make_origin * *
Paranoiac mode
Template rendering
Template rendering Custom rendering method Leveraging pdftk and FDFGen Use
a dedicated Template class
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
https://gist.github.com/918403
4
Usage
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
Demo
Questions?