Reputation: 173
I create a set of pdf files and want to add them to zip archive. Everything seems fine, but when I download my zip file It can't be open.
So I create pdf with create_pdf
function
def create_pdf(child):
buffer = io.BytesIO()
canvas = Canvas(buffer, pagesize=A4)
p = staticfiles_storage.path('TNR.ttf')
pdfmetrics.registerFont(TTFont('TNR', p))
canvas.setFont('TNR', 14)
t = canvas.beginText(-1 * cm, 29.7 * cm - 1 * cm)
t.textLines(create_text(child), trim=0)
canvas.drawText(t)
canvas.save()
pdf = buffer.getvalue()
return pdf
Then I create zip file and pack it to response
def create_zip(pdfs):
mem_zip = io.BytesIO()
i = 0
with zipfile.ZipFile(mem_zip, mode='w', compression=zipfile.ZIP_DEFLATED)\
as zf:
for f in pdfs:
i += 1
zf.writestr(f'{str(i)}.pdf', f)
return mem_zip.getvalue()
def get_files(request, children):
pdfs = []
for child in children:
pdfs.append(create_pdf(child))
zip = create_zip(pdfs)
response = FileResponse(zip,
content_type='application/zip',
filename='zayavleniya.zip')
response['Content-Disposition'] = 'attachment; filename=files.zip'
return response
Please help to find where I am wrong.
Upvotes: 0
Views: 604
Reputation: 6653
In the documentation, you can see the write_str
method expects data
as second argument. Here, you are providing a filename.
So the content of the pdf files are just "i.pdf", which is of course not the content that you expect for a pdf file.
Try with something like this:
def create_zip(pdfs):
mem_zip = io.BytesIO()
i = 0
with zipfile.ZipFile(mem_zip, mode='w', compression=zipfile.ZIP_DEFLATED)\
as zf:
for filename in pdfs:
i += 1
with open(filename, 'rb') as f:
zf.writestr(f'{i}.png', f.read())
return mem_zip.getvalue()
NB: try to avoid using
zip
as a variable name, since it is already a builtin python function
If you isolate the archive creation to get a minimal working example, you get this, which create an zipfile as you wanted:
def create_zip(pdfs):
i = 0
with zipfile.ZipFile(HERE / "my_archive.zip", mode='w', compression=zipfile.ZIP_DEFLATED)\
as zf:
for filename in pdfs:
i += 1
with open(filename, 'rb') as f:
zf.writestr(f'{str(i)}.png', f.read())
create_zip(["icon.png"])
Upvotes: 1
Reputation: 173
After I post this question I managed to find the answer myself. I changed create_zip
def create_zip(pdfs):
mem_zip = io.BytesIO()
i = 0
with zipfile.ZipFile(mem_zip, mode='w', compression=zipfile.ZIP_DEFLATED)\
as zf:
for f in pdfs:
i += 1
zf.writestr(f'{str(i)}.pdf', f)
mem_zip.seek(0)
return mem_zip
Upvotes: 0