0

让我分解一下我的要求。这就是我现在正在做的事情。

1. 从 HTML 生成 PDF 文件

为此,我使用 Wea​​syprint 如下:

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 文档中找到它。我可以强制保存文件的路径吗?

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

提前致谢。

4

2 回答 2

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超过一小时左右的所有文件。

于 2016-09-30T08:27:26.217 回答
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它。

于 2016-09-29T15:08:29.870 回答