pdf file doesn't save in Django - python

I use Django 2.1.4 and use Django sample for create pdf report
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.
return FileResponse(buffer, as_attachment=True, filename='hello.pdf')
It started dowloaded but never finished. What is wrong?
Old version works properly
def some_view(request):
# Create the HttpResponse object with the appropriate PDF headers.
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="somefilename.pdf"'
# Create the PDF object, using the response object as its "file."
p = canvas.Canvas(response)
# 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()
return response

I would look at this example (except for the queryset),, see if that works, similar worked for me earlier today, How can i display my data in database and export it to pdf -Django
Get the value of the BytesIO buffer and write it to the response.
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="WishList.pdf"'
from reportlab.pdfgen import canvas
buffer = BytesIO()
p = canvas.Canvas(buffer)
p.drawString(100, 100, "Hello world.")
p.showPage()
p.save()
pdf = buffer.getvalue()
buffer.close()
response.write(pdf)
return response

Believe it or not, the old version is the way I recommend that you do it. To get this working with a FileResponse, try the below:
# FileResponse sets the Content-Disposition header so that browsers
# present the option to save the file.
response = FileResponse(buffer, as_attachment=True, filename='hello.pdf', content_type='application/pdf')
# set the content length to let the browser know how many bytes to expect
response['Content-Length'] = bugger.getbuffer().nbytes
return response

Related

Django : Downloading PDF object generated by the library FPDF

I have a view that contains a wizard form. When the form is submitted, a httpresponse is sent with a PDF file. I generate the PDF file with the FPDF2 Library from the data got in the form submitted by the user.
To be sure that the PDF class using this library works, I tested it in a simple python script.
EDITED
My problem comes from the pdf that I download, I can not open it because no data is stored in it. I open it with the "Note" software and there is just an "None" written inside.
So how can I send the data of the pdf object to the Httpresponse ?
Here is my code :
class FormWizardQR(SessionWizardView):
template_name = "invoices/qr.html"
form_list = [FormStepOneBeneficiary, FormStepTwoPaymentInfos, FormStepThreeDebtor]
def done(self, form_list, **kwargs):
# GET DATA FROM FORMS
form_data = dict(ChainMap(*[form.cleaned_data for form in form_list]))
# PREPARE DATA FOR QR-PDF GENERATOR
list_str_pay_to = []
list_str_pay_by = []
reference = form_data.get('ref_number')
pdf = PDF('portrait', 'mm', 'A4')
pdf.set_margins(left=0, top=0, right=0)
pdf.add_page()
pdf.border_bill()
pdf.r_title("Récépissé")
pdf.r_zone_indications(reference=reference, list_str_pay_to=list_str_pay_to, list_str_pay_by=list_str_pay_by)
pdf.output(name="myfilename.pdf", dest="S")
print(type(pdf))
print(pdf)
response = HttpResponse(pdf, content_type='application/pdf')
response['Content-Disposition'] = "attachment; filename=myfilename.pdf"
return response
Thank you
According to the documentation of the last version of pyFPDF2 (version 2.5.7) : https://pyfpdf.github.io/fpdf2/fpdf/fpdf.html#fpdf.fpdf.FPDF.output
The dest is DEPRECATED and "By default the bytearray buffer is returned. If a name is given, the PDF is written to a new file."
So it just needs :
response = HttpResponse(bytes(pdf.output()), content_type='application/pdf')
response['Content-Disposition'] = "attachment; filename=myfilename.pdf"
return response

How can i display my data in database and export it to pdf -Django

my x variable is getting all the data in my database, i guess? someone help me how can i display all data and export it to pdf file.
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="WishList.pdf"'
buffer = BytesIO()
# Create the PDF object, using the BytesIO object as its "file."
p = canvas.Canvas(buffer)
x = Item.objects.all()
p.drawString(100, 100,x)
p.drawString(200,300,"sad")
# Close the PDF object cleanly.
p.showPage()
p.save()
# Get the value of the BytesIO buffer and write it to the response.
pdf = buffer.getvalue()
buffer.close()
response.write(pdf)
return response
Your variable x won't return anything you can print into the PDF, because its a queryset and not a couple strings attached to each other. I just started working with Django and getting the values works something like this:
x = Item.objects.all[0].name
This code snippet will assign the vale of the row name of the first entry in your Item table to the variable x.
For more Information I can only recommend reading the Tutorial about writing queries on the django website.

Modyfing pdf and returning it as a django response

I need to modify the existing pdf and return it as a response in Django. So far, I have found this solution to modify the file:
def some_view(request):
# Create the HttpResponse object with the appropriate PDF headers.
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment;filename="somefilename.pdf"'
packet = StringIO.StringIO()
# create a new PDF with Reportlab
can = canvas.Canvas(packet, pagesize=letter)
##################### 1. First and last name
first_last_name = "Barney Stinson"
can.drawString(63, 686, first_last_name)
#Saving
can.save()
#move to the beginning of the StringIO buffer
packet.seek(0)
new_pdf = PdfFileReader(packet)
# read your existing PDF
existing_pdf = PdfFileReader(file("fw9.pdf", "rb"))
output = PdfFileWriter()
# add the "watermark" (which is the new pdf) on the existing page
page = existing_pdf.getPage(0)
page.mergePage(new_pdf.getPage(0))
output.addPage(page)
# finally, write "output" to a real file
#outputStream = file("output.pdf", "wb")
#output.write(outputStream)
response.write(output)
outputStream.close()
return response
It let's me download the pdf, but when I am trying to open it, I get the message, that the file is damaged or wasn't correctly decoded.
Does anyone know what am I don't wrong?
Thank you!
You can write the output PDF to the response object. So instead of this:
response.write(output)
do this:
output.write(response)
This will write the contents of the PDF to the response instead of the string version of the output object which would be something like:
<PyPDF2.pdf.PdfFileWriter object at 0x7f0e801ea090>
which is what you will find in the downloaded PDF file.

How to fill PDF form in Django/Python?

I'm trying to fill pre-made pdf form with database data and flatten it. For example, if the user inputs a field called "name", it should be placed in the name field of the pdf form.
You can use reportlab library in combination with Django views :
from io import BytesIO
from reportlab.pdfgen import canvas
from django.http import HttpResponse
def some_view(request):
# Create the HttpResponse object with the appropriate PDF headers.
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="somefilename.pdf"'
buffer = BytesIO()
# Create the PDF object, using the BytesIO object 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.
p.showPage()
p.save()
# Get the value of the BytesIO buffer and write it to the response.
pdf = buffer.getvalue()
buffer.close()
response.write(pdf)
return response
Django documentation : https://docs.djangoproject.com/en/1.9/howto/outputting-pdf/
Reportlab documentation : http://www.reportlab.com/documentation/

Django Change File name in PDF export

I found this handy code in the Django Docs:
from reportlab.pdfgen import canvas
from django.http import HttpResponse
def some_view(request):
# Create the HttpResponse object with the appropriate PDF headers.
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="somefilename.pdf"'
# Create the PDF object, using the response object as its "file."
p = canvas.Canvas(response)
# 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()
return response
I would like to pass a variable to the function as variable name, but cannot figure it out (though I am sure it is super easy).
Anyone have an idea?
Thanks so much!
filename="somefilename.pdf" there is place where you can determine your filename.
You can use it as:
filename = 'somefilename.pdf'
response['Content-Disposition'] = 'attachment; filename="{}"'.format(filename)
Hope it might helps you:
Add one more argument named "name" to the view "some_view" and replace the filename with the argument value.
def hello_pdf(request, name):
# Create the HttpResponse object with the appropriate PDF headers.
response = HttpResponse(mimetype='application/pdf')
response['Content-Disposition'] = 'attachment; filename=%s.pdf'% name
temp = StringIO()
# Create the PDF object, using the StringIO object as its "file."
p = canvas.Canvas(temp)
# 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.
p.showPage()
p.save()
# Get the value of the StringIO buffer and write it to the response.
response.write(temp.getvalue())
return response
Check the name argument replacing the filename in the 4th line of code. Also don't forget to update the urls.py like below:
url(r'^(?P<name>\w+)/$', 'app.some_view')
After all pass the filename you wish to replace with url like below:
http://yourwebsite.com/name-of-file/
If you want to force viewing the PDF in browser with given filename but without automatic download, you can use "inline" instead of "attachment":
response["Content-Disposition"] = f'inline; filename="{file_name}"'

Categories