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
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Sébastien Fievet
April 16, 2011
Programming
0
88
[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
62
Django Round-Up – Meetup Django CH #28
zyegfryed
0
60
Django Round-Up – Meetup Django CH #25
zyegfryed
0
55
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
70
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
ぼくの開発環境2026
yuzneri
0
230
今こそ知るべき耐量子計算機暗号(PQC)入門 / PQC: What You Need to Know Now
mackey0225
3
380
開発者から情シスまで - 多様なユーザー層に届けるAPI提供戦略 / Postman API Night Okinawa 2026 Winter
tasshi
0
200
AIエージェントのキホンから学ぶ「エージェンティックコーディング」実践入門
masahiro_nishimi
5
460
なるべく楽してバックエンドに型をつけたい!(楽とは言ってない)
hibiki_cube
0
140
Amazon Bedrockを活用したRAGの品質管理パイプライン構築
tosuri13
4
710
そのAIレビュー、レビューしてますか? / Are you reviewing those AI reviews?
rkaga
6
4.6k
SourceGeneratorのススメ
htkym
0
200
0→1 フロントエンド開発 Tips🚀 #レバテックMeetup
bengo4com
0
570
16年目のピクシブ百科事典を支える最新の技術基盤 / The Modern Tech Stack Powering Pixiv Encyclopedia in its 16th Year
ahuglajbclajep
5
1k
AIによる開発の民主化を支える コンテキスト管理のこれまでとこれから
mulyu
3
290
AI時代のキャリアプラン「技術の引力」からの脱出と「問い」へのいざない / tech-gravity
minodriven
21
7.2k
Featured
See All Featured
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
0
360
Optimizing for Happiness
mojombo
379
71k
Designing Powerful Visuals for Engaging Learning
tmiket
0
230
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.2k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
51k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
69
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
120
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
82
How to make the Groovebox
asonas
2
1.9k
The SEO Collaboration Effect
kristinabergwall1
0
350
Agile that works and the tools we love
rasmusluckow
331
21k
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.3k
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?