当前位置: 首页 > news >正文

1-python 自定义模板导出文档-基础实现

使用 Python 根据自定义的 Word 模板和传入的 JSON 数据生成 Word 报告,是自动化文档生成的常见需求。最常用的方法是使用 python-docxdocxtpl 库。其中,docxtpl 是基于 python-docx 的模板引擎,支持 Jinja2 模板语法,非常适合根据模板和数据生成报告。

1. 新建项目、引入依赖

pip install docxtpl

2. 创建word模板

在这里插入图片描述

3. 程序导出word文档

from datetime import datetimefrom docxtpl import DocxTemplate
import jsondef generate_report(template_path, json_data, output_path):# 加载模板doc = DocxTemplate(template_path)# 加载 JSON 数据context = json.loads(json_data) if isinstance(json_data, str) else json_data# 渲染模板doc.render(context)# 保存为新文件doc.save(output_path)print(f"报告已生成:{output_path}")# 使用示例
if __name__ == "__main__":template_file = "./template/test-tempalte01.docx"output_file = "./output/test-output01.docx"# 模拟 JSON 数据data = {"report_title": "测试报告","report_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),"server_infos": [{"server_name": "server01", "ip": "192.168.10.5", "port": 80},{"server_name": "server02", "ip": "192.168.10.6", "port": 80},{"server_name": "server03", "ip": "192.168.10.7", "port": 80}]}generate_report(template_file, data, output_file)

在这里插入图片描述

4. 程序导出PDF

  1. 安装依赖

    pip install docx2pdf
    
  2. 修改程序

    from datetime import datetimefrom docxtpl import DocxTemplate
    from docx2pdf import convert
    import jsondef generate_report(template_path, json_data, output_path, export_pdf=False):# 加载模板doc = DocxTemplate(template_path)# 加载 JSON 数据context = json.loads(json_data) if isinstance(json_data, str) else json_data# 渲染模板doc.render(context)# 保存为Word文件doc.save(output_path)print(f"Word报告已生成:{output_path}")# 如果需要导出PDFif export_pdf:pdf_path = output_path.replace('.docx', '.pdf')convert(output_path, pdf_path)print(f"PDF报告已生成:{pdf_path}")return pdf_pathreturn output_path# 使用示例
    if __name__ == "__main__":template_file = "./template/test-tempalte01.docx"output_file = "./output/test-output01.docx"# 模拟 JSON 数据data = {"report_title": "测试报告","report_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),"server_infos": [{"server_name": "server01", "ip": "192.168.10.5", "port": 80},{"server_name": "server02", "ip": "192.168.10.6", "port": 80},{"server_name": "server03", "ip": "192.168.10.7", "port": 80}]}generate_report(template_file, data, output_file, export_pdf=True)

    此时会同时导出word和pdf文件

    注意:使用docx2pdf会依赖Microsoft Office,所以在Windows环境下可以转换成pdf文件,但是在Linux环境会有问题。需要修改为LibreOffice方案。详见下面步骤。

5. 将程序导出为工具使用(windows)

  1. 安装LibreOffice

    下载地址:https://www.libreoffice.org/download/download-libreoffice/

    安装完成后,将安装目录的program目录添加到Path环境变量。

    # 验证
    soffice --version
    
  2. 修改程序

    from datetime import datetime
    from docxtpl import DocxTemplate
    import json
    import argparse
    import sys
    import os
    import subprocessdef generate_report(template_path, json_data, output_path, export_pdf=False):# 转换路径为绝对路径并规范化template_path = os.path.abspath(template_path)output_path = os.path.abspath(output_path)print(f"执行中, 正在检查模板文件路径: {template_path}")if not os.path.exists(template_path):raise FileNotFoundError(f"执行异常, 模板文件不存在!请检查路径是否正确。\n路径: {template_path}")if not os.path.isfile(template_path):raise FileNotFoundError(f"执行异常, 路径存在,但不是一个文件(可能是目录)。\n路径: {template_path}")file_size = os.path.getsize(template_path)if file_size == 0:raise ValueError(f"执行异常, 模板文件大小为 0,可能是空文件。\n路径: {template_path}")print(f"执行中, 模板文件存在,大小: {file_size} 字节")# === 确保输出目录存在 ===output_dir = os.path.dirname(output_path)  # 根据输出文件的路径获取父目录(导出文件的目录)if output_dir and not os.path.exists(output_dir):print(f"执行中, 输出目录不存在,正在创建: {output_dir}")os.makedirs(output_dir, exist_ok=True)  # 递归创建目录# =============================# 加载模板try:doc = DocxTemplate(template_path)except Exception as e:raise RuntimeError(f"加载模板失败: {e}")# 解析 JSON 数据try:context = json.loads(json_data) if isinstance(json_data, str) else json_data# 添加当前时间(如果模板中使用了 report_time 但未提供)if 'report_time' not in context:context['report_time'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")except json.JSONDecodeError as e:raise ValueError(f"执行异常, JSON 数据解析失败: {e}")# 渲染模板try:doc.render(context)except Exception as e:raise RuntimeError(f"执行异常, 模板渲染失败,请检查上下文变量: {e}")# 保存 Word 文件doc.save(output_path)print(f"执行中, Word报告已生成:{output_path}")# 导出 PDFif export_pdf:try:pdf_path = output_path.replace('.docx', '.pdf')# convert(output_path, pdf_path)convert_to_pdf_with_libreoffice(output_path, pdf_path)print(f"执行中, PDF报告已生成:{pdf_path}")return pdf_pathexcept Exception as e:raise RuntimeError(f"执行异常, 转换PDF失败: {e}")return output_pathdef convert_to_pdf_with_libreoffice(input_docx, output_pdf):"""使用 LibreOffice 将 .docx 转为 .pdf"""# 确保目录存在pdf_dir = os.path.dirname(output_pdf)if pdf_dir and not os.path.exists(pdf_dir):os.makedirs(pdf_dir, exist_ok=True)# 调用 LibreOffice 命令try:subprocess.run(['soffice','--headless','--convert-to', 'pdf','--outdir', pdf_dir,input_docx], check=True, capture_output=True)# LibreOffice 会生成在指定目录,文件名相同,扩展名为 .pdfgenerated_pdf = os.path.join(pdf_dir, os.path.basename(input_docx).rsplit('.', 1)[0] + '.pdf')# 移动或重命名为目标路径(避免同名冲突)if generated_pdf != output_pdf:os.replace(generated_pdf, output_pdf)print(f"执行中, PDF转换成功: {output_pdf}")except subprocess.CalledProcessError as e:raise RuntimeError(f"执行异常, LibreOffice 转换失败: {e.stderr.decode()}")except Exception as e:raise RuntimeError(f"执行异常, 调用 LibreOffice 时出错: {e}")def main():parser = argparse.ArgumentParser(description="从模板和JSON数据生成Word/PDF报告")parser.add_argument('--template', '-t',required=True,help='Word模板文件路径 (.docx)')parser.add_argument('--output', '-o',required=True,help='输出文件路径,例如: ./output/report.docx')parser.add_argument('--data', '-d',required=True,help='JSON格式的数据字符串,或以@开头的文件路径,如: @data.json')parser.add_argument('--pdf',action='store_true',help='是否同时导出PDF文件')args = parser.parse_args()# 支持从文件读取 JSON 数据(以 @ 开头)if args.data.startswith('@'):data_file = args.data[1:]try:with open(data_file, 'r', encoding='utf-8') as f:json_data = f.read()except FileNotFoundError:print(f"执行异常, 数据文件未找到: {data_file}", file=sys.stderr)sys.exit(1)except Exception as e:print(f"执行异常, 读取数据文件失败: {e}", file=sys.stderr)sys.exit(1)else:json_data = args.data# 调用生成函数try:result_path = generate_report(template_path=args.template,json_data=json_data,output_path=args.output,export_pdf=args.pdf)print(f"执行完成: {result_path}")except Exception as e:print(f"执行异常, 生成报告失败: {e}", file=sys.stderr)sys.exit(1)if __name__ == "__main__":main()
    
  3. 导出为可执行程序

    # 安装依赖
    python -m pip install pyinstaller# 导出,此时会生成一个dist目录,可执行文件在此目录中
    pyinstaller main.py --onefile --console --clean# 重命名(可选)
    ren main.exe xxx.exe
    
  4. 组装数据(data.json)

    {"report_title": "测试报告","server_infos": [{"server_name": "server01", "ip": "192.168.10.5", "port": 80},{"server_name": "server02", "ip": "192.168.10.6", "port": 80},{"server_name": "server03", "ip": "192.168.10.7", "port": 80}]
    }
    
  5. 运行exe文件

    # windows 数据使用文件的方式
    main.exe --template "D:/universal_export/universal_export/template/test-template01.docx" --output "D:/universal_export/universal_export/output/test-template01.docx" --data @D:/universal_export/universal_export/data.json --pdf# windows 数据使用字符串的方式
    main.exe --template "D:/universal_export/universal_export/template/test-template01.docx" --output "D:/universal_export/universal_export/output/test-template01.docx" --data "{\"report_title\":\"测试报告\",\"server_infos\":[{\"server_name\":\"server01\",\"ip\":\"192.168.10.5\",\"port\":80},{\"server_name\":\"server02\",\"ip\":\"192.168.10.6\",\"port\":80},{\"server_name\":\"server03\",\"ip\":\"192.168.10.7\",\"port\":80}]}" --pdf
    

6. 将程序导出为工具使用(Centos)

  1. Centos安装python环境

    # 安装依赖
    yum -y groupinstall "Development tools"
    yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel
    yum install -y libffi-devel zlib1g-dev
    yum install zlib* -y# 下载源码包
    cd /opt
    sudo wget https://www.python.org/ftp/python/3.12.6/Python-3.12.6.tgz
    sudo tar -xzf Python-3.12.6.tgz# 创建编译安装目录
    mkdir /usr/local/python3 # 检查openssl版本
    openssl version
    # 对于python 3.12,openssl版本不能低于1.1.1
    # 添加 EPEL 仓库
    yum install -y epel-release
    # 安装较新的 OpenSSL
    yum install -y openssl11 openssl11-devel# 安装
    export CPPFLAGS="-I/usr/include/openssl11"
    export LDFLAGS="-L/usr/lib64/openssl11"
    cd Python-3.12.6
    ./configure --prefix=/usr/local/python3 --with-openssl=/usr --with-openssl-include=/usr/include/openssl11 --with-openssl-lib=/usr/lib64/openssl11 --enable-shared
    make -j$(nproc)
    sudo make install# 配置库路径
    echo '/usr/local/python3/lib' | sudo tee /etc/ld.so.conf.d/python3.conf
    sudo ldconfig# 创建软链接
    ln -s /usr/local/python3/bin/python3 /usr/local/bin/python3
    ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip3# 验证
    python3 -V
    pip3 -V
    python3 -c "import ssl; print(ssl.OPENSSL_VERSION)"# 修改pip源
    cd ~
    mkdir .pip
    cd .pip
    vim pip.conf#进入后添加以下内容,保存退出.
    [global]
    index-url = https://pypi.tuna.tsinghua.edu.cn/simple
    
  2. Centos安装libreoffice

    # 在线安装
    yum install epel-release -y
    yum install libreoffice-headless -y# 验证
    soffice --version
    
  3. 将程序上传至Linux服务器后编译

    # 安装 PyInstaller
    pip3 install pyinstaller# 安装程序所需要的依赖
    pip3 install docxtpl# 打包,命名为universal_export
    python3 -m PyInstaller --onefile --clean --name=universal_export main.py
    
  4. 执行导出命令

    ./universal_export -t template/test-template01.docx -o out/test.docx -d @data.json --pdf
    
http://www.dtcms.com/a/355103.html

相关文章:

  • 【cursor】提示词示范
  • 瑞芯微RK3568与君正X2600e平台Linux系统CS创世SD NAND应用全解析与驱动架构详解
  • springboot Apache PDFBox 通过路径参数读取文件信息流,并转化为pdf 在网页预览
  • 云计算学习100天-第31天
  • vue table 甘特图 vxe-gantt 实现多个表格的任务互相拖拽数据
  • GitHub 热榜项目 - 日榜(2025-08-28)
  • 鸿蒙banner页实现
  • Docker从零学习系列之Docker是什么?
  • Java有几种文件拷贝方式,哪一种效率最高?
  • 【DAB收音机】DAB 信号发生器介绍
  • 从零入门:C 语言操作 MySQL 数据库的完整指南
  • 多模态大模型研究每日简报【2025-08-28】
  • Logstash数据迁移之es-to-kafka.conf详细配置
  • 5G核心网的架构和功能详解
  • 大模型微调技术
  • 自下而上的树形dp
  • Servlet 注解:简化配置的完整指南
  • 隐语Kuscia正式发布 1.0.0 版本,实现支持 Hive 数据源,支持 envoy 日志进行异常分析等功能
  • hive on tez如果是2个大表union会写几次临时文件到hdfs目录,数据量如何计算
  • hive on tez为什么写表时,要写临时文件到hdfs目录
  • 最长连续序列,leetCode热题100,C++实现
  • 解读 AUTOSAR AP R24-11 Manifest 规范 —— 从部署到安全的全流程支撑
  • 可拖拽指令
  • Xray与XPOC工具对比分析
  • 让企业资产管理高效透明——深度解析固定资产管理系统的功能、优势与价值
  • HBase Compaction HFile 可见性和并发安全性分析
  • Docker-compose离线安装
  • 【Canvas与盾牌】“靡不有初,鲜克有终”黄竖条盾牌
  • [ICCV25]TRACE:用3D高斯直接学习物理参数,让AI“推演”未来场景
  • 微硕WINSOK高性能MOS管WSF80P04,助力充电宝效能与安全升级