Django - 无法下载文件(改为显示为文本)
Django - can't download file (showed as text instead)
我的静态文件中有一个 pdf,我需要给它添加一些文本并让用户下载它,但是下载部分给我带来了一些问题,这是我的部分代码:
views.py
import io
from werkzeug.wsgi import FileWrapper
from pathlib import Path
from PyPDF2 import PdfFileWriter, PdfFileReader
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from django.http import HttpResponse, FileResponse
def downloadpdf(request):
pdf_path = (Path.home()/"bot"/"mysite"/"static"/"images"/"tesseragenerica.pdf")
# 1
pdf_reader = PdfFileReader(str(pdf_path))
packet = io.BytesIO()
# create a new PDF with Reportlab
can = canvas.Canvas(packet, pagesize=letter)
testo = "text to add" #in future "text to add" will be the username
can.drawString(5, 5, testo)
can.save()
#move to the beginning of the StringIO buffer
packet.seek(0)
new_pdf = PdfFileReader(packet)
# read your existing PDF
existing_pdf = PdfFileReader(open("/home/myusername/bot/mysite/static/images/tesseragenerica.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 = open("destination3.pdf", "wb")
output.write(outputStream)
outputStream.close()
return FileResponse(FileWrapper(packet), as_attachment=True, filename='hello.pdf')
将文本添加到 pdf 的代码是正确的,因为在本地它可以工作,所以我认为问题是我将其作为 FileResponse 的第一个参数,如果我将 FileWrapper(packet) 作为示例而不是让我下载我在浏览器上看到的文件:
%PDF-1.3 %���� ReportLab Generated PDF document http://www.reportlab.com 1 0 obj << /F1 2 0 R >> endobj 2 0 obj << /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >> endobj 3 0 obj << /Contents 7 0 R /MediaBox [ 0 0 612 792 ] /Parent 6 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 4 0 obj << /PageMode /UseNone /Pages 6 0 R /Type /Catalog >> endobj 5 0 obj << /Author (anonymous) /CreationDate (D:20210718122806+00'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20210718122806+00'00') /Producer (ReportLab PDF Library - www.reportlab.com) /Subject (unspecified) /Title (untitled) /Trapped /False >> endobj 6 0 obj << /Count 1 /Kids [ 3 0 R ] /Type /Pages >> endobj 7 0 obj << /Filter [ /ASCII85Decode /FlateDecode ] /Length 97 >> stream GapQh0E=F,0U\H3T\pNYT^QKk?tc>IP,;W#U1^23ihPEM_?CW4KISh__N8"+NKVeK&quKrKuB2i9neZ[Kb,ht63StAffBaV~>endstream endobj xref 0 8 0000000000 65535 f 0000000073 00000 n 0000000104 00000 n 0000000211 00000 n 0000000404 00000 n 0000000472 00000 n 0000000768 00000 n 0000000827 00000 n trailer << /ID [<75dce57879667ca53ee6edf7352f4f98><75dce57879667ca53ee6edf7352f4f98>] % ReportLab generated PDF document -- digest (http://www.reportlab.com) /Info 5 0 R /Root 4 0 R /Size 8 >> startxref 1013 %%EOF
我认为这是一个 pdf 文件,但不明白为什么浏览器显示它而不是下载它。我认为(并希望)我接近解决方案,但我不知道我做错了什么。我该怎么做才能使 pdf 可下载?谢谢
如果文件响应是浏览器可识别的格式,则浏览器会显示文件响应。正如浏览器所识别的那样,浏览器会显示预览。如果想强制用户下载,有两种方法。
首先,如果您要 link 下载 url,请将下载属性添加到来自 html 的 link。 <a href="download/example.pdf" download>download me pls</a>
如果您想从 python 开始,或者 必须 在 python 中完成,那么您可以 return HttpResponse
对象,但带有强制下载的 content_type 。示例:
def download(request, path):
file_path = os.path.join(settings.MEDIA_ROOT, path)
if os.path.exists(file_path):
with open(file_path, 'rb') as fh:
response = HttpResponse(fh.read(), content_type="application/force-download")
response['Content-Disposition'] = 'inline; filename=' + os.path.basename(file_path)
return response
raise Http404
资源:Having Django serve downloadable files
您可以用更少的代码来完成。如果你的文件路径是静态的而不是动态的,你可以用 file_path = "/static/your_file_path/"
来改变
def download_file_from_server(request):
file_path = request.GET["file_path"]
file = open(os.path.join(settings.BASE_DIR, file_path), 'rb')
response = FileResponse(file)
return response
我的静态文件中有一个 pdf,我需要给它添加一些文本并让用户下载它,但是下载部分给我带来了一些问题,这是我的部分代码:
views.py
import io
from werkzeug.wsgi import FileWrapper
from pathlib import Path
from PyPDF2 import PdfFileWriter, PdfFileReader
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from django.http import HttpResponse, FileResponse
def downloadpdf(request):
pdf_path = (Path.home()/"bot"/"mysite"/"static"/"images"/"tesseragenerica.pdf")
# 1
pdf_reader = PdfFileReader(str(pdf_path))
packet = io.BytesIO()
# create a new PDF with Reportlab
can = canvas.Canvas(packet, pagesize=letter)
testo = "text to add" #in future "text to add" will be the username
can.drawString(5, 5, testo)
can.save()
#move to the beginning of the StringIO buffer
packet.seek(0)
new_pdf = PdfFileReader(packet)
# read your existing PDF
existing_pdf = PdfFileReader(open("/home/myusername/bot/mysite/static/images/tesseragenerica.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 = open("destination3.pdf", "wb")
output.write(outputStream)
outputStream.close()
return FileResponse(FileWrapper(packet), as_attachment=True, filename='hello.pdf')
将文本添加到 pdf 的代码是正确的,因为在本地它可以工作,所以我认为问题是我将其作为 FileResponse 的第一个参数,如果我将 FileWrapper(packet) 作为示例而不是让我下载我在浏览器上看到的文件:
%PDF-1.3 %���� ReportLab Generated PDF document http://www.reportlab.com 1 0 obj << /F1 2 0 R >> endobj 2 0 obj << /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >> endobj 3 0 obj << /Contents 7 0 R /MediaBox [ 0 0 612 792 ] /Parent 6 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> /Type /Page >> endobj 4 0 obj << /PageMode /UseNone /Pages 6 0 R /Type /Catalog >> endobj 5 0 obj << /Author (anonymous) /CreationDate (D:20210718122806+00'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20210718122806+00'00') /Producer (ReportLab PDF Library - www.reportlab.com) /Subject (unspecified) /Title (untitled) /Trapped /False >> endobj 6 0 obj << /Count 1 /Kids [ 3 0 R ] /Type /Pages >> endobj 7 0 obj << /Filter [ /ASCII85Decode /FlateDecode ] /Length 97 >> stream GapQh0E=F,0U\H3T\pNYT^QKk?tc>IP,;W#U1^23ihPEM_?CW4KISh__N8"+NKVeK&quKrKuB2i9neZ[Kb,ht63StAffBaV~>endstream endobj xref 0 8 0000000000 65535 f 0000000073 00000 n 0000000104 00000 n 0000000211 00000 n 0000000404 00000 n 0000000472 00000 n 0000000768 00000 n 0000000827 00000 n trailer << /ID [<75dce57879667ca53ee6edf7352f4f98><75dce57879667ca53ee6edf7352f4f98>] % ReportLab generated PDF document -- digest (http://www.reportlab.com) /Info 5 0 R /Root 4 0 R /Size 8 >> startxref 1013 %%EOF
我认为这是一个 pdf 文件,但不明白为什么浏览器显示它而不是下载它。我认为(并希望)我接近解决方案,但我不知道我做错了什么。我该怎么做才能使 pdf 可下载?谢谢
如果文件响应是浏览器可识别的格式,则浏览器会显示文件响应。正如浏览器所识别的那样,浏览器会显示预览。如果想强制用户下载,有两种方法。
首先,如果您要 link 下载 url,请将下载属性添加到来自 html 的 link。 <a href="download/example.pdf" download>download me pls</a>
如果您想从 python 开始,或者 必须 在 python 中完成,那么您可以 return HttpResponse
对象,但带有强制下载的 content_type 。示例:
def download(request, path):
file_path = os.path.join(settings.MEDIA_ROOT, path)
if os.path.exists(file_path):
with open(file_path, 'rb') as fh:
response = HttpResponse(fh.read(), content_type="application/force-download")
response['Content-Disposition'] = 'inline; filename=' + os.path.basename(file_path)
return response
raise Http404
资源:Having Django serve downloadable files
您可以用更少的代码来完成。如果你的文件路径是静态的而不是动态的,你可以用 file_path = "/static/your_file_path/"
def download_file_from_server(request):
file_path = request.GET["file_path"]
file = open(os.path.join(settings.BASE_DIR, file_path), 'rb')
response = FileResponse(file)
return response