亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

是否可以使用 StreamingHttpResponse 生成 PDF,因為對于大型數據集可以使用

是否可以使用 StreamingHttpResponse 生成 PDF,因為對于大型數據集可以使用

慕妹3242003 2023-05-09 15:21:16
我有一個大型數據集,我必須為其生成 CSV 和 PDF。對于 CSV,我使用本指南:https://docs.djangoproject.com/en/3.1/howto/outputting-csv/import csvfrom django.http import StreamingHttpResponseclass Echo:    """An object that implements just the write method of the file-like    interface.    """    def write(self, value):        """Write the value by returning it, instead of storing in a buffer."""        return valuedef some_streaming_csv_view(request):    """A view that streams a large CSV file."""    # Generate a sequence of rows. The range is based on the maximum number of    # rows that can be handled by a single sheet in most spreadsheet    # applications.    rows = (["Row {}".format(idx), str(idx)] for idx in range(65536))    pseudo_buffer = Echo()    writer = csv.writer(pseudo_buffer)    response = StreamingHttpResponse((writer.writerow(row) for row in rows),                                     content_type="text/csv")    response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'    return response它很好用。但是,我找不到任何可以為 PDF 做的事情。它可以?我使用render_to_pdf以及使用 PDF 模板。
查看完整描述

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 花費的時間太長(例如可能會觸發超時錯誤),請考慮以下幾點:

  1. 嘗試優化生成算法的速度

  2. 在客戶端請求之前在后臺生成文件并將其存儲在您的存儲系統中。您可能希望使用 cronjob 或celery來觸發 PDF 的生成而不阻止 HTTP 請求。

  3. 一旦準備好下載,就使用 websockets 將文件發送到客戶端(參見django-channels)


查看完整回答
反對 回復 2023-05-09
?
暮色呼如

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')


查看完整回答
反對 回復 2023-05-09
?
蝴蝶刀刀

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')

查看完整回答
反對 回復 2023-05-09
?
慕沐林林

TA貢獻2016條經驗 獲得超9個贊

我有一個類似的情況,我能夠“生成和流式下載”文件csvjson和類型,我想對Excel -xml文件做同樣的事情。xlsx

不幸的是,我不能那樣做。但是,那段時間我發現了一些事情

  1. 文件、CSV、JSON 和 XML 是具有適當表示的文本文件。但是,對于 PDF 或 Excel(或類似文件),這些文件是使用適當的格式和適當的元數據構建的。

  2. 只有當我們調用一些特定的方法時, PDF 和類似文檔的二進制數據才會寫入io 緩沖區。[showPage()save()方法reportlab。(來源 - Django Doc)]

  3. 如果我們檢查文件流,PDF 和 Excel 需要復雜的特殊應用程序(例如:PDF 閱讀器、Bowsers 等)來查看/讀取數據,而對于 CSV 和 JSON,我們只需要一個簡單的文本編輯器。

因此,我得出結論,“通過流下載即時生成文件” (不確定我應該使用的正確技術術語是什么)的過程對于所有文件類型都是不可能的,但只適用于一些面向文本的文件

注意:這是我有限的經驗,可能有誤。


查看完整回答
反對 回復 2023-05-09
  • 4 回答
  • 0 關注
  • 206 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號