$30 off During Our Annual Pro Sale. View Details »
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
87
[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
69
Django Round-Up – Meetup Django CH #19
zyegfryed
2
87
[Django] URL prefix with runserver
zyegfryed
0
1.4k
[Django] RESTful API
zyegfryed
1
220
Other Decks in Programming
See All in Programming
TestingOsaka6_Ozono
o3
0
140
Why Kotlin? 電子カルテを Kotlin で開発する理由 / Why Kotlin? at Henry
agatan
2
7.1k
Flutter On-device AI로 완성하는 오프라인 앱, 박제창 @DevFest INCHEON 2025
itsmedreamwalker
1
110
宅宅自以為的浪漫:跟 AI 一起為自己辦的研討會寫一個售票系統
eddie
0
500
20251212 AI 時代的 Legacy Code 營救術 2025 WebConf
mouson
0
110
30分でDoctrineの仕組みと使い方を完全にマスターする / phpconkagawa 2025 Doctrine
ttskch
3
830
TUIライブラリつくってみた / i-just-make-TUI-library
kazto
1
380
バックエンドエンジニアによる Amebaブログ K8s 基盤への CronJobの導入・運用経験
sunabig
0
150
Canon EOS R50 V と R5 Mark II 購入でみえてきた最近のデジイチ VR180 事情、そして VR180 静止画に活路を見出すまで
karad
0
110
AIコーディングエージェント(skywork)
kondai24
0
160
配送計画の均等化機能を提供する取り組みについて(⽩⾦鉱業 Meetup Vol.21@六本⽊(数理最適化編))
izu_nori
0
150
AIエンジニアリングのご紹介 / Introduction to AI Engineering
rkaga
5
2k
Featured
See All Featured
The Power of CSS Pseudo Elements
geoffreycrofte
80
6.1k
GitHub's CSS Performance
jonrohan
1032
470k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.1k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.8k
Automating Front-end Workflow
addyosmani
1371
200k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
7.9k
A Tale of Four Properties
chriscoyier
162
23k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.5k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
51k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3k
Agile that works and the tools we love
rasmusluckow
331
21k
Optimizing for Happiness
mojombo
379
70k
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?