
1. Odoo18泰文打印乱码问题深度解析最近在实施一个泰国市场的Odoo18项目时遇到了一个颇为棘手的问题系统生成的PDF报告中泰文显示为乱码。这个问题看似简单实则涉及字符编码、字体配置、PDF生成引擎等多个技术环节的协同工作。经过一周的排查和测试终于找到了完整的解决方案这里把整个处理过程和经验总结分享给大家。重要提示Odoo的PDF打印功能依赖于wkhtmltopdf工具而泰文乱码问题90%以上都与字体配置有关但剩下的10%可能是更隐蔽的系统级问题。2. 问题现象与初步诊断2.1 典型乱码表现在Odoo18中当尝试打印包含泰文的销售订单或发票时生成的PDF中泰文字符会呈现以下几种异常情况完全无法显示显示为空白显示为方框□□□显示为乱码字符如à¸à¸±à¸à¸à¸µà¹à¸à¸°部分字符正确但音调符号错位2.2 诊断步骤首先通过以下命令检查系统基础环境# 检查系统支持的泰文字体 fc-list | grep Thai # 检查wkhtmltopdf版本 wkhtmltopdf --version # 检查locale设置 locale常见问题根源包括服务器缺少泰文字体支持wkhtmltopdf编译时未包含字体配置选项Odoo模板未正确声明字符编码系统locale设置不正确3. 完整解决方案3.1 系统级字体安装对于Ubuntu/Debian系统# 安装泰文字体包 sudo apt-get install fonts-thai-tlwg fonts-sipa-arundina # 刷新字体缓存 fc-cache -fv对于CentOS/RHEL系统sudo yum install cjkuni-ukai-fonts thai-scalable-fonts验证字体安装fc-list | grep -i thai应能看到类似输出/usr/share/fonts/truetype/thai/TlwgTypo.ttf: Tlwg Typo:styleRegular /usr/share/fonts/truetype/thai/TlwgTypo-Bold.ttf: Tlwg Typo:styleBold3.2 wkhtmltopdf专项配置推荐使用特定版本的wkhtmltopdfwget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb sudo dpkg -i wkhtmltox_0.12.6-1.focal_amd64.deb sudo apt-get install -f创建自定义配置文件!-- /etc/xml/unicode.xml -- !DOCTYPE unicode [ !ENTITY thai-font Tlwg Typo ]3.3 Odoo模板调整在报表模板的style部分添加style page { size: A4; margin: 0mm; } body { font-family: Tlwg Typo, SIPA Arundina, sans-serif; encoding: UTF-8; } /style对于QWeb报表需要在t标签中指定t t-callweb.external_layout t t-setencoding t-valueUTF-8/ ... /t4. 进阶问题排查4.1 音调符号错位问题泰语的音调符号需要特殊处理在CSS中添加thai-text { text-rendering: optimizeLegibility; font-feature-settings: kern 1, liga 1, clig 1, dlig 1; }4.2 字体回退机制创建字体回退配置文件sudo nano /etc/fonts/local.conf内容为?xml version1.0? !DOCTYPE fontconfig SYSTEM fonts.dtd fontconfig alias familyserif/family prefer familyTlwg Typo/family familySIPA Arundina/family /prefer /alias /fontconfig4.3 Docker环境特殊处理如果使用Docker部署需要在Dockerfile中添加RUN apt-get update \ apt-get install -y fonts-thai-tlwg fonts-sipa-arundina \ fc-cache -fv5. 验证与测试方案5.1 测试模板创建一个专门的测试报表odoo template idreport_thai_test t t-callweb.html_container div classpage h1泰文测试/h1 p正常文本: Hello World/p p泰文测试: ภาษาไทย/p p混合文本: 订单 Order123 ภาษาไทย/p /div /t /template /odoo5.2 自动化测试脚本创建测试Python脚本import os from odoo.tests.common import TransactionCase class TestThaiPrinting(TransactionCase): def test_thai_pdf_generation(self): report self.env.ref(your_module.report_thai_test) pdf_content report._render_qweb_pdf(report.id, [])[0] with open(/tmp/thai_test.pdf, wb) as f: f.write(pdf_content) # 检查PDF是否包含泰文字符 self.assertIn(bภาษาไทย, pdf_content)6. 性能优化建议字体子集化使用pyftsubset工具只嵌入使用的字符pyftsubset TlwgTypo.ttf --textภาษาไทย --output-fileTlwgTypo-subset.ttf缓存机制对频繁打印的报表启用缓存api.model def render_qweb_pdf(self, docids, dataNone): cache_key freport_{self.id}_{hash(tuple(docids))} cached self.env.cr.cache.get(cache_key) if cached: return cached result super().render_qweb_pdf(docids, data) self.env.cr.cache.set(cache_key, result, timeout3600) return result异步生成对于大批量打印使用队列api.model def generate_reports_async(self, docids): self.env[queue.job].create({ name: Generate Thai Reports, model_name: ir.actions.report, method: render_qweb_pdf, args: (self.id, docids), })7. 常见问题速查表问题现象可能原因解决方案全部显示为方框字体未正确安装执行fc-list部分字符乱码编码声明错误检查模板中的meta charsetUTF-8音调位置错误字体渲染问题添加CSStext-rendering: optimizeLegibility打印速度慢字体文件过大使用字体子集化工具精简字体Docker中无效字体未装入容器在Dockerfile中添加字体安装指令8. 扩展知识多语言打印最佳实践字体选择原则泰文推荐Tlwg Typo, SIPA Arundina中文推荐Noto Sans CJK, Source Han Sans日文推荐IPAexGothic, Noto Sans JP混合语言处理.multilang { font-family: Tlwg Typo, Noto Sans CJK SC, sans-serif; unicode-range: U0E00-0E7F, U4E00-9FFF; }PDF/A合规性# 在报表动作中设置 report_type: pdfa, pdfa_metadata: { Producer: Odoo, Creator: Your Company, },经过这次问题的解决我深刻体会到国际化系统中小语种支持的重要性。特别是在东南亚市场泰文、越南文等带有复杂音调符号的文字处理需要格外注意。建议在项目初期就建立多语言测试用例避免后期大规模返工。