无法从Apache托管的Django网站生成可下载的PDF文件

iaqfqrcu  于 2023-06-07  发布在  Go
关注(0)|答案(1)|浏览(369)

我在从托管的django网站生成PDF文件时遇到了一个问题。该网站是托管在apache通过cpanel python web应用程序。该网站基本上是所有用户提交的 Jmeter 板,旁边有一个下载按钮。一旦你点击按钮,一个对话框将弹出,提示你下载pdf文件与用户提交的详细信息。我按照这个教程让它工作:https://docs.djangoproject.com/en/4.2/howto/outputting-pdf/
我使用pypdf和reportlab添加了更多的代码来处理数据库中的详细信息,并将它们添加到pdf文件中以输出它。代码在我的本地计算机上工作正常,但当部署到我的托管站点时,它在我的控制台上返回一个通用错误响应,并在我的webapp stderr.log文件上返回一个不常见的类似错误的消息io.UnsupportedOperation: fileno
我的项目是如何设置的,我有一个javascript函数,它向一个django函数发出GET请求,以在浏览器上生成pdf文件。这是我的代码。
javascript:

function downloadPDF(id, date) {
    const csrftoken = getCookie('csrftoken');
    $.ajax({
      url: `/generate-pdf/${id}`,
      method: 'GET',
      headers: {
        'X-CSRFToken': csrftoken,
      },
      mode: 'same-origin',
      xhrFields: {
        responseType: 'blob' // Specify the response type as 'blob'
      },
      
      success: function(response) {
        // Create a temporary URL for the downloaded file
        console.log(response)
        var url = URL.createObjectURL(response);
        // Trigger a download by creating an anchor element and clicking it
        var link = document.createElement('a');
        link.href = url;
        link.download = `${id}-${date}.pdf`;
        link.click();
  
        // Clean up the temporary URL
        URL.revokeObjectURL(url);

      error: function(xhr, status, error) {
        console.error('Error generating PDF:', error);
        // Handle the error or display an error message
      }
    });
  }

Django:

def generate_pdf(request, id):
        buffer = io.BytesIO()
        doc = SimpleDocTemplate(buffer, pagesize=letter)
        # Rest of code to generate file
        buffer.seek(0)
        return FileResponse(buffer, as_attachment=True, filename="gen_pdf.pdf")

我试图解决这个问题的一件事是,删除我所有的代码,并使用一个简单的GET请求来测试从Django到javascript的消息。它在我的本地计算机和网站上工作得很好。所以JavaScript和Python函数工作得很好。
在尝试了不同的方法后,我怀疑问题是来自javascript代码var url = URL.createObjectURL(response);或python FileResponse()函数。起初,我以为这是io.BytesIO()的问题,因为我在stderr.log文件中得到了错误消息,但没有问题。
我甚至在cpanel中的终端中逐行输入了主代码,直到FileResponse之前都运行得很好。我无法生成日志文件中的错误消息,我不知道它来自哪里。这就是为什么我怀疑它来自我前面提到的两个功能。
希望你能帮助解决这个问题。

ajsxfq5m

ajsxfq5m1#

我终于发现出了问题。我试图加载一个大的pdf文件到内存,然后崩溃,由于大小。不得不把文件分块传输。
这里更新的代码解决了我的问题。

from wsgiref.util import FileWrapper

def generate_pdf(request, id):
        buffer = io.BytesIO()
        doc = SimpleDocTemplate(buffer, pagesize=letter)
        # Rest of code to generate file
        wrapper = FileWrapper(buffer)
        response = FileResponse(wrapper, content_type='application/pdf')
        response['Content-Disposition'] = 'attachment; filename=gen.pdf'
        response['Content-Length'] = buffer.tell()
        buffer.seek(0)
        return response

相关问题