Odoo切换至external_layout后编码异常,如何解决?
Odoo报告使用external_layout时特殊字符(如欧元符号)乱码的解决方法
问题场景
继承product.report_pricelist模板并替换基础布局为web.external_layout后,报告中的欧元符号等特殊字符出现乱码,切换回basic_layout则编码显示正常。用户的模板代码如下:
<template id="product.report_pricelist"> <t t-call="web.external_layout"> <main> <div class="page"> <t t-call="product.report_pricelist_page"/> </div> <p style="page-break-before:always;"> </p> </main> </t> </template>
问题原因
web.external_layout默认可能缺少UTF-8编码的meta声明,或使用的字体不支持欧元等特殊字符;而basic_layout内置了正确的编码配置和兼容字体。
解决步骤
1. 为external_layout添加UTF-8编码声明
继承原生的web.external_layout,在HTML头部插入UTF-8编码的meta标签:
<template id="custom_external_layout" inherit_id="web.external_layout"> <xpath expr="//head" position="inside"> <meta charset="UTF-8"/> </xpath> </template>
然后修改你的报告模板,调用这个自定义布局:
<template id="product.report_pricelist"> <t t-call="your_module.custom_external_layout"> <main> <div class="page"> <t t-call="product.report_pricelist_page"/> </div> <p style="page-break-before:always;"> </p> </main> </t> </template>
(注意替换your_module为你的自定义模块名称)
2. 强制报告响应使用UTF-8编码
如果有自定义的报告渲染逻辑,在Python代码中明确指定响应的编码为UTF-8:
from odoo import http from odoo.http import request class PricelistReportController(http.Controller): @http.route('/report/pdf/product/pricelist/<int:pricelist_id>', type='http', auth='user') def generate_pricelist_pdf(self, pricelist_id): pricelist = request.env['product.pricelist'].browse(pricelist_id) pdf_content, _ = request.env['ir.actions.report']._render_qweb_pdf( 'your_module.product.report_pricelist', res_ids=[pricelist_id] ) response = request.make_response( pdf_content, headers=[ ('Content-Type', 'application/pdf; charset=utf-8'), ('Content-Disposition', 'attachment; filename="pricelist.pdf"'), ('Content-Transfer-Encoding', 'UTF-8') ] ) return response
3. 更换支持特殊字符的字体
部分情况下乱码是因为external_layout使用的字体不支持欧元符号,修改布局的字体设置为兼容UTF-8的字体(如DejaVu Sans):
<template id="custom_external_layout" inherit_id="web.external_layout"> <xpath expr="//style" position="inside"> <style> body, .page { font-family: 'DejaVu Sans', sans-serif; } </style> </xpath> </template>
总结
通过添加UTF-8编码声明、强制响应编码、更换兼容字体这三个步骤,即可在使用external_layout的同时保证特殊字符正常显示。
内容的提问来源于stack exchange,提问作者CafeConMasCafe
相关产品推荐
相关产品推荐

