zoukankan      html  css  js  c++  java
  • 【odoo】【知识点】生成pdf文件时缺少样式的问题

    欢迎转载,但需标注出处,谢谢!

    背景

    近期在客户的项目中发现在自定义报表样式的时候,存在渲染为html正常,但是在生成pdf的时候,缺少样式的情况。

    分析

    涉及到的odoo源码中的ir_actions_report.py文件中的代码

    
        def _prepare_html(self, html):
            '''Divide and recreate the header/footer html by merging all found in html.
            The bodies are extracted and added to a list. Then, extract the specific_paperformat_args.
            The idea is to put all headers/footers together. Then, we will use a javascript trick
            (see minimal_layout template) to set the right header/footer during the processing of wkhtmltopdf.
            This allows the computation of multiple reports in a single call to wkhtmltopdf.
    
            :param html: The html rendered by render_qweb_html.
            :type: bodies: list of string representing each one a html body.
            :type header: string representing the html header.
            :type footer: string representing the html footer.
            :type specific_paperformat_args: dictionary of prioritized paperformat values.
            :return: bodies, header, footer, specific_paperformat_args
            '''
            IrConfig = self.env['ir.config_parameter'].sudo()
            base_url = IrConfig.get_param('report.url') or IrConfig.get_param('web.base.url')
    
            # Return empty dictionary if 'web.minimal_layout' not found.
            layout = self.env.ref('web.minimal_layout', False)
            if not layout:
                return {}
            layout = self.env['ir.ui.view'].browse(self.env['ir.ui.view'].get_view_id('web.minimal_layout'))
    
            root = lxml.html.fromstring(html)
            match_klass = "//div[contains(concat(' ', normalize-space(@class), ' '), ' {} ')]"
    
            header_node = etree.Element('div', id='minimal_layout_report_headers')
            footer_node = etree.Element('div', id='minimal_layout_report_footers')
            bodies = []
            res_ids = []
    
            body_parent = root.xpath('//main')[0]
            # Retrieve headers
            for node in root.xpath(match_klass.format('header')):
                body_parent = node.getparent()
                node.getparent().remove(node)
                header_node.append(node)
    
            # Retrieve footers
            for node in root.xpath(match_klass.format('footer')):
                body_parent = node.getparent()
                node.getparent().remove(node)
                footer_node.append(node)
    
            # Retrieve bodies
            for node in root.xpath(match_klass.format('article')):
                layout_with_lang = layout
                # set context language to body language
                if node.get('data-oe-lang'):
                    layout_with_lang = layout_with_lang.with_context(lang=node.get('data-oe-lang'))
                body = layout_with_lang._render(dict(subst=False, body=lxml.html.tostring(node), base_url=base_url))
                bodies.append(body)
                if node.get('data-oe-model') == self.model:
                    res_ids.append(int(node.get('data-oe-id', 0)))
                else:
                    res_ids.append(None)
    
            if not bodies:
                body = bytearray().join([lxml.html.tostring(c) for c in body_parent.getchildren()])
                bodies.append(body)
    
            # Get paperformat arguments set in the root html tag. They are prioritized over
            # paperformat-record arguments.
            specific_paperformat_args = {}
            for attribute in root.items():
                if attribute[0].startswith('data-report-'):
                    specific_paperformat_args[attribute[0]] = attribute[1]
    
            header = layout._render(dict(subst=True, body=lxml.html.tostring(header_node), base_url=base_url))
            footer = layout._render(dict(subst=True, body=lxml.html.tostring(footer_node), base_url=base_url))
    
            return bodies, res_ids, header, footer, specific_paperformat_args
    
    1. 我们可以看到在base_url = IrConfig.get_param('report.url') or IrConfig.get_param('web.base.url')中取了系统参数中的report.urlweb.base.url中的地址。
    2. body = layout_with_lang._render(dict(subst=False, body=lxml.html.tostring(node), base_url=base_url))中渲染了我们必要的样式,若这里的url出错,那么这里我们将缺少样式内容。当然,若是全部都通过html原生去实现样式,那么也是可以避免如上的问题。

    解决方案

    在系统参数添加report.url或者web.base.url的值为http://127.0.0.1:8069(填写本机的地址)

    本文来自博客园,作者:老韩头的开发日常,转载请注明原文链接:https://www.cnblogs.com/xushuotec/p/15138938.html

  • 相关阅读:
    04-树7 二叉搜索树的操作集
    04-树6 Complete Binary Search Tree
    04-树5 Root of AVL Tree
    04-树4 是否同一棵二叉搜索树
    05-树8 File Transfer
    05-树7 堆中的路径
    二叉树的非递归遍历(先序、中序、后序和层序遍历)
    队列的定义与操作——顺序存储和链式存储
    Maven项目的核心pom.xml解释(转)
    eclipse安装插件的三种方式
  • 原文地址:https://www.cnblogs.com/xushuotec/p/15138938.html
Copyright © 2011-2022 走看看