Odoo 18 QWeb报表加载KaTeX时出现odoo未定义错误
Odoo QWeb中KaTeX渲染问题排查与解决
问题背景
尝试在Odoo QWeb报表中使用KaTeX渲染数学公式,已本地下载KaTeX库并配置到__manifest__.py的资产中:
'assets': { 'web.report_assets_common': [ 'custom_quest/static/src/lib/katex/katex.css', 'custom_quest/static/src/lib/katex/katex.js', 'custom_quest/static/src/lib/katex/contrib/*.js', ], }
QWeb模板中嵌入渲染脚本,但PDF打印时公式仍为纯文本,HTML模式下控制台出现两个错误:
Uncaught ReferenceError: odoo is not defined(来自katex.js第1行)Uncaught ReferenceError: renderMathInElement is not defined(来自自定义脚本)
错误原因分析
1. odoo is not defined
Odoo的资产加载系统采用AMD模块规范,会自动包裹非AMD格式的JS文件,试图将其纳入Odoo的模块体系。KaTeX的webpack打包代码在执行时,Odoo的模块加载环境会干扰其全局作用域绑定,导致KaTeX无法正确挂载到全局对象(如window),同时触发对odoo变量的未定义引用。
2. renderMathInElement is not defined
renderMathInElement是KaTeX的auto-render.js提供的功能,配置中的contrib/*.js通配符可能未正确匹配到目标文件(路径层级或Odoo资产打包的通配符解析限制)。- 即使文件被加载,由于第一个错误导致KaTeX核心库未正确初始化,全局的
renderMathInElement函数也无法被注册。
解决步骤
步骤1:调整KaTeX资产加载方式,避免Odoo模块包裹
将KaTeX的JS文件移至web.assets_frontend(或对应报表的资产组),并添加?raw后缀强制Odoo不进行模块包裹,同时明确指定auto-render.js的完整路径:
'assets': { 'web.report_assets_common': [ 'custom_quest/static/src/lib/katex/katex.css', ], 'web.assets_frontend': [ 'custom_quest/static/src/lib/katex/katex.js?raw', 'custom_quest/static/src/lib/katex/contrib/auto-render/auto-render.js?raw', ], }
步骤2:修改QWeb渲染脚本,确保全局函数可用
调整脚本逻辑,检查renderMathInElement是否存在,并确保DOM加载完成后执行:
<template id="report_exam_paper_template"> <t t-call="web.basic_layout"> <t t-foreach="docs" t-as="exam"> <div class="page" id="exam_question_container"> <!-- 报表内容 --> <script type="text/javascript"> <![CDATA[ window.onload = function() { var container = document.getElementById('exam_question_container'); if (!container) { console.error('KaTeX Error: Container not found!'); return; } if (typeof renderMathInElement === 'undefined') { console.error('KaTeX auto-render script not loaded!'); return; } renderMathInElement(container, { delimiters: [ {left: '$$', right: '$$', display: true}, {left: '\\[', right: '\\]', display: true}, {left: '\\(', right: '\\)', display: false} ], throwOnError: false }); }; ]]> </script> </div> </t> </t> </template>
步骤3:处理PDF渲染的异步问题
Odoo的PDF生成依赖wkhtmltopdf,需要确保JS渲染完成后再生成PDF:
- 在脚本中添加
window.status = 'ready'通知wkhtmltopdf渲染完成 - 在报表的Python代码中配置等待JS执行的参数:
def _get_report_values(self, docids, data=None): docs = self.env['your.model'].browse(docids) return { 'docs': docs, 'doc_ids': docids, 'doc_model': self.env['your.model'], 'wait_for_js': True, 'js_delay': 2000, # 延迟2秒,可根据实际调整 }
步骤4:清除资产缓存
修改配置后,执行以下操作确保更新生效:
- 重启Odoo服务
- 访问
/web/assets/clear清除浏览器端缓存 - 使用
?debug=assets模式加载报表验证
内容的提问来源于stack exchange,提问作者Ammar Ahmed Khan
相关产品推荐
相关产品推荐

