天天看點

odoo14裡面給下載下傳PDF附件加水印

依賴包:pip install reportlab

​Odoo 中附件的下載下傳會經過 ir.http 的 def binary_content() 方法擷取附件内容等必要資訊,​

是以我們需要繼承 ​

​ir.http​

​ 模型并重寫 ​

​binary_content​

​ 方法,對 PDF 類型的附件添加水印,在 ​

​[models.py](http://models.py)​

​ 中添加繼承的代碼:

import io
import base64
import logging
from reportlab.pdfbase import pdfmetrics, ttfonts
from reportlab.pdfgen import canvas
from reportlab.lib.units import cm
from PyPDF2 import PdfFileWriter, PdfFileReader

from odoo import fields, models

_logger = logging.getLogger(__name__)


class IrHttp(models.AbstractModel):
    _inherit = 'ir.http'

    def binary_content(self, *args, **kwargs):
        status, headers, content = super(IrHttp, self).binary_content(*args, **kwargs)
        content_type = dict(headers).get('Content-Type')
        print ('------------content_type----------',content_type)
        if content_type == 'application/pdf':
           content = self.add_watermark(base64.b64decode(content))
           content = base64.b64encode(content)

        return status, headers, content

    def _get_watermark(self):
        """
        擷取水印文本:公司名稱+目前日期
        :return:
        """
        return f'{self.env.company.name} {fields.Date.context_today(self)}'

    def _generate_watermark(self):
        """
        生成水印
        :return:
        """
        # 水印檔案臨時存儲路徑:
        filename = f'E:\DEMO\watermark.pdf' #這是windows環境      
# 水印檔案臨時存儲路徑 
        # filename = f'/tmp/watermark.pdf' #這是linux環境      
watermark = self._get_watermark()
        # 擷取畫布并修改原點坐标
        c = canvas.Canvas(filename)
        c.translate(1.5 * cm, -3 * cm)

        try:
            font_name = 'SimSun'
            # 從系統路徑中引入中文字型(新宋)
            pdfmetrics.registerFont(ttfonts.TTFont('SimSun', 'SimSun.ttf'))
        except Exception as e:
            # 預設字型,不支援中文
            font_name = 'Helvetica'
            _logger.error(f'Register Font Error: {e}')

        # 設定字型及大小,旋轉 -20 度并設定顔色和透明度
        c.setFont(font_name, 14)
        c.rotate(20)
        c.setFillColor('#27334C', 0.15)
        # 平鋪寫入水印
        print('watermark---------------', watermark)
        for i in range(0, 30, 6):
            for j in range(0, 35, 5):
                c.drawString(i * cm, j * cm, watermark)
        c.save()
        return filename

    def add_watermark(self, content):
        """
        添加水印
        :param content:
        :return:
        """
        watermark = self._generate_watermark()
        pdf_input = PdfFileReader(io.BytesIO(content), strict=False)
        watermark = PdfFileReader(open(watermark, "rb"), strict=False)
        pdf_output = PdfFileWriter()
        page_count = pdf_input.getNumPages()
        # 周遊要下載下傳的 PDF 将它的每一頁都和水印檔案合并起來
        for page_number in range(page_count):
            input_page = pdf_input.getPage(page_number)
            input_page.mergePage(watermark.getPage(0))
            pdf_output.addPage(input_page)
        stream = io.BytesIO()
        pdf_output.write(stream)
        data = stream.getvalue()
        return data      

最後效果

odoo14裡面給下載下傳PDF附件加水印

繼續閱讀