I am trying to make pdf in Django
from xhtml2pdf import pisa
from django.http import HttpResponse
from django.template.loader import get_template
from django.template import Context
from rest_framework.views import APIView
from .models import Brand
class ABCView(APIView):
def post(self, request,format=None):
report = Brand.objects.all()
template_path = 'profile_brand_report.html'
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="Report.pdf"'
context = {'report': report}
template = get_template(template_path)
html = template.render(Context(context))
print (html)
pisaStatus = pisa.CreatePDF(html, dest=response)
return response
but I am getting an unexpected error I don't know what I am doing wrong, I am getting this error
argument of type 'Context' is not iterable
or is there any other way to do it .thanks for help in advance
We don't need to use a class based view for it. For simplicity we can use a function based view. Change your code as below.
from django.template.loader import render_to_string
def generate_pdf(request):
report = Brand.objects.all()
template_path = 'profile_brand_report.html'
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="Report.pdf"'
html = render_to_string(template_path, {'report': report})
print (html)
pisaStatus = pisa.CreatePDF(html, dest=response)
return response
We can also use wkhtmltopdf to generate PDF's in django.
Read: https://learnbatta.com/blog/django-html-to-pdf-using-pdfkit-and-wkhtmltopdf-5/
Related
I'm working on Django blog and I want to export posts and I made it work but I have a problem when exporting text because I used Quill - rich text editor and Django Import Export
body = QuillField()
And when I export posts in excel, I got this <django_quill.fields.FieldQuill object at 0x7f0746389840>.
excel is looking like this,
image
This is resources.py
from import_export import resources
from .models import Post
class PostResource(resources.ModelResource):
class Meta:
model = Post
This is views.py
def export_data(request):
if request.method == 'POST':
# Get selected option from form
file_format = request.POST['file-format']
post_resource = PostResource()
dataset = post_resource.export()
if file_format == 'CSV':
response = HttpResponse(dataset.csv, content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="exported_data.csv"'
return response
elif file_format == 'JSON':
response = HttpResponse(dataset.json, content_type='application/json')
response['Content-Disposition'] = 'attachment; filename="exported_data.json"'
return response
elif file_format == 'XLS (Excel)':
response = HttpResponse(dataset.xls, content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename="exported_data.xls"'
return response
return render(request, 'dashboard/export.html')
Any idea how to get the text in this body column?
Thanks in advance!
You have to get the content from the quill object Post.body.html or Post.body.html
Try something like this
from import_export import resources
from import_export.fields import Field
from .models import Post
class PostResource(resources.ModelResource):
body = Field()
class Meta:
model = Post
def dehydrate_body(self,post):
body_content = post.body.html
return body_content
See docs : https://django-import-export.readthedocs.io/en/stable/getting_started.html#advanced-data-manipulation-on-export
and Django Quill Editor Display Saved Field
I'm trying to retrive data from database which was entered by user and result will be in a pdf file but unfortunately not succeeded. can any one help me..
this is my first time asking question on stackoverflow , even i have tried to add my code it showing some error.
code is in comments
model.py
class Doners(models.Model):
name = models.CharField(max_length=100)
desc = models.CharField(max_length=100)
view.py
def donateddetails(request,*args, **kwargs):
data = {
'name' : {{Doners.name}},
'desc' : {{Doners.desc}}
}
pdf = render_to_pdf('donateddetails.html', data)
return HttpResponse(pdf, content_type='application/pdf')
utils.py
from io import BytesIO
from django.http import HttpResponse
from django.template.loader import get_template
from xhtml2pdf import pisa
def render_to_pdf(template_src, context_dict={}):
template = get_template(template_src)
html = template.render(context_dict)
result = BytesIO()
pdf = pisa.pisaDocument(BytesIO(html.encode("ISO-8859-1")), result)
if not pdf.err:
return HttpResponse(result.getvalue(),
content_type='application/pdf')
return None
Here is a supposed solution I have found. https://stackoverflow.com/a/2180417
I am trying to implement it but I am not able to do so.
Here is my current code:
utils.py
from io import BytesIO
from django.http import HttpResponse
from django.template.loader import get_template
from xhtml2pdf import pisa
def render_to_pdf(template_src, context_dict={}):
template = get_template(template_src)
html = template.render(context_dict)
result = BytesIO()
pdf = pisa.pisaDocument(BytesIO(html.encode("ISO-8859-1")), result, link_callback=fetch_resources)
if not pdf.err:
return HttpResponse(result.getvalue(), content_type='application/pdf')
return None
def fetch_resources(uri, rel):
path = os.path.join(settings.MEDIA_ROOT, uri.replace(settings.MEDIA_URL, ""))
return path
views.py
from django.http import HttpResponse
from django.views.generic import View
from yourproject.utils import render_to_pdf #created in step 4
class GeneratePdf(View):
def get(self, request, *args, **kwargs):
data = {
'today': datetime.date.today(),
'amount': 39.99,
'customer_name': 'Cooper Mann',
'order_id': 1233434,
}
pdf = render_to_pdf('pdf/invoice.html', data)
return HttpResponse(pdf, content_type='application/pdf')
Everything loads correctly if I just render a normal template so I know the problem is with this part of the process. The invoice.html template includes a url such as /home/images/products/1231
<img src='{{ photo.url }}'>
To render the image inside the pdf you need to make an image callback with the following function:
def link_callback(uri, rel):
"""
Convert HTML URIs to absolute system paths so xhtml2pdf can access those
resources
"""
# use short variable names
sUrl = settings.STATIC_URL # Typically /static/
sRoot = settings.STATIC_ROOT # Typically /home/userX/project_static/
mUrl = settings.MEDIA_URL # Typically /static/media/
mRoot = settings.MEDIA_ROOT # Typically /home/userX/project_static/media/
# convert URIs to absolute system paths
if uri.startswith(mUrl):
path = os.path.join(mRoot, uri.replace(mUrl, ""))
elif uri.startswith(sUrl):
path = os.path.join(sRoot, uri.replace(sUrl, ""))
else:
return uri # handle absolute uri (ie: http://some.tld/foo.png)
# make sure that file exists
if not os.path.isfile(path):
raise Exception(
'media URI must start with %s or %s' % (sUrl, mUrl)
)
return path
Next you add your rendering function.
Link: Biblioteca xhtml2pdf
If this answer has helped you, mark it as an answer.
no need set the fetch resources. its works for me
def render_to_pdf(template_src, context_dict={}):
template = get_template(template_src)
html = template.render(context_dict)
result = BytesIO()
pdf = pisa.pisaDocument(BytesIO(html.encode("ISO-8859-1")), result)
if not pdf.err:
return HttpResponse(result.getvalue(), content_type='application/pdf')
return None
also try to refer this link html-template-to-pdf-in-django
I am trying to pass a queryset object to django context class, but doing so results in the following error: TypeError('context must be a dict rather than %s.' % context.__class__.__name__)
Now i understand that the context accepts only a dictionary but i am following an example from a book called django_unleashed which uses Django version 1.8 and i am using django 2.0. and i guess it was done like that in previous versions.
So my question is how should i do this step correctly using django 2.0
from django.shortcuts import render
from django.http import HttpResponse
from .models import Tag
from django.template import Context, loader
def homepage(request):
tag_list = Tag.objects.all()
template = loader.get_template('organizer/tag_list.html')
context = Context({'tag_list': tag_list})
output = template.render(context)
return HttpResponse(output)
As the error suggests, you should use a regular dictionary for the context:
def homepage(request):
tag_list = Tag.objects.all()
template = loader.get_template('organizer/tag_list.html')
context = {'tag_list': tag_list}
output = template.render(context)
return HttpResponse(output)
In practice, you would usually use the render shortcut rather than manually rendering the template:
from django.shortcuts import render
def homepage(request):
tag_list = Tag.objects.all()
context = {'tag_list': tag_list}
return render(request, 'organizer/tag_list.html', context)
'''you have a model class named 'Tag',
wish your template is on ' Project directory/ app directory/ template/ same name of app directory'
example: let your project name is 'Website' and app name is 'organizer' then the template will be on: 'Website/ organizer/ templates/ organizer/ tag_list.html' Confirm your TEMPLATES setting is default on setting.py file."'
from django.shortcuts import render
from .models import Tag
def homepage(request):
tag_list = Tag.objects.all()
context = { 'tag_list' : tag_list}
return render ( request, 'organizer/tag_list.html', context)
I have a web app in Django. It's a plataform to store bills and invoices. Now i'm trying to export those bills un PDF.
I'm using xhtml2pdf but it's not working.
I'm using this code for testing:
http://obroll.com/generate-pdf-with-xhtml2pdf-pisa-in-django-examples/
It doesnt give any errors but doesnt generate the PDF documentos.
Try using this code. It works for me.
Change "template_testing.html" for your template and add your data to render on "data = {}"
views.py:
import os
from django.conf import settings
from django.http import HttpResponse
from django.template import Context
from django.template.loader import get_template
import datetime
from xhtml2pdf import pisa
def generate_PDF(request):
data = {}
template = get_template('template_testing.html')
html = template.render(Context(data))
file = open('test.pdf', "w+b")
pisaStatus = pisa.CreatePDF(html.encode('utf-8'), dest=file,
encoding='utf-8')
file.seek(0)
pdf = file.read()
file.close()
return HttpResponse(pdf, 'application/pdf')