{"title":"Création de fichiers PDF","version":"5.1","locale":"fr","docname":"howto/outputting-pdf","url":"/fr/5.1/howto/outputting-pdf/","canonical":"https://djangodocs.dev/fr/5.1/howto/outputting-pdf/","summary":"Ce document explique comment produire des fichiers PDF dynamiquement en utilisant des vues Django. C’est possible grâce à l’excellente bibliothèque Python libre…","html":"<h1>Création de fichiers PDF<a class=\"heading-anchor\" href=\"#how-to-create-pdf-files\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Ce document explique comment produire des fichiers PDF dynamiquement en utilisant des vues Django. C’est possible grâce à l’excellente bibliothèque Python libre <a class=\"reference external\" href=\"https://docs.reportlab.com/\">ReportLab</a>.</p>\n<p>L’avantage de générer des fichiers PDF dynamiquement est que vous pouvez créer des PDF personnalisés pour différents besoins, par exemple en fonction des utilisateurs ou de certaines parties de contenu.</p>\n<p>Par exemple, Django était utilisé chez <a class=\"reference external\" href=\"https://www2.kusports.com/\">kusports.com</a> pour générer des tableaux de tournois NCAA personnalisés et prêts pour l’impression, sous forme de fichiers PDF, pour les personnes participant au concours « March Madness ».</p>\n<section id=\"install-reportlab\">\n<h2>Installation de ReportLab<a class=\"heading-anchor\" href=\"#install-reportlab\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>La bibliothèque ReportLab est <a class=\"extlink-pypi reference external\" href=\"https://pypi.org/project/reportlab/\">disponible sur PyPI</a>. Un <a class=\"reference external\" href=\"https://www.reportlab.com/docs/reportlab-userguide.pdf\">manuel d’utilisation</a> (un fichier PDF, bien évidemment) est aussi disponible en téléchargement. Vous pouvez installer ReportLab avec <code class=\"docutils literal notranslate\"><span class=\"pre\">pip</span></code>:</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-0-unix-label\">Linux / macOS</p><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>python<span class=\"w\"> </span>-m<span class=\"w\"> </span>pip<span class=\"w\"> </span>install<span class=\"w\"> </span>reportlab\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-0-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</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=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> py -m pip install reportlab\n</code></pre></div></div></div>\n<p>Testez votre installation en l’important dans l’interpréteur interactif de Python :</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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=\"Python console 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>Si cette commande ne produit aucune erreur, l’installation a réussi.</p>\n</section>\n<section id=\"write-your-view\">\n<h2>Écriture de la vue<a class=\"heading-anchor\" href=\"#write-your-view\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>L’élément clé dans la génération dynamique de PDF avec Django est que l’API de ReportLab agit sur des objets de type fichier, et les objets <a class=\"reference internal\" href=\"/fr/5.1/ref/request-response/#django.http.FileResponse\" title=\"django.http.FileResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">FileResponse</span></code></a> de Django acceptent des objets de type fichier.</p>\n<p>Voici un exemple « 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\">import</span><span class=\"w\"> </span><span class=\"nn\">io</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\">FileResponse</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\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 a file-like buffer to receive PDF data.</span>\n    <span class=\"n\">buffer</span> <span class=\"o\">=</span> <span class=\"n\">io</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 buffer 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, 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\n    <span class=\"c1\"># FileResponse sets the Content-Disposition header so that browsers</span>\n    <span class=\"c1\"># present the option to save the file.</span>\n    <span class=\"n\">buffer</span><span class=\"o\">.</span><span class=\"n\">seek</span><span class=\"p\">(</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n    <span class=\"k\">return</span> <span class=\"n\">FileResponse</span><span class=\"p\">(</span><span class=\"n\">buffer</span><span class=\"p\">,</span> <span class=\"n\">as_attachment</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"n\">filename</span><span class=\"o\">=</span><span class=\"s2\">&quot;hello.pdf&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Le code et les commentaires sont assez explicites, mais certains points méritent un éclaircissement :</p>\n<ul class=\"simple\">\n<li><p>La réponse définit automatiquement le type MIME <em class=\"mimetype\">application/pdf</em> en se basant sur l’extension du nom de fichier. Ceci indique aux navigateurs que le document est un fichier PDF, et non pas un fichier HTML ou autre contenu binaire générique de type <em class=\"mimetype\">application/octet-stream</em>.</p></li>\n<li><p>Lorsque <code class=\"docutils literal notranslate\"><span class=\"pre\">as_attachment=True</span></code> est transmis à <code class=\"docutils literal notranslate\"><span class=\"pre\">FileResponse</span></code>, l’en-tête <code class=\"docutils literal notranslate\"><span class=\"pre\">Content-Disposition</span></code> est défini en conséquence et pousse les navigateurs Web à ouvrir une boîte de dialogue demandant comment gérer le document, même si un comportement par défaut est défini sur la machine. Si le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">as_attachment</span></code> est omis, les navigateurs gèrent directement le fichier PDF en utilisant le programme ou greffon qui aura été configuré pour les fichiers PDF.</p></li>\n<li><p>Vous pouvez indiquer le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">filename</span></code> de votre choix. Ce contenu sera utilisé dans les boîtes de dialoque <code class=\"docutils literal notranslate\"><span class=\"pre\">Enregistrer</span> <span class=\"pre\">sous…</span></code>.</p></li>\n<li><p>Il est possible de se brancher à l’API ReportLab : le même tampon transmis comme premier paramètre à <code class=\"docutils literal notranslate\"><span class=\"pre\">canvas.Canvas</span></code> peut être passé à la classe <a class=\"reference internal\" href=\"/fr/5.1/ref/request-response/#django.http.FileResponse\" title=\"django.http.FileResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">FileResponse</span></code></a>.</p></li>\n<li><p>Notez que toute méthode de génération PDF subséquente est appelée sur l’objet PDF (<code class=\"docutils literal notranslate\"><span class=\"pre\">p</span></code> dans ce cas), et non pas sur <code class=\"docutils literal notranslate\"><span class=\"pre\">buffer</span></code>.</p></li>\n<li><p>Finalement, il est important d’appeler <code class=\"docutils literal notranslate\"><span class=\"pre\">showPage()</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code> sur le fichier PDF.</p></li>\n</ul>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>ReportLab n’est pas « thread-safe ». Certains utilisateurs ont signalé des problèmes bizarres lorsque des vues Django de production de PDF sont simultanément appelées par beaucoup de monde.</p>\n</aside>\n</section>\n<section id=\"other-formats\">\n<h2>Autres formats<a class=\"heading-anchor\" href=\"#other-formats\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Vous constaterez que ces exemples ne contiennent pas beaucoup de code spécifique au format PDF, uniquement les parties utilisant <code class=\"docutils literal notranslate\"><span class=\"pre\">reportlab</span></code>. Vous pouvez donc employer des techniques semblables pour générer tout autre format pour lequel vous trouvez une bibliothèque Python. Consultez également <a class=\"reference internal\" href=\"/fr/5.1/howto/outputting-csv/\"><span class=\"doc\">Création de contenu CSV</span></a>, un autre exemple qui contient certaines techniques utilisables lors de la génération de formats basés sur du texte.</p>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">Voir aussi</p>\n<p>Le site Django Packages présente une <a class=\"reference external\" href=\"https://djangopackages.org/grids/g/pdf/\">comparaison de paquets</a> qui peuvent aider à produire des fichiers PDF avec Django.</p>\n</aside>\n</section>","rootId":"how-to-create-pdf-files","toc":[{"title":"Installation de ReportLab","anchor":"install-reportlab","children":[]},{"title":"Écriture de la vue","anchor":"write-your-view","children":[]},{"title":"Autres formats","anchor":"other-formats","children":[]}],"breadcrumbs":[{"docname":"howto/index","title":"Guides pratiques","url":"/fr/5.1/howto/"}],"prev":{"docname":"howto/outputting-csv","title":"Création de contenu CSV","url":"/fr/5.1/howto/outputting-csv/"},"next":{"docname":"howto/overriding-templates","title":"Surcharge des gabarits","url":"/fr/5.1/howto/overriding-templates/"},"formats":{"html":"/fr/5.1/howto/outputting-pdf/","markdown":"/fr/5.1/howto/outputting-pdf.md","json":"/fr/5.1/howto/outputting-pdf.json"},"source":"https://github.com/django/django/blob/stable/5.1.x/docs/howto/outputting-pdf.txt","official":"https://docs.djangoproject.com/fr/5.1/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","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}