4 回答

TA贡献1942条经验 获得超3个赞
将 CSV 视为水果沙拉。你可以在一个大锅里把香蕉切成薄片,加入一些葡萄柚、一些菠萝……然后把整体分成单独的部分,然后放在一起放在桌子上(这是:你生成你的 CSV 文件,然后将它发送到客户端)。但是你也可以直接做单独的部分:在一个小碗里切一些香蕉片,加入一些葡萄柚,一些菠萝,......把这个小碗带到桌子上,然后对其他单独的部分重复这个过程(这是:您生成 CSV 文件并在生成它时将其部分发送给客户端)。
好吧,如果 CSV 是水果沙拉,那么 PDF 就是蛋糕。您必须混合所有成分并将其放入烤箱。这意味着在烘烤整个蛋糕之前,您不能将一块蛋糕带到餐桌上。同样,在完全生成 PDF 文件之前,您无法开始将其发送给客户。
所以,为了回答你的问题,这个 ( response = StreamingHttpResponse((writer.writerow(row) for row in rows), content_type="text/csv")
) 不能为 PDF 完成。
但是,一旦生成文件,您就可以使用其他答案中提到的方式将其流式传输到客户端FileResponse
。
如果您的问题是生成 PDF 花费的时间太长(例如可能会触发超时错误),请考虑以下几点:
尝试优化生成算法的速度
在客户端请求之前在后台生成文件并将其存储在您的存储系统中。您可能希望使用 cronjob 或celery来触发 PDF 的生成而不阻止 HTTP 请求。
一旦准备好下载,就使用 websockets 将文件发送到客户端(参见django-channels)

TA贡献1853条经验 获得超9个赞
您尝试过FileResponse吗?
像这样的东西应该可以工作,它基本上是你可以在Django 文档中找到的:
import io
from django.http import FileResponse
from reportlab.pdfgen import canvas
def stream_pdf(request):
buffer = io.BytesIO()
p = canvas.Canvas(buffer)
p.drawString(10, 10, "Hello world.")
p.showPage()
p.save()
buffer.seek(io.SEEK_SET)
return FileResponse(buffer, as_attachment=True, filename='helloworld.pdf')

TA贡献1801条经验 获得超8个赞
查看您提供的链接,它确实提供了指向使用reportlab动态创建和发送 pdf 文件的页面的链接。
import io
from django.http import FileResponse
from reportlab.pdfgen import canvas
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.
buffer.seek(0)
return FileResponse(buffer, as_attachment=True, filename='hello.pdf')

TA贡献2016条经验 获得超9个赞
我有一个类似的情况,我能够“生成和流式下载”文件csv
,json
和类型,我想对Excel -xml
文件做同样的事情。xlsx
不幸的是,我不能那样做。但是,那段时间我发现了一些事情
文件、CSV、JSON 和 XML 是具有适当表示的文本文件。但是,对于 PDF 或 Excel(或类似文件),这些文件是使用适当的格式和适当的元数据构建的。
只有当我们调用一些特定的方法时, PDF 和类似文档的二进制数据才会写入io 缓冲区。[
showPage()
和save()
方法reportlab
。(来源 - Django Doc)]如果我们检查文件流,PDF 和 Excel 需要复杂的特殊应用程序(例如:PDF 阅读器、Bowsers 等)来查看/读取数据,而对于 CSV 和 JSON,我们只需要一个简单的文本编辑器。
因此,我得出结论,“通过流下载即时生成文件” (不确定我应该使用的正确技术术语是什么)的过程对于所有文件类型都是不可能的,但只适用于一些面向文本的文件
注意:这是我有限的经验,可能有误。
添加回答
举报