You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo 17中如何将Excel转为PDF并实现下载?

Odoo 17 Excel转PDF下载实现及对齐问题解决方案

一、是否支持Excel转PDF直接下载?是否必须用XML报表?

完全支持,不需要强制使用XML报表。你可以在现有Excel生成逻辑的基础上,通过Python调用外部工具或库将Excel文件转换为PDF,再沿用当前的二进制字段存储+URL下载的流程。

二、现有代码修改实现转PDF

方案1:使用LibreOffice命令行转换(推荐服务器环境)

LibreOffice是跨平台办公套件,支持命令行批量转换Excel到PDF,服务器部署方便且兼容性强,能保留Excel原格式。

步骤:

  1. 服务器安装LibreOffice:

    • Ubuntu/Debian:sudo apt install libreoffice libreoffice-headless libreoffice-calc
    • CentOS/RHEL:sudo yum install libreoffice-headless
  2. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 05:25:23