{"title":"Εξάγοντας αρχεία PDF με το Django","version":"2.0","locale":"el","docname":"howto/outputting-pdf","url":"/el/2.0/howto/outputting-pdf/","canonical":"https://djangodocs.dev/el/2.0/howto/outputting-pdf/","summary":"Αυτό το άρθρο εξηγεί πως να εξάγετε αρχεία PDF, δυναμικά, χρησιμοποιώντας τα Django views. Αυτό είναι εφικτό, με τη χρήση της εξαιρετικής, ανοιχτού λογισμικου PDF…","html":"<h1>Εξάγοντας αρχεία PDF με το Django<a class=\"heading-anchor\" href=\"#outputting-pdfs-with-django\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Αυτό το άρθρο εξηγεί πως να εξάγετε αρχεία PDF, δυναμικά, χρησιμοποιώντας τα Django views. Αυτό είναι εφικτό, με τη χρήση της εξαιρετικής, ανοιχτού λογισμικου PDF βιβλιοθήκης της Python, <a class=\"reference external\" href=\"https://www.reportlab.com/opensource/\">ReportLab</a>.</p>\n<p>Το πλεονέκτημα της παραγωγής δυναμικών αρχείων PDF είναι ότι μπορείτε να δημιουργείτε παραμετροποιήσιμα PDFs για διαφορετικούς σκοπούς – πχ, για διαφορετικούς χρήστες ή διαφορετικά κομμάτια δεδομένων.</p>\n<p>Για παράδειγμα, το Django χρησιμοποιήθηκε στο <a class=\"reference external\" href=\"http://www.kusports.com/\">kusports.com</a> για να παράγει παραμετροποιήσιμα, φιλικά προς εκτύπωση αποτελέσματα αγώνων μπάσκετ (NCAA tournament brackets), ως αρχεία PDF, για αυτούς που συμμετέχουν στον διαγωνισμό March Madness.</p>\n<section id=\"install-reportlab\">\n<h2>Εγκατάσταση της βιβλιοθήκης ReportLab<a class=\"heading-anchor\" href=\"#install-reportlab\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Η βιβλιοθήκη ReportLab είναι <a class=\"reference external\" href=\"https://pypi.python.org/pypi/reportlab\">διαθέσιμη στο PyPI</a>. Ένας <a class=\"reference external\" href=\"http://www.reportlab.com/docs/reportlab-userguide.pdf\">οδηγός χρήστη</a> (όχι τυχαία, ένα PDF αρχείο) είναι επίσης διαθέσιμο για download. Μπορείτε να εγκαταστήσετε το ReportLab με το <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>Ελέγξτε την εγκατάσταση της βιβλιοθήκης κάνοντας την import στο Python interactive shell σας (αν την έχετε εγκαταστήσει globally, τότε σε κονσόλα γράψτε πρώτα <code class=\"docutils literal notranslate\"><span class=\"pre\">python</span></code> ή <code class=\"docutils literal notranslate\"><span class=\"pre\">python3.x</span></code> όπου <code class=\"docutils literal notranslate\"><span class=\"pre\">x</span></code> η έκδοση 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>Αν αυτό δεν σας εμφανίσει κάποιο σφάλμα, η βιβλιοθήκη έχει εγκατασταθεί επιτυχώς.</p>\n</section>\n<section id=\"write-your-view\">\n<h2>Γράψτε το view<a class=\"heading-anchor\" href=\"#write-your-view\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Το κλειδί για να παράγετε PDFs δυναμικά με το Django είναι ότι το ReportLab API ενεργεί σε objects που μοιάζουν με αρχεία και τα objects της κλάσης <a class=\"reference internal\" href=\"/el/2.0/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> του Django μοιάζουν με αρχεία.</p>\n<p>Εδώ φαίνεται το κλασικό παράδειγμα «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\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</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<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>Παρόλο που ο κώδικας και τα σχόλια είναι αρκετά επεξηγηματικά, θα πρέπει να αναφέρουμε μερικά πράγματα:</p>\n<ul>\n<li><p>Το response παίρνει έναν ειδικό τύπο MIME, <em class=\"mimetype\">application/pdf</em>. Αυτό λέει στους browsers ότι το έγγραφο είναι ένα PDF αρχείο, αντί ένα HTML αρχείο. Αν δεν το προσδιορίσετε, οι browsers θα ερμηνεύσουν την έξοδο ως HTML, που σημαίνει ότι όχι μόνο η έξοδος θα είναι άσχημη αλλά δεν θα καταλαβαίνετε τίποτα!</p></li>\n<li><p>Το response παίρνει ένα επιπλέον header με το όνομα <code class=\"docutils literal notranslate\"><span class=\"pre\">Content-Disposition</span></code>, ο οποίος περιέχει το όνομα του αρχείου PDF. Το όνομα αυτό είναι αυθαίρετο: Μπορείτε να το ονομάσετε όπως εσείς θέλετε. Θα χρησιμοποιηθεί από τους browsers στο παράθυρο διαλόγου «Αποθήκευση ως…» κλπ.</p></li>\n<li><p>Σε αυτό το παράδειγμα, ο header <code class=\"docutils literal notranslate\"><span class=\"pre\">Content-Disposition</span></code> ξεκινά με τη λέξη <code class=\"docutils literal notranslate\"><span class=\"pre\">'attachment;</span> <span class=\"pre\">'</span></code>. Αυτό αναγκάζει τους Web browsers να εμφανίσουν ένα pop-up παράθυρο διαλόγου ρωτώντας τον χρήστη πως να χειριστεί το έγγραφο ακόμη και αν μια προεπιλεγμένη ενέργεια είναι ρυθμισμένη στον browser. Αν το παραλείψετε αυτό, οι browsers θα χειριστούν το PDF χρησιμοποιώντας οποιοδήποτε πρόγραμμα/plugin είναι ρυθμισμένοι να χρησιμοποιούν όταν έρχονται αντιμέτωποι με τέτοιου είδους αρχεία. Ο κώδικας θα φαίνεται κάπως έτσι:</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>Η επικοινωνία με το ReportLab API είναι εύκολη: Απλώς περάστε το <code class=\"docutils literal notranslate\"><span class=\"pre\">response</span></code> ως πρώτο όρισμα στην κλάση <code class=\"docutils literal notranslate\"><span class=\"pre\">canvas.Canvas</span></code>. Η κλάση <code class=\"docutils literal notranslate\"><span class=\"pre\">Canvas</span></code> περιμένει ένα object που μοιάζει με αρχείο και τα objects της κλάσης <a class=\"reference internal\" href=\"/el/2.0/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> ταιριάζουν ακριβώς με την περιγραφή.</p></li>\n<li><p>Σημειώστε ότι όλες οι ακόλουθες μέθοδοι που δημιουργούν PDF, καλούνται πάνω στο PDF object (σε αυτή την περίπτωση, στο <code class=\"docutils literal notranslate\"><span class=\"pre\">p</span></code>) – όχι πάνω στο <code class=\"docutils literal notranslate\"><span class=\"pre\">response</span></code>.</p></li>\n<li><p>Στο τέλος είναι σημαντικό να καλέσετε τις μεθόδους <code class=\"docutils literal notranslate\"><span class=\"pre\">showPage()</span></code> και <code class=\"docutils literal notranslate\"><span class=\"pre\">save()</span></code> στο PDF object.</p></li>\n</ul>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Σημείωση</p>\n<p>Η βιβλιοθήκη ReportLab δεν είναι ασφαλής από πολλαπλά threads. Μερικοί από τους χρήστες ανέφεραν κάποια περίεργα προβλήματα όταν πολλοί χρήστες είχαν πρόσβαση, ταυτόχρονα, στα Django views που χρησιμοποιούνταν για να παράξουν PDF αρχεία.</p>\n</aside>\n</section>\n<section id=\"complex-pdfs\">\n<h2>Περίπλοκα PDFs<a class=\"heading-anchor\" href=\"#complex-pdfs\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Αν δημιουργείτε ένα περίπλοκο έγγραφο PDF με το ReportLab, σκεφτείτε να χρησιμοποιήσετε τη βιβλιοθήκη <a class=\"reference external\" href=\"https://docs.python.org/3/library/io.html#module-io\" title=\"(στη Python έκδοση 3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">io</span></code></a> ως ένα προσωρινό μέρος για να κρατάτε το PDF αρχείο σας. Αυτή η βιβλιοθήκη παρέχει ένα interface που μοιάζει με file object το οποίο είναι ιδιαίτερα αποδοτικό. Παρακάτω φαίνεται το παράδειγμα «Hello World» χρησιμοποιώντας, αυτή τη φορά, τη βιβλιοθήκη <a class=\"reference external\" href=\"https://docs.python.org/3/library/io.html#module-io\" title=\"(στη Python έκδοση 3.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>Άλλες μορφές τύπου κειμένου<a class=\"heading-anchor\" href=\"#other-formats\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Όπως είδατε, δεν υπάρχει κάτι συγκεκριμένο με το PDF εδώ – μόνο τα κομμάτια που χρησιμοποιούν τη βιβλιοθήκη <code class=\"docutils literal notranslate\"><span class=\"pre\">reportlab</span></code>. Μπορείτε να χρησιμοποιήσετε κάποια παρόμοια τεχνική για να εξάγετε οποιαδήποτε μορφή τύπου κειμένου, αρκεί να υπάρχει μια Python βιβλιοθήκη που να την υποστηρίζει. Δείτε στο άρθρο <a class=\"reference internal\" href=\"/el/2.0/howto/outputting-csv/\"><span class=\"doc\">εξάγοντας αρχεία CSV με το Django</span></a> για ένα άλλο παράδειγμα και μερικές τεχνικές που μπορείτε να χρησιμοποιήσετε όταν παράγετε αρχεία με μορφή τύπου κειμένου.</p>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">Δείτε επίσης</p>\n<p>Τα Django Packages παρέχουν <a class=\"reference external\" href=\"https://djangopackages.org/grids/g/pdf/\">συγκριτικό πίνακα μεταξύ των πακέτων</a> ο οποίος βοηθά στη δημιουργία PDF αρχείων από το Django.</p>\n</aside>\n</section>","rootId":"outputting-pdfs-with-django","toc":[{"title":"Εγκατάσταση της βιβλιοθήκης ReportLab","anchor":"install-reportlab","children":[]},{"title":"Γράψτε το view","anchor":"write-your-view","children":[]},{"title":"Περίπλοκα PDFs","anchor":"complex-pdfs","children":[]},{"title":"Άλλες μορφές τύπου κειμένου","anchor":"other-formats","children":[]}],"breadcrumbs":[{"docname":"howto/index","title":"Οδηγοί «Πως-να»","url":"/el/2.0/howto/"}],"prev":{"docname":"howto/outputting-csv","title":"Εξάγοντας αρχεία CSV με το Django","url":"/el/2.0/howto/outputting-csv/"},"next":{"docname":"howto/overriding-templates","title":"Overriding templates","url":"/el/2.0/howto/overriding-templates/"},"formats":{"html":"/el/2.0/howto/outputting-pdf/","markdown":"/el/2.0/howto/outputting-pdf.md","json":"/el/2.0/howto/outputting-pdf.json"},"source":"https://github.com/django/django/blob/stable/2.0.x/docs/howto/outputting-pdf.txt","official":"https://docs.djangoproject.com/el/2.0/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"],"inLocales":["en","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}