zoukankan      html  css  js  c++  java
  • 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:DEMOwatermark.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

    最后效果

    本文来自:https://ruterly.com/2020/12/27/Odoo-Add-Watermark-to-PDF

    心有猛虎,细嗅蔷薇
  • 相关阅读:
    App架构经验总结
    通过C语言程序改动控制台的背景和前景颜色
    java实现读取yaml文件,并获取值
    java 实现yaml 数据转json与map
    yaml标记语言的简介
    重新学习之spring第二个程序,配置AOP面向切面编程
    重新学习之spring第一个程序,配置IOC容器
    重新学习Spring之核心IOC容器的底层原理
    hibernate之xml映射文件关系维护,懒加载,级联
    hibernate映射xml文件配置之一对多,多对多
  • 原文地址:https://www.cnblogs.com/1314520xh/p/14753511.html
Copyright © 2011-2022 走看看