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
86
[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
68
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
私はどうやって技術力を上げたのか
yusukebe
43
18k
あなたとKaigi on Rails / Kaigi on Rails + You
shimoju
0
140
ALL CODE BASE ARE BELONG TO STUDY
uzulla
18
3.3k
What's new in Spring Modulith?
olivergierke
1
150
Web Components で実現する Hotwire とフロントエンドフレームワークの橋渡し / Bridging with Web Components
da1chi
3
2.4k
『毎日の移動』を支えるGoバックエンド内製開発
yutautsugi
2
240
Advance Your Career with Open Source
ivargrimstad
0
520
Android16 Migration Stories ~Building a Pattern for Android OS upgrades~
reoandroider
0
110
Le côté obscur des IA génératives
pascallemerrer
0
140
Claude CodeによるAI駆動開発の実践 〜そこから見えてきたこれからのプログラミング〜
iriikeita
0
170
コードとあなたと私の距離 / The Distance Between Code, You, and I
hiro_y
0
160
Writing Better Go: Lessons from 10 Code Reviews
konradreiche
0
1.2k
Featured
See All Featured
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.1k
Writing Fast Ruby
sferik
629
62k
Testing 201, or: Great Expectations
jmmastey
45
7.7k
Build The Right Thing And Hit Your Dates
maggiecrowley
37
2.9k
Large-scale JavaScript Application Architecture
addyosmani
514
110k
Being A Developer After 40
akosma
91
590k
Building Applications with DynamoDB
mza
96
6.7k
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
Designing for Performance
lara
610
69k
Leading Effective Engineering Teams in the AI Era
addyosmani
3
380
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
20
1.2k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
30
2.9k
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?