依赖包: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附件加水印_中文字体

 

 

 


心有猛虎,细嗅蔷薇