使用 Flask 和 pdfkit 生成带透明 PNG 盖章的 PDF 并上传到阿里云 OSS

news/2025/2/22 9:02:10/

在现代 Web 开发中,生成 PDF 文档并在其上添加盖章是常见的需求。本文将详细介绍如何使用 Flask 框架和 pdfkit 库来批量生成 PDF,并在其中添加透明 PNG 盖章,最后将生成的 PDF 上传到阿里云 OSS(对象存储服务)。

环境准备

首先,确保您的开发环境中已安装以下依赖:

pip install Flask pdfkit Pillow PyPDF2 aliyun-oss2

此外,您还需要安装 wkhtmltopdf,这是 pdfkit 的依赖。根据您的操作系统选择安装方式:

  • Ubuntu:

    sudo apt-get install wkhtmltopdf
    
  • CentOS:

    sudo yum install wkhtmltopdf
    

项目结构

以下是 Flask 应用的基本结构:

/your_project
│
├── app.py               # 主应用文件
├── uploads              # 存放生成的 PDF 文件
└── stamp.png            # 透明 PNG 盖章文件

确保将您的透明 PNG 盖章文件放在项目目录中。

Flask 应用代码

以下是完整的 Flask 应用代码,包含生成 PDF、添加盖章以及上传到 OSS 的功能:

from flask import Flask, request, jsonify, send_file
import pdfkit
import os
from PIL import Image
from werkzeug.utils import secure_filename
import oss2app = Flask(__name__)# 设置上传文件的目录
UPLOAD_FOLDER = 'uploads'
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER# OSS 配置
OSS_ACCESS_KEY_ID = 'your_access_key_id'
OSS_ACCESS_KEY_SECRET = 'your_access_key_secret'
OSS_ENDPOINT = 'your_oss_endpoint'  # 例如 'oss-cn-region.aliyuncs.com'
OSS_BUCKET_NAME = 'your_bucket_name'# 初始化 OSS 客户端
auth = oss2.Auth(OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET)
bucket = oss2.Bucket(auth, OSS_ENDPOINT, OSS_BUCKET_NAME)# PDF 生成函数
def create_pdf(html_content, output_path):pdfkit.from_string(html_content, output_path)# 加盖章函数
def add_stamp_to_pdf(pdf_path, stamp_path, output_path):from PyPDF2 import PdfWriter, PdfReaderstamp = Image.open(stamp_path)stamp.save('temp_stamp.pdf', "PDF")with open(pdf_path, "rb") as pdf_file, open('temp_stamp.pdf', "rb") as stamp_file:pdf_reader = PdfReader(pdf_file)stamp_reader = PdfReader(stamp_file)writer = PdfWriter()for page in pdf_reader.pages:page.merge_page(stamp_reader.pages[0])writer.add_page(page)with open(output_path, "wb") as output_file:writer.write(output_file)# 上传文件到 OSS
def upload_to_oss(file_path, object_name):bucket.put_object_from_file(object_name, file_path)@app.route('/generate_pdf', methods=['POST'])
def generate_pdf():data = request.get_json()if not data or 'html_content' not in data:return jsonify({"error": "Invalid input"}), 400html_content = data['html_content']stamp_path = data.get('stamp_path')  # 可选盖章路径filename = secure_filename('output.pdf')output_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)try:create_pdf(html_content, output_path)if stamp_path:output_path_with_stamp = os.path.join(app.config['UPLOAD_FOLDER'], 'stamped_' + filename)add_stamp_to_pdf(output_path, stamp_path, output_path_with_stamp)# 上传到 OSSupload_to_oss(output_path_with_stamp, 'pdfs/' + filename)return send_file(output_path_with_stamp, as_attachment=True)# 上传到 OSSupload_to_oss(output_path, 'pdfs/' + filename)return send_file(output_path, as_attachment=True)except Exception as e:return jsonify({"error": str(e)}), 500@app.route('/batch_generate', methods=['POST'])
def batch_generate():data = request.get_json()if not data or 'html_contents' not in data:return jsonify({"error": "Invalid input"}), 400output_files = []stamp_path = data.get('stamp_path')  # 可选盖章路径for index, html_content in enumerate(data['html_contents']):filename = secure_filename(f'output_{index}.pdf')output_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)try:create_pdf(html_content, output_path)if stamp_path:output_path_with_stamp = os.path.join(app.config['UPLOAD_FOLDER'], 'stamped_' + filename)add_stamp_to_pdf(output_path, stamp_path, output_path_with_stamp)# 上传到 OSSupload_to_oss(output_path_with_stamp, 'pdfs/' + filename)output_files.append(output_path_with_stamp)else:# 上传到 OSSupload_to_oss(output_path, 'pdfs/' + filename)output_files.append(output_path)except Exception as e:return jsonify({"error": f"Failed to generate PDF {index}: {str(e)}"}), 500return jsonify({"message": "PDFs generated and uploaded to OSS", "files": output_files}), 200if __name__ == '__main__':app.run(debug=True)

代码解析

1. 环境设置

在代码中设置了上传文件的目录,并确保该目录存在。

2. OSS 配置

配置阿里云 OSS 的访问密钥和存储桶信息,并初始化 OSS 客户端。

3. PDF 生成函数

使用 pdfkit 从 HTML 内容生成 PDF 文件。

4. 加盖章函数

使用 Pillow 加载透明 PNG 盖章,并使用 PyPDF2 将其添加到生成的 PDF 上。

5. 上传文件到 OSS

创建 upload_to_oss 函数,将生成的 PDF 文件上传到阿里云 OSS。

6. API 端点

  • /generate_pdf:接收单个 HTML 内容和可选的盖章 PNG 路径,生成 PDF 并上传到 OSS。
  • /batch_generate:接收多个 HTML 内容和可选的盖章 PNG 路径,批量生成 PDF 并上传到 OSS。

使用示例

生成单个 PDF

/generate_pdf 发送 POST 请求,包含 HTML 内容和可选的 PNG 图片路径:

{"html_content": "<h1>Hello, World!</h1>","stamp_path": "path/to/stamp.png"
}

批量生成 PDF

/batch_generate 发送 POST 请求,包含多个 HTML 内容和可选的 PNG 图片路径:

{"html_contents": ["<h1>Document 1</h1>","<h1>Document 2</h1>"],"stamp_path": "path/to/stamp.png"
}

注意事项

  • 安全性:妥善管理您的 OSS 密钥信息,避免在公共代码中暴露。
  • OSS 权限:确保您的阿里云 OSS 存储桶具有相应的权限,以允许上传和访问文件。

总结

通过使用 Flask、pdfkit、透明 PNG 图片和阿里云 OSS,您可以轻松地生成带有盖章的 PDF 文档,并将其上传到云端存储。这种方法在处理大量文档时特别有用,可以有效提高工作效率。


http://www.ppmy.cn/news/1573115.html

相关文章

渲染相机设置 pyrender cameralib

目录 cameralib 设置相机 numpy获取相机参数: pyrender设置相机: hmr2渲染设置 multi_hmr获取cam_t cameralib 设置相机 cameralib安装教程: cameralib 安装-CSDN博客 import cameralibcamera = cameralib.Camera.from_fov(fov_degrees=55, imshape=(720,1280))intri…

Java 大视界 -- 开源社区对 Java 大数据发展的推动与贡献(91)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

tomcat html乱码

web tomcat html中文乱码 将html文件改成jsp <% page language"java" contentType"text/html; charsetUTF-8" pageEncoding"UTF-8"%>添加 <meta charset"UTF-8">

机器学习_12 逻辑回归知识点总结

逻辑回归是机器学习中一种重要的分类算法&#xff0c;广泛应用于二分类和多分类问题。它不仅能够预测分类结果&#xff0c;还能提供每个类别的概率估计。今天&#xff0c;我们就来深入探讨逻辑回归的原理、实现和应用。 一、逻辑回归的基本概念 1.1 逻辑回归与线性回归的区别…

pythonrsa加密与sha256加密

这个比较有意思&#xff0c;不过我前端不太熟悉&#xff0c;js也是二懂二懂的。 登录校验 最近的业务涉及到这一块&#xff0c;这边分析前端的源代码、发现涉及两种登录方式。 首先在这边找前端源代码 sha256 xxxx: function() {var t a("6c27").sha256;l["…

你如何利用SIMD(如SSE/AVX)优化图像处理的性能?

SIMD优化问题 1. SIMD 在图像处理中的优化方式2. 典型应用场景3. SIMD 的常见优化技巧4. 总结 利用 SIMD&#xff08;Single Instruction, Multiple Data&#xff09; 指令集&#xff08;如 SSE/AVX/AVX2/AVX-512&#xff09;优化图像处理的性能&#xff0c;可以极大地提升计算…

洗衣洗鞋上门预约融合小程序新模式

在传统洗衣洗鞋家政行业中&#xff0c;客户们常需亲临门店&#xff0c;通过抖音团购下单并完成核销&#xff0c;这对于忙碌或不愿出门的顾客而言&#xff0c;实属不便。为优化用户体验&#xff0c;抖音生活服务进行了大胆革新&#xff0c;推出了一城一店新模式。此模式下&#…

C++中的顺序容器(一)

文章目录 顺序容器概述所有容器类型都支持的操作迭代器容器定义与初始化将一个容器初始化为另一个容器的拷贝标准库array具有固定大小 赋值和swap关系运算符 顺序容器的特有操作向顺序容器添加元素访问元素删除元素特殊的forward_list操作改变容器的大小容器操作可能是迭代器失…