Odoo 17中如何将Excel转为PDF并实现下载?
Odoo 17 Excel转PDF下载实现及对齐问题解决方案
一、是否支持Excel转PDF直接下载?是否必须用XML报表?
完全支持,不需要强制使用XML报表。你可以在现有Excel生成逻辑的基础上,通过Python调用外部工具或库将Excel文件转换为PDF,再沿用当前的二进制字段存储+URL下载的流程。
二、现有代码修改实现转PDF
方案1:使用LibreOffice命令行转换(推荐服务器环境)
LibreOffice是跨平台办公套件,支持命令行批量转换Excel到PDF,服务器部署方便且兼容性强,能保留Excel原格式。
步骤:
服务器安装LibreOffice:
- Ubuntu/Debian:
sudo apt install libreoffice libreoffice-headless libreoffice-calc - CentOS/RHEL:
sudo yum install libreoffice-headless
- Ubuntu/Debian:
修改
export_payslip函数添加转换逻辑:
import subprocess import os from tempfile import NamedTemporaryFile def export_payslip(self): this = self[0] # 生成原始Excel二进制数据 xlsx_data = self.create_xlsx_file() # 临时保存Excel到本地磁盘 with NamedTemporaryFile(suffix='.xlsx', delete=False) as tmp_xlsx: tmp_xlsx.write(xlsx_data) tmp_xlsx_path = tmp_xlsx.name # 定义PDF临时文件路径 tmp_pdf_path = tmp_xlsx_path.replace('.xlsx', '.pdf') # 调用LibreOffice命令行转换 subprocess.run([ 'libreoffice', '--headless', '--convert-to', 'pdf', '--outdir', os.path.dirname(tmp_pdf_path), tmp_xlsx_path ], check=True, capture_output=True) # 读取转换后的PDF二进制数据 with open(tmp_pdf_path, 'rb') as f: pdf_data = f.read() # 清理临时文件 os.unlink(tmp_xlsx_path) os.unlink(tmp_pdf_path) # 更新二进制字段与文件名 filename = 'phieu_luong.pdf' this.write({'data': pdf_data, 'export_filename': filename}) # 返回下载动作 return { 'type': 'ir.actions.act_url', 'name': 'report', 'url': '/web/content/hr.payslip/%s/data/%s?download=true' % ( self.id, filename), }
方案2:使用Python库转换(适合简单Excel格式)
如果你的Excel结构简单,可使用xlsx2pdf(Windows环境依赖pywin32)或openpyxl结合reportlab实现转换,但兼容性不如LibreOffice。
三、自定义PDF列单元格对齐问题解决
分两种场景针对性处理:
场景1:用QWeb XML报表生成PDF(若后续改用XML报表方案)
在QWeb模板中通过CSS样式直接指定对齐规则:
- 文本左对齐:
<td style="text-align: left; padding: 4px;">{{ record.name }}</td> - 数字右对齐:
<td style="text-align: right; padding: 4px;">{{ record.amount }}</td> - 全局居中:
<tr style="text-align: center;">...</tr>
若为动态列,可在Python代码中给字段附加对齐属性,或在模板中通过条件判断动态设置样式。
场景2:用Python库(如reportlab)生成PDF
以reportlab为例,通过TableStyle精准控制列对齐:
from reportlab.platypus import Table, TableStyle from reportlab.lib import colors # 构造表格数据 data = [ ["姓名", "基本工资", "奖金"], ["张三", 5000, 1000], ["李四", 6000, 1200] ] # 定义表格样式:指定列对齐、垂直居中 style = TableStyle([ ('ALIGN', (0, 0), (0, -1), 'LEFT'), # 第1列左对齐 ('ALIGN', (1, 0), (2, -1), 'RIGHT'), # 第2、3列右对齐 ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),# 所有单元格垂直居中 ('GRID', (0, 0), (-1, -1), 1, colors.black) # 加边框 ]) table = Table(data) table.setStyle(style)
如果是从Excel转换时要保留对齐,确保Excel源文件的单元格对齐设置正确,LibreOffice转换会完整保留这些格式。
内容的提问来源于stack exchange,提问作者Cris Tuan
相关产品推荐
相关产品推荐

