我正在尝试创建一个"转换为pdf"当前页面的按钮(服务详细信息,这是一个动态页面)我尝试使用ReportLab(正如Django文档建议的那样,但我不能让它工作,而ReportLab文档并没有说明这种可能性)
现在我可以从这个视图中创建一个pdf文件:(编辑,为了清楚起见,回到django文档中的代码) views.py
@login_required
def service_detail(request, pk):
service = get_object_or_404(Service, pk=pk)
return render(request, 'detail.html', {'service':service, 'pk':pk})
@login_required
def render_to_pdf(request):
# Create the HttpResponse object with the appropriate PDF headers.
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="service.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.
p.drawString("Hello world.")
# Close the PDF object cleanly, and we're done.
p.showPage()
p.save()
return response
urls.py
url(r'^service/(?P<pk>\d+)/$', views.service_detail, name='service_detail'), #Services details
url(r'^render_to_pdf/', views.render_to_pdf, name='render_to_pdf'),
服务详细信息的模板包括动态元素,例如:
Your location: {{ service.user_location }} <br><br>
任何人都知道我该怎么做,或者我可以用什么技术来创建这样的PDF?
我主要使用Python,Django,HTML和CSS
答案 0 :(得分:0)
content_type
需要application/pdf
而不是service/pdf
,还要尝试从docs提供不带空格的pdf文件名,例如service.pdf
,也就是忘了将attachment
放入Content-Disposition
尝试将pdf写入response
,然后使用BytesIO
:
from io import BytesIO
@login_required
def render_to_pdf(request):
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'inline; filename="service.pdf'
buffer = BytesIO()
p = canvas.Canvas(buffer)
# Start writing the PDF here
p.drawString(100, 100, 'Hello world.')
# End writing
p.showPage()
p.save()
pdf = buffer.getvalue()
buffer.close()
response.write(pdf)
return response
答案 1 :(得分:0)
您可能需要考虑用于在Django中生成PDF的包django-wkhtmltopdf。
使用此功能,您可以将PDF布局为HTML页面(带有CSS标记),就像任何其他视图一样,但它会将其呈现为PDF文件。请注意,您必须安装wkhtmltopdf binary才能使其正常运行。
通过在网址中添加?as=html
前缀,您可以在开发过程中在浏览器中查看您的网页。
django-wkhtmltopdf包使用基于类的视图。这是一个例子:
<强> views.py 强>
from django.utils.text import slugify
from wkhtmltopdf.views import PDFTemplateView
class Portfolio(PDFTemplateView):
template_name = 'frontend/portfolio.html'
def get_filename(self):
return slugify('portfolio ' + self.request.user.first_name + ' ' + self.request.user.last_name) + '.pdf'
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
<强> urls.py 强>
from django.urls import path
from . import views
app_name = 'frontend'
urlpatterns = [
path(
'<slug:group_slug>/<int:school_year_pk>/portfolio/',
views.Portfolio.as_view(),
name='portfolio'
),
...