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

  • 相关阅读:
    leetcode Remove Linked List Elements
    leetcode Word Pattern
    leetcode Isomorphic Strings
    leetcode Valid Parentheses
    leetcode Remove Nth Node From End of List
    leetcode Contains Duplicate II
    leetcode Rectangle Area
    leetcode Length of Last Word
    leetcode Valid Sudoku
    leetcode Reverse Bits
  • 原文地址:https://www.cnblogs.com/xushuotec/p/15138938.html
Copyright © 2011-2022 走看看