Gerando PDFs com o Django¶
Este documnto explica como gerar arquivos PDF dinamicamente usando “views” Django. Isso é possível através da excelente, biblioteca Python de código-aberto RepostLab .
A vantagem de gerar arquivos PDF dinamicamente é que você pode criar PDFs personalizados para diferentes propósitos – vamos dizer, para diferentes usuários ou diferentes partes de conteúdo.
Por exemplo, o DJango foi usado no kusports.com para gerar relatórios personalizados, prontos para impressão, de pontuação de torneio da NCAA, como arquivos PDF, para pessoas que participam do concurso March Madness.
Instalar o ReportLab¶
A biblioteca RepostLab está disponível available on PyPI. Um guia de usuário em user guide (não coincidentemente um arquivo PDF) está disponível para download. Você pode instalar o ReportLab com pip
:
$ pip install reportlab
...\> pip install reportlab
Teste sua instalação importando no interpretador interativo Python:
>>> import reportlab
Se o comando não emitir nenhum erro, a instalação funciona.
Escreva sua “view”¶
A chave para gerar PDFs dinamicamente com Django é que a API do ReportLab atua em objetos tipo arquivo, e objetos da classe do Django FileResponse
aceitam objetivos tipo arquivo.
Aqui um exemplo “Hello World”:
import io
from django.http import FileResponse
from reportlab.pdfgen import canvas
def some_view(request):
# Create a file-like buffer to receive PDF data.
buffer = io.BytesIO()
# Create the PDF object, using the buffer as its "file."
p = canvas.Canvas(buffer)
# Draw things on the PDF. Here's where the PDF generation happens.
# See the ReportLab documentation for the full list of functionality.
p.drawString(100, 100, "Hello world.")
# Close the PDF object cleanly, and we're done.
p.showPage()
p.save()
# FileResponse sets the Content-Disposition header so that browsers
# present the option to save the file.
buffer.seek(0)
return FileResponse(buffer, as_attachment=True, filename='hello.pdf')
O código e comentário devem ser auto-explanaveis, mas algumas coisas merecem uma menção.
- A resposta HTTP irá automaticamente definir o tipo MIME application/pdf baseado na extensão do nome do arquivo. Isso diz aos navegadores que o documento é do tipo PDF, ao invés de um arquivo HTML ou um conteúdo binário genérico application/octet-stream.
- Quando
as_attachment=True
é passado paraFileResponse
, ele define o cabeçalho HTTPContent-Disposition
apropriado e isso informa aos navegadores para abrir uma caixa de diálogo perguntando/confirmando como lidar com o documento, mesmo que o padrão esteja definido para a sua máquina. Se o parâmetroas_attachement
for omitido, os navegadores irão lidar com PDF usando qualquer programa ou plugin que esteja configurado para usar com PDFs. - Você pode fornecer um parâmetro
filename
arbitrário. Ele será usado para os navegadores na caixa de diálogo “Salvar como…”. - Acessar a API do ReportLab é fácil: O mesmo buffer passado como primeiro argumento para
canvas.Canvas
pode ser passado para a classe classeFileResponse
. - Note que todas os methods de geração de PDF subsequentes são chamados no objeto PDF (nesse caso,
p
) – não nobuffer
. - E finalmente, é importante chamar
showPage()
e osave()
no arquivo PDF.
Nota
O ReposrtLab não tem mecanismos de segurança para ser usado de maneira concorrente, ou não é thread-safe. Alguns de nossos usuários tem relatado problemas ímpares ao gerar PDF em “views” Django que são acessadas por muitos usuários ao mesmo tempo.
Outros formatos¶
Note que não tem muito nestes exemplos que seja especificamente sobre PDF – apenas as partes usando reportlab
. Você pode usar técnicas similares para gerar qualquer outro formato arbitrário para a qual você encontre uma bilioteca Python. Veja também Emitindo CSV com Django para outro exemplo e algumas técnicas que você pode usar quando quiser gerar fomatos baseados em texto.
Ver também
O Django Packages fornece uma ferramenta para comparação de pacotes que auxiliam a geração de arquivos PDF com o Django