让我打破我的要求。这就是我现在正在做的事情。
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文件发送给客户端。
提前致谢。
答案 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
。