【问题标题】:Can't open zip file created with python and Django无法打开使用 python 和 Django 创建的 zip 文件
【发布时间】:2021-04-26 19:48:53
【问题描述】:

我创建了一组 pdf 文件并希望将它们添加到 zip 存档中。一切似乎都很好,但是当我下载我的 zip 文件时它无法打开。

所以我用create_pdf函数创建了pdf

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

然后我创建 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)
    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

请帮忙找出我错在哪里。

【问题讨论】:

    标签: python django zipfile


    【解决方案1】:

    documentation 中,您可以看到write_str 方法需要data 作为第二个参数。在这里,您提供了一个文件名。 所以pdf文件的内容只是“i.pdf”,这当然不是你期望的pdf文件的内容。

    试试这样的:

    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()
    

    注意:尽量避免使用zip作为变量名,因为它已经是一个内置的python函数

    更新

    如果您隔离存档创建以获得最小的工作示例,您会得到这个,它会根据需要创建一个 zipfile:

    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"])
    

    【讨论】:

    • 感谢您的建议。我想我做到了。
    【解决方案2】:

    发布此问题后,我自己设法找到了答案。我改了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
    

    【讨论】:

    • 你能确认这是有效的吗?因为我不明白如何使用文件名? (请参阅我的答案编辑)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多