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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Sébastien Fievet
April 16, 2011
Programming
91
0
Share
[Django] Generating PDF with PDFForm
Sébastien Fievet
April 16, 2011
More Decks by Sébastien Fievet
See All by Sébastien Fievet
Introduction to Flask
zyegfryed
0
63
Django Round-Up – Meetup Django CH #28
zyegfryed
0
61
Django Round-Up – Meetup Django CH #25
zyegfryed
0
56
Django Round-Up – Meetup Django CH #23
zyegfryed
0
51
Django Round-Up – Meetup Django CH #21
zyegfryed
0
68
Django Round-Up – Meetup Django CH #20
zyegfryed
0
72
Django Round-Up – Meetup Django CH #19
zyegfryed
2
87
[Django] URL prefix with runserver
zyegfryed
0
1.5k
[Django] RESTful API
zyegfryed
1
220
Other Decks in Programming
See All in Programming
Cache-moi si tu peux : patterns et pièges du cache en production - Devoxx France 2026 - Conférence
slecache
0
240
感情を設計する
ichimichi
5
1.5k
Spec Driven Development | AI Summit Vilnius
danielsogl
PRO
1
100
iOS機能開発のAI環境と起きた変化
ryunakayama
0
180
PHP で mp3 プレイヤーを実装しよう
m3m0r7
PRO
0
280
実践CRDT
tamadeveloper
0
570
Angular Signal Forms
debug_mode
0
110
アーキテクチャモダナイゼーションとは何か
nwiizo
19
5.3k
PCOVから学ぶコードカバレッジ #phpcon_odawara
o0h
PRO
0
270
AI-DLC Deep Dive
yuukiyo
9
4.2k
Lightning-Fast Method Calls with Ruby 4.1 ZJIT / RubyKaigi 2026
k0kubun
3
420
YJITとZJITにはイカなる違いがあるのか?
nakiym
0
220
Featured
See All Featured
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
99
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
10k
Designing Experiences People Love
moore
143
24k
Embracing the Ebb and Flow
colly
88
5k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.2k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.1k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
122
21k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
2
1k
Site-Speed That Sticks
csswizardry
13
1.2k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
200
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
199
73k
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?