【问题标题】:Issue with merging .png files in .pdf through Pillow 6.0.0 in Odoo 12 (CE)通过 Odoo 12 (CE) 中的 Pillow 6.0.0 合并 .pdf 中的 .png 文件的问题
【发布时间】:2021-03-24 12:51:41
【问题描述】:

在 Odoo 12 CE 的自定义模块中,我扩展了 sale.order.line 类并添加了将单独的 .png 图像合并到一个 .pdf 文件中的功能。对于此任务,我使用库 Pillow 6.0.0。

image_files = [<PIL.Image.Image image mode=RGB size=800x1400 at 0x118295908>, <PIL.Image.Image image mode=RGB size=800x1400 at 0x118295B38>]
filename = "test.pdf"
image_files[0].save(filename, "PDF", resolution=100.0, save_all=True, append_images=image_files[1:])

我将此方法添加到 order_line_form 中的按钮,但是当我单击它时,我收到错误消息:

 File ".../models/sale_order_line.py", line 261, in generateLabel
    image_files[0].save(filename, "PDF", resolution=100.0, save_all=True, append_images=image_files[1:])
  File "/...virt/lib/python3.7/site-packages/PIL/Image.py", line 1994, in save
    save_handler = SAVE_ALL[format.upper()]
KeyError: 'PDF'

疑难解答:我在 Odoo 之外创建了测试 .py 项目,我使用相同的虚拟环境和相同的包测试了此功能,它按预期工作:所有 png 文件合并到一个 pdf 文件中。

为什么我从 Odoo 模块运行它时它不起作用?

【问题讨论】:

    标签: odoo odoo-12


    【解决方案1】:

    我不知道要使用枕头,但我使用了 FPDF,它应该将 png 转换为 pdf。

    import os
    from odoo.tools import pdf
    from fpdf import FPDF
    import base64
    from odoo import models, fields, api, _
    from odoo.exceptions import Warning, ValidationError
    
    
    @api.multi
    def download_labels(self):
        self.ensure_one()
        try:
            file_path = "/tmp/waves/"
            directory = os.path.dirname(file_path)
            os.stat(directory)
            os.system("mkdir %s" % (file_path))
            # "P" indiacte Portal page for pdf , mm indicate
            pdf_info = FPDF('P', 'mm', (297, 210))
            pdf_datas = []
            for line in self.order_line:
                # Create Directory -
                file_name = line.name
                file_name = file_name.replace('/', '_')
                attachment_id = self.env['ir.attachment'].search([('res_id', '=', line.id), ('res_model', '=', line._name)], limit=1)
                file_extension = attachment_id.name.split('.')[1] if attachment_id.name.split('.')[1] else "pdf"
                if attachment_id:
                    if file_extension in ['pdf', 'PDF']:
                        pdf_datas.append(base64.decodestring(attachment_id.datas))
                        continue
                    with open("%s%s.%s" % (file_path, file_name, file_extension), "wb") as f:
                        f.write(base64.decodestring(attachment_id.datas))
                    pdf_info.add_page()
                    pdf_info.image("%s%s.%s" % (file_path, file_name, file_extension), 1, 1, 296, 209)
    
            if pdf_datas:
                message_ept = (_("All shipment label combined!"))
                message = self.message_post(body=message_ept, attachments=[('Label-%s.%s' % (self.id, 'PDF'), pdf.merge_pdf(pdf_datas))])
                return {
                    'type': 'ir.actions.act_url',
                    'url': '/web/binary/download_document?model=ir.attachment&field=datas&id=%s&filename=%s.pdf' % ( message.attachment_ids[0].id, self.name.replace('/', '_')),
                    'target': 'self',
                }
    
            pdf_info.output("%s%s.pdf" % (file_path, self.name.replace('/', '_')), "F")
    
            binary_package = open("%s%s.pdf" % (file_path, self.name.replace('/', '_')), 'rb').read()
            os.system("rm -R %s" % (directory))
            message_ept = (_("label combined!"))
            message = self.message_post(body=message_ept, attachments=[("%s.pdf" % (self.name.replace('/', '_')), binary_package)])
            return {
                'type': 'ir.actions.act_url',
                'url': '/web/binary/download_document?model=ir.attachment&field=datas&id=%s&filename=%s.pdf' % ( message.attachment_ids[0].id, self.name.replace('/', '_')),
                'target': 'self',
            }
        except Exception as e:
            raise ValidationError(e)
    

    【讨论】:

    • 嗨,Harshit,谢谢您的回答。我还重写了我的代码并使用 FPDF 作为一种解决方法,但我仍然想了解为什么这段代码在 Odoo 中不起作用,而在 python 项目中却可以正常工作。
    • @edward 你能否告诉我更具体的问题或放置完整的堆栈跟踪。
    • 我在 git 上添加了完整的测试功能,所以你可以复制它并尝试从你的 odoo 环境中运行以了解问题:github.com/jarvee1/test/blob/master/pil
    【解决方案2】:

    我可能会迟到回复,但这是解决方案。尝试在你的逻辑之前输入这些

    Image._initialized = 0
    Image.init()
    

    【讨论】:

      猜你喜欢
      • 2020-05-03
      • 2019-03-21
      • 2011-07-17
      • 2023-03-23
      • 2019-08-01
      • 2020-06-25
      • 1970-01-01
      • 2012-08-25
      • 1970-01-01
      相关资源
      最近更新 更多