使用Weasyprint生成pdf文件,保存为zip文件,将该zip文件发送到客户端并提供下载

时间:2016-09-29 14:16:15

标签: javascript python django zipfile weasyprint

让我打破我的要求。这就是我现在正在做的事情。

1。从HTML生成PDF文件

为此我使用Weasyprint如下:

lstFileNames = []
for i, content in enumerate(lstHtmlContent):
    repName = 'report'+ str(uuid.uuid4()) + '.pdf'
    lstFileNames.append("D:/Python/Workspace/" + repName)

    HTML(string=content).write_pdf(target=repName,
        stylesheets=[CSS(filename='/css/bootstrap.css')])

所有带路径的文件名都保存在lstFileNames

2。使用weasyprint生成的pdf文件创建一个zip文件

为此我使用zipfile

zipPath = 'reportDir' + str(uuid.uuid4()) + '.zip'
myzip = zipfile.ZipFile(zipPath, 'w') 
with  myzip:
    for f in lstFileNames:
        myzip.write(f)

第3。将zip文件发送到客户端进行下载

resp = HttpResponse(myzip, content_type = "application/x-zip-compressed")

resp['Content-Disposition'] = 'attachment; filename=%s' % 'myzip.zip'

4。打开文件,通过Javascript下载

var file = new Blob([response], {type: 'application/x-zip-compressed'});
var fileURL = URL.createObjectURL(file);
window.open(fileURL);

问题

1。虽然在前端成功收到了zip文件,但在我尝试打开它后,它会出现以下错误:

  

存档格式未知或已损坏

我发错文件或我的Javascript代码是问题吗?

2. 有没有办法将所有pdf文件存储在字节数组列表中并生成包含这些字节数组的zip文件并将其发送到客户端?我尝试使用weasyprint,但结果是damaged file

3。不完全是问题,但我还没能在weasyprint docs中找到它。我可以强制执行文件保存位置的路径吗?

问题#1是极端优先的,休息是次要的。我想知道我是否做得对,即生成pdf文件并将其zip文件发送给客户端。

提前致谢。

2 个答案:

答案 0 :(得分:1)

稍微不同的方法是将zip文件移动到公共目录,然后将该位置发送到客户端(例如json格式化),即:

publicPath = os.path.join('public/', os.path.basename(zipPath))
os.rename(zipPath, os.path.join('/var/www/', publicPath))

jsonResp = '{ "zip-location": "' + publicPath + '" }'

resp = HttpResponse(jsonResp, content_type = 'application/json');

然后在你客户的javascript:

var res = JSON.parse(response);
var zipFileUrl = '/' + res['zip-location'];

window.open(zipFileUrl, '_blank');

'/' + res['zip-location']假设您的网页与public目录位于同一文件夹中(因此http://example.com/public/pdf-files-123.zip指向您文件系统上的/var/www/public/pdf-files-123.zip。)

您可以使用cron作业清除public目录,该作业将删除那些超过一小时左右的所有.zip个文件。

答案 1 :(得分:0)

退出with块后,文件句柄将关闭。您应该重新打开该文件(这次打开)并使用read()将内容传递给HttpResponse,而不是传递文件句柄本身。

with zipfile.ZipFile(zipPath, 'w') as myzip
    for f in lstFileNames:
        myzip.write(f)
with open(zipPath, 'r') as myzip:
    return HttpResponse(myzip.read(), content_type = "application/x-zip-compressed")

如果可以,那么您可以使用StringIO实例而不是文件句柄来存储zip文件。我不熟悉Weasyprint,因此我不知道您是否可以使用StringIO

相关问题