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
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Sébastien Fievet
April 16, 2011
Programming
92
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
66
Django Round-Up – Meetup Django CH #28
zyegfryed
0
64
Django Round-Up – Meetup Django CH #25
zyegfryed
0
57
Django Round-Up – Meetup Django CH #23
zyegfryed
0
54
Django Round-Up – Meetup Django CH #21
zyegfryed
0
72
Django Round-Up – Meetup Django CH #20
zyegfryed
0
77
Django Round-Up – Meetup Django CH #19
zyegfryed
2
89
[Django] URL prefix with runserver
zyegfryed
0
1.5k
[Django] RESTful API
zyegfryed
1
230
Other Decks in Programming
See All in Programming
生成AI時代にこそ効くGo | Why Go Works in the Age of Generative AI
mom0tomo
8
3.1k
oxlintはeslint/typescript-eslintを置き換えられるのか
shomafujita
2
300
正しくソフトウェアを作る、前提を疑うための認知の視点 / doubt-premise
minodriven
15
4.8k
LLM本来の能力を解き放つサンドボックス技術とAI民主化への適用
yukukotani
2
1.4k
net-httpのHTTP/2対応について
naruse
0
420
Copilot CLI の継戦能力を高める コンテキスト管理
nozomutu
1
1.2k
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3k
TSKaigi 2026 TypeScriptバックエンドのオブザーバビリティ戦略 — Datadog × NestJSの実践
taiseiyamamotoan
1
220
技術記事、AIに書かせるか、自分で書くか? 〜それでも私が自分の手で書く理由〜 / #QiitaConference
jnchito
2
1.2k
Lessons from Spec-Driven Development
simas
PRO
0
110
Make SRE Operations Easier with Azure SRE Agent
kkamegawa
0
2.9k
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
230
Featured
See All Featured
ラッコキーワード サービス紹介資料
rakko
1
3.5M
Visualization
eitanlees
152
17k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
400
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.5k
Building a Scalable Design System with Sketch
lauravandoore
463
34k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
The agentic SEO stack - context over prompts
schlessera
0
790
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
350
Git: the NoSQL Database
bkeepers
PRO
432
67k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
380
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.2k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
370
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?