python 基于 docx 文件模板生成 docx 或 PDF 文件

需求背景

提供一个Word 文档模板,使用python程序替换里边的占位符,替换内容包括文本和图片,然后输出docx 或者PDF文件。

功能演示

输入示例

输出示例

实现程序

python 复制代码
import os
import shutil
import subprocess
import time

from docx import Document
from docx.shared import Pt


class DocFiller:
    def __init__(self, doc_file_path, libreoffice_path=None):
        self.doc = Document(doc_file_path)
        self.libreoffice_path = libreoffice_path

    def _process_paragraphs(self, paragraphs, placeholders):
        # 遍历处理每个段落
        for paragraph in paragraphs:
            # 遍历处理每个段落中的每个run
            for run in paragraph.runs:
                self._process_run(run, placeholders)

    @staticmethod
    def _process_run(run, placeholders):
        for placeholder, replacement in placeholders.items():
            # 文本替换
            if isinstance(replacement, str):
                run.text = run.text.replace(placeholder, replacement)
            # 图片替换
            elif isinstance(replacement, tuple) and len(replacement) == 3:
                image_path, width, height = replacement
                if placeholder in run.text:
                    # 保留占位符前后文本,只替换占位符部分
                    texts = run.text.split(placeholder, 1)
                    run.clear()
                    run.add_text(texts[0])
                    run.add_picture(image_path, width=Pt(width), height=Pt(height))
                    run.add_text(texts[1])

    def _process_tables(self, doc_tables, placeholders):
        for table in doc_tables:
            for row in table.rows:
                for cell in row.cells:
                    self._process_paragraphs(cell.paragraphs, placeholders)

    def fill(self, placeholders):
        self._process_paragraphs(self.doc.paragraphs, placeholders)
        self._process_tables(self.doc.tables, placeholders)

    def convert_to_pdf(self, docx_path, pdf_path):
        output_dir = os.path.dirname(pdf_path)
        temp_pdf_path = os.path.join(output_dir, os.path.basename(docx_path).rsplit('.', 1)[0] + '.pdf')

        try:
            subprocess.run([
                self.libreoffice_path, '--headless', '--convert-to', 'pdf:writer_pdf_Export',
                '--outdir', output_dir, docx_path], check=True)
            shutil.move(temp_pdf_path, pdf_path)
            print(f"conversion successful: {pdf_path}")
        except subprocess.CalledProcessError as e:
            print(f"convert the document error: {e}")

    def to_docx(self, outputfile):
        self.doc.save(path_or_stream=outputfile)
        print('to docx complete')

    def to_pdf(self, outputfile):
        temp_file = f'{int(time.time() * 1e6)}.docx'
        self.to_docx(temp_file)
        try:
            self.convert_to_pdf(temp_file, outputfile)
        finally:
            os.remove(temp_file)

        print('to pdf complete')


if __name__ == '__main__':
    liberoffice = 'D:/LibreOffice/program/soffice.exe'
    d = DocFiller('template.docx', liberoffice)
    data = {
        '{{meeting_time}}': '2024年12月12日 下午3点半',
        '{{meeting_address}}': '中央会议室',
        '{{host}}': '小白',
        '{{photo}}': ('./0.png', 80, 80),
        '{{image1}}': ('./1.jpg', 8, 8),
        '{{image2}}': ('./2.jpg', 300, 200)
    }
    d.fill(data)
    # 生成docx文件
    # d.to_docx('data/output.docx')
    # 生成pdf文件
    d.to_pdf('data/output.pdf')

说明

  1. 本程序依赖python-docx 库和liberoffice ,可以实现docx文件模板内容替换。
  2. 如果替换后只需生成Word 文档,则无需安装liberoffice ,也不用指定liberoffice可执行文件路径。
  3. 如果需要生成PDF 文件,则需要安装liberoffice ,并将程序中的liberoffice可执行文件路径修改为自己的路径。
相关推荐
evans在进步10 分钟前
Spring Boot 工程化核心详解:Parent、Starter、热部署、事务与多数据源
spring boot·后端·python
战略性的菠萝41 分钟前
学习笔记-Numpy知识
python·numpy
总有刁民想爱朕ha1 小时前
零基础Python开发「图片批量转MP4视频」工具,本地离线、免费无水印
开发语言·python·音视频
捧 花1 小时前
FastAPI 基础语法:从一个完整接口理解 Web API 的设计
前端·python·fastapi·middleware
Ming_studying1 小时前
Python批量压缩图片:支持JPG_PNG_WebP、尺寸限制与CSV报告
开发语言·图像处理·python·pillow·图片压缩
大熊背1 小时前
ISP图像处理中大数乘法溢出处理(一)
人工智能·python·算法·溢出处理
何以解忧,唯有..1 小时前
Python协程详解:从生成器到async/await的完整指南
开发语言·python
hhzz1 小时前
智慧校园13类视频异常检测:数据集与预训练模型全攻略
人工智能·pytorch·python·深度学习·目标检测·机器学习
浩腾数字多媒体2 小时前
如何判断专业电子留言厂家适配条件?
大数据·人工智能·python
Source.Liu2 小时前
【A11】基于 PDF 渲染引擎的统一文档界面架构设计
rust·pdf