Generate pdf files with Weasyprint, save in zip file, send that zip file to client and present it for download
<p>Let me break down my requirement. Here's what I'm doing right now.</p>

<p><strong>1. Generate PDF files from HTML</strong></p>

<p>for this I'm using Weasyprint as following:</p>

<pre><code>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')])
</code></pre>

<p>all files names, with paths, are saved in <code>lstFileNames</code>.</p>

<p><strong>2. Create a zip file with pdf files generated by weasyprint</strong></p>

<p>for this I'm using zipfile</p>

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

<p><strong>3. Send zip file to client for download</strong></p>

<pre><code>resp = HttpResponse(myzip, content_type = "application/x-zip-compressed")

resp['Content-Disposition'] = 'attachment; filename=%s' % 'myzip.zip'
</code></pre>

<p><strong>4. Open file for downloading via Javascript</strong></p>

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

<p><strong><em>Problems</em></strong></p>

<p><strong>1.</strong> While the zip file is successfully received at front end, after I try to open it, it gives the following error:</p>

<blockquote>
  <p>The archive is in either unknown format or damaged</p>
</blockquote>

<p>Am I sending the file wrong or is my Javascript code the problem?</p>

<p><strong>2.</strong> Is there a way to store all pdf files in list of byte arrays and generate zip files with those byte array and send it to the client? I tried that with weasyprint but the result was same <code>damaged file</code>.</p>

<p><strong>3.</strong> Not exactly a problem but I haven't been able to find it in weasyprint docs. Can I enforce the path to where the file should be saved?</p>

<p>Problem # 1 is of extreme priority, rest are secondary. I would like to know if I'm doing it right i.e. generating pdf files and sending their zip file to client. </p>

<p>Thanks in advance. </p>

<p>Once you have exited the <code>with</code> block the filehandle is closed. You should reopen the file (this time with open) and use <code>read()</code> to pass the contents to <code>HttpResponse</code> instead of passing the filehandle itself.</p>

<pre><code>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")
</code></pre>

<p>If that works, then you can use a <code>StringIO</code> instance instead of a filehandle to store the zip file. I'm not familiar with Weasyprint so I don't know whether you can use <code>StringIO</code> for that.</p>

javascript python django zipfile weasyprint