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
84
[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
58
Django Round-Up – Meetup Django CH #28
zyegfryed
0
58
Django Round-Up – Meetup Django CH #25
zyegfryed
0
54
Django Round-Up – Meetup Django CH #23
zyegfryed
0
49
Django Round-Up – Meetup Django CH #21
zyegfryed
0
66
Django Round-Up – Meetup Django CH #20
zyegfryed
0
63
Django Round-Up – Meetup Django CH #19
zyegfryed
2
84
[Django] URL prefix with runserver
zyegfryed
0
1.4k
[Django] RESTful API
zyegfryed
1
220
Other Decks in Programming
See All in Programming
いりゃあせ、PHPカンファレンス名古屋2025 / Welcome to PHP Conference Nagoya 2025
ttskch
1
270
Amazon ECS とマイクロサービスから考えるシステム構成
hiyanger
2
490
Lottieアニメーションをカスタマイズしてみた
tahia910
0
120
Kanzawa.rbのLT大会を支える技術の裏側を変更する Ruby on Rails + Litestream 編
muryoimpl
0
220
チームリードになって変わったこと
isaka1022
0
190
Software Architecture
hschwentner
6
2.1k
プログラミング言語学習のススメ / why-do-i-learn-programming-language
yashi8484
0
120
パスキーのすべて ── 導入・UX設計・実装の紹介 / 20250213 パスキー開発者の集い
kuralab
3
670
Pythonでもちょっとリッチな見た目のアプリを設計してみる
ueponx
1
480
JavaScriptツール群「UnJS」を5分で一気に駆け巡る!
k1tikurisu
10
1.8k
ASP. NET CoreにおけるWebAPIの最新情報
tomokusaba
0
360
テストをしないQAエンジニアは何をしているか?
nealle
0
130
Featured
See All Featured
Code Review Best Practice
trishagee
66
17k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
GraphQLの誤解/rethinking-graphql
sonatard
68
10k
Writing Fast Ruby
sferik
628
61k
Automating Front-end Workflow
addyosmani
1367
200k
Measuring & Analyzing Core Web Vitals
bluesmoon
6
240
Code Reviewing Like a Champion
maltzj
521
39k
The World Runs on Bad Software
bkeepers
PRO
67
11k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
6
540
RailsConf 2023
tenderlove
29
1k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
Building an army of robots
kneath
302
45k
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?