{"title":"Gerando PDFs com o Django","version":"1.11","locale":"pt-br","docname":"howto/outputting-pdf","url":"/pt-br/1.11/howto/outputting-pdf/","canonical":"https://djangodocs.dev/pt-br/1.11/howto/outputting-pdf/","summary":"Este documnto explica como gerar arquivos PDF dinamicamente usando “views” Django. Isso é possível através da excelente, biblioteca Python de código-aberto…","html":"<h1>Gerando PDFs com o Django<a class=\"heading-anchor\" href=\"#outputting-pdfs-with-django\"><span class=\"visually-hidden\">Link para este cabeçalho</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Este documnto explica como gerar arquivos PDF dinamicamente usando “views” Django. Isso é possível através da excelente, biblioteca Python de código-aberto <a class=\"reference external\" href=\"http://www.reportlab.com/opensource/\">RepostLab</a> .</p>\n<p>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.</p>\n<p>Por exemplo, o DJango foi usado no <a class=\"reference external\" href=\"http://www.kusports.com/\">kusports.com</a> 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.</p>\n<section id=\"install-reportlab\">\n<h2>Instalar o ReportLab<a class=\"heading-anchor\" href=\"#install-reportlab\"><span class=\"visually-hidden\">Link para este cabeçalho</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>A biblioteca RepostLab está  disponível  <a class=\"reference external\" href=\"https://pypi.python.org/pypi/reportlab\">available on PyPI</a>. Um guia de usuário em <a class=\"reference external\" href=\"http://www.reportlab.com/docs/reportlab-userguide.pdf\">user guide</a> (não coincidentemente um arquivo PDF) está disponível para download. Você pode instalar o ReportLab com <code class=\"docutils literal notranslate\"><span class=\"pre\">pip</span></code>:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>pip<span class=\"w\"> </span>install<span class=\"w\"> </span>reportlab\n</code></pre></div>\n<p>Teste sua instalação importando no interpretador interativo Python:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">reportlab</span>\n</code></pre></div>\n<p>Se o comando não emitir nenhum erro, a instalação funciona.</p>\n</section>\n<section id=\"write-your-view\">\n<h2>Escreva sua “view”<a class=\"heading-anchor\" href=\"#write-your-view\"><span class=\"visually-hidden\">Link para este cabeçalho</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>A chave para gerar PDF dinamicamente com Django é que a API do ReportLab atua como um objeto “file-like”, e os <a class=\"reference internal\" href=\"/pt-br/1.11/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a> do Django são objetos “file-like”.</p>\n<p>Aqui um exemplo “Hello World”:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">reportlab.pdfgen</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">canvas</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">some_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Create the HttpResponse object with the appropriate PDF headers.</span>\n    <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"n\">content_type</span><span class=\"o\">=</span><span class=\"s1\">&#39;application/pdf&#39;</span><span class=\"p\">)</span>\n    <span class=\"n\">response</span><span class=\"p\">[</span><span class=\"s1\">&#39;Content-Disposition&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;attachment; filename=&quot;somefilename.pdf&quot;&#39;</span>\n\n    <span class=\"c1\"># Create the PDF object, using the response object as its &quot;file.&quot;</span>\n    <span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">canvas</span><span class=\"o\">.</span><span class=\"n\">Canvas</span><span class=\"p\">(</span><span class=\"n\">response</span><span class=\"p\">)</span>\n\n    <span class=\"c1\"># Draw things on the PDF. Here&#39;s where the PDF generation happens.</span>\n    <span class=\"c1\"># See the ReportLab documentation for the full list of functionality.</span>\n    <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">drawString</span><span class=\"p\">(</span><span class=\"mi\">100</span><span class=\"p\">,</span> <span class=\"mi\">100</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Hello world.&quot;</span><span class=\"p\">)</span>\n\n    <span class=\"c1\"># Close the PDF object cleanly, and we&#39;re done.</span>\n    <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">showPage</span><span class=\"p\">()</span>\n    <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n    <span class=\"k\">return</span> <span class=\"n\">response</span>\n</code></pre></div>\n<p>O código e comentário devem ser auto-explanaveis, mas algumas coisas merecem uma menção.</p>\n<ul>\n<li><p>A resposta HTTP tem um tipo MIME especial, <em class=\"mimetype\">application/pdf</em>. Isso indica ao browser que o documento é um arquivo PDF, ao invés de arquivo HTML. Se deixar isso de fora, o browser provavelmente irá interpretar o ontúdo como HTML, o qual deve resultar em uma feia, assustadora “sopa de ltrinhas” no browser.</p></li>\n<li><p>A resposta HTTP também tem um cabeçalho adicional  <code class=\"docutils literal notranslate\"><span class=\"pre\">Content-Disposition</span></code>, o qual contém o nome do arquivo PDF. Este nome de arquivo é arbitrário: Chame como quizer. Isso será usado pelo browser na caixa de diálogo “Salvar como…”, etc.</p></li>\n<li><p>O cabeçalho HTTP <code class=\"docutils literal notranslate\"><span class=\"pre\">Content-Disposition</span></code> começa com <code class=\"docutils literal notranslate\"><span class=\"pre\">attachment;</span></code> neste exemplo. Isso força o browser a mostrar uma caixa de diálogo perguntando/confirmando como manipular o documento mesmo que exista um padrão definido no computador. Se deixar sem o <code class=\"docutils literal notranslate\"><span class=\"pre\">'attachment;'</span></code>, os browsers usarão qualquer programa/plugin que estejam configurados para usar com PDF. Aqui como o código se parece:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">response</span><span class=\"p\">[</span><span class=\"s1\">&#39;Content-Disposition&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;filename=&quot;somefilename.pdf&quot;&#39;</span>\n</code></pre></div>\n</li>\n<li><p>Acessar a API do ReportLab é fácil: apenas passe o <code class=\"docutils literal notranslate\"><span class=\"pre\">response</span></code> como primeiro argumento para <code class=\"docutils literal notranslate\"><span class=\"pre\">canvas.Canvas`.</span> <span class=\"pre\">A</span> <span class=\"pre\">classe</span> <span class=\"pre\">``Canvas</span></code> espera um objeto “file-like”, e os objetos <a class=\"reference internal\" href=\"/pt-br/1.11/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a> se encaixam na definição.</p></li>\n<li><p>Note que todos os métodos subsequentes para geração do PDF são chamados  a partir do objeto (neste caso , <code class=\"docutils literal notranslate\"><span class=\"pre\">p</span></code>) – e não do <code class=\"docutils literal notranslate\"><span class=\"pre\">response</span></code>.</p></li>\n<li><p>E finalmente, é importante chamar <code class=\"docutils literal notranslate\"><span class=\"pre\">showPage()</span></code> e o  <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code> no arquivo PDF.</p></li>\n</ul>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Nota</p>\n<p>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.</p>\n</aside>\n</section>\n<section id=\"complex-pdfs\">\n<h2>PDFs complexos<a class=\"heading-anchor\" href=\"#complex-pdfs\"><span class=\"visually-hidden\">Link para este cabeçalho</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Se estiver contruindo documentos PDFs complexos com o ReportLab, considere usar a bilioteca <a class=\"reference external\" href=\"https://docs.python.org/3/library/io.html#module-io\" title=\"(em Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">io</span></code></a> como um lucar temporário de armazenamento do seu arquivo PDF. Essa biblioteca fornece uma  objeto “file-like” como interface que é particularmente eficiente. Aqui o mesmo exemplo “Hello World” de antes, reescrito com uso do <a class=\"reference external\" href=\"https://docs.python.org/3/library/io.html#module-io\" title=\"(em Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">io</span></code></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">io</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BytesIO</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">reportlab.pdfgen</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">canvas</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">some_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Create the HttpResponse object with the appropriate PDF headers.</span>\n    <span class=\"n\">response</span> <span class=\"o\">=</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"n\">content_type</span><span class=\"o\">=</span><span class=\"s1\">&#39;application/pdf&#39;</span><span class=\"p\">)</span>\n    <span class=\"n\">response</span><span class=\"p\">[</span><span class=\"s1\">&#39;Content-Disposition&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;attachment; filename=&quot;somefilename.pdf&quot;&#39;</span>\n\n    <span class=\"n\">buffer</span> <span class=\"o\">=</span> <span class=\"n\">BytesIO</span><span class=\"p\">()</span>\n\n    <span class=\"c1\"># Create the PDF object, using the BytesIO object as its &quot;file.&quot;</span>\n    <span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">canvas</span><span class=\"o\">.</span><span class=\"n\">Canvas</span><span class=\"p\">(</span><span class=\"n\">buffer</span><span class=\"p\">)</span>\n\n    <span class=\"c1\"># Draw things on the PDF. Here&#39;s where the PDF generation happens.</span>\n    <span class=\"c1\"># See the ReportLab documentation for the full list of functionality.</span>\n    <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">drawString</span><span class=\"p\">(</span><span class=\"mi\">100</span><span class=\"p\">,</span> <span class=\"mi\">100</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Hello world.&quot;</span><span class=\"p\">)</span>\n\n    <span class=\"c1\"># Close the PDF object cleanly.</span>\n    <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">showPage</span><span class=\"p\">()</span>\n    <span class=\"n\">p</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n\n    <span class=\"c1\"># Get the value of the BytesIO buffer and write it to the response.</span>\n    <span class=\"n\">pdf</span> <span class=\"o\">=</span> <span class=\"n\">buffer</span><span class=\"o\">.</span><span class=\"n\">getvalue</span><span class=\"p\">()</span>\n    <span class=\"n\">buffer</span><span class=\"o\">.</span><span class=\"n\">close</span><span class=\"p\">()</span>\n    <span class=\"n\">response</span><span class=\"o\">.</span><span class=\"n\">write</span><span class=\"p\">(</span><span class=\"n\">pdf</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">response</span>\n</code></pre></div>\n</section>\n<section id=\"other-formats\">\n<h2>Outros formatos<a class=\"heading-anchor\" href=\"#other-formats\"><span class=\"visually-hidden\">Link para este cabeçalho</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Note que não tem muito nestes exemplos que seja especificamente sobre PDF – apenas as partes usando <code class=\"docutils literal notranslate\"><span class=\"pre\">reportlab</span></code>. Você pode usar técnicas similares para gerar qualquer outro formato arbitrário para a qual você encontre uma bilioteca Python. Veja também <a class=\"reference internal\" href=\"/pt-br/1.11/howto/outputting-csv/\"><span class=\"doc\">Emitindo CSV com Django</span></a> para outro exemplo e algumas técnicas que você pode usar quando quiser gerar fomatos baseados em texto.</p>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">Ver também</p>\n<p>O Django Packages fornece uma ferramenta para <a class=\"reference external\" href=\"https://djangopackages.org/grids/g/pdf/\">comparação de pacotes</a> que auxiliam a geração de arquivos PDF com o Django</p>\n</aside>\n</section>","rootId":"outputting-pdfs-with-django","toc":[{"title":"Instalar o ReportLab","anchor":"install-reportlab","children":[]},{"title":"Escreva sua “view”","anchor":"write-your-view","children":[]},{"title":"PDFs complexos","anchor":"complex-pdfs","children":[]},{"title":"Outros formatos","anchor":"other-formats","children":[]}],"breadcrumbs":[{"docname":"howto/index","title":"Guias de “como fazer”","url":"/pt-br/1.11/howto/"}],"prev":{"docname":"howto/outputting-csv","title":"Emitindo CSV com Django","url":"/pt-br/1.11/howto/outputting-csv/"},"next":{"docname":"howto/overriding-templates","title":"Sobrescrevendo templates","url":"/pt-br/1.11/howto/overriding-templates/"},"formats":{"html":"/pt-br/1.11/howto/outputting-pdf/","markdown":"/pt-br/1.11/howto/outputting-pdf.md","json":"/pt-br/1.11/howto/outputting-pdf.json"},"source":"https://github.com/django/django/blob/stable/1.11.x/docs/howto/outputting-pdf.txt","official":"https://docs.djangoproject.com/pt-br/1.11/howto/outputting-pdf/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","fr","ja","id","pt-br","ko","es","el","pl"]}