python实现HTML转PDF

复制代码
import os
import sys
import asyncio
from urllib.parse import urlparse

from pyppeteer import launch


# 直接写你的真实文件路径
INPUT_HTML = r"C:\Users\70292727\Desktop\test\报价单.html"
OUTPUT_PDF = r"C:\Users\70292727\Desktop\test\报价单.pdf"
BROWSER_EXE = r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"


def is_url(path: str) -> bool:
    """判断是否为 URL"""
    if not path:
        return False
    parsed = urlparse(path)
    return parsed.scheme in ("http", "https")


def path_to_file_url(path: str) -> str:
    """本地路径转 file:/// URL"""
    abs_path = os.path.abspath(path)
    return "file:///" + abs_path.replace("\\", "/")


async def html_to_pdf(input_path: str, output_pdf: str, browser_exe: str) -> None:
    if not input_path:
        raise ValueError("input_path 不能为空")
    if not output_pdf:
        raise ValueError("output_pdf 不能为空")
    if not browser_exe:
        raise ValueError("browser_exe 不能为空")

    if not os.path.isfile(browser_exe):
        raise FileNotFoundError(f"浏览器程序不存在:{browser_exe}")

    input_path = os.path.abspath(input_path)
    if not is_url(input_path) and not os.path.isfile(input_path):
        raise FileNotFoundError(f"HTML 文件不存在:{input_path}")

    output_pdf = os.path.abspath(output_pdf)
    output_dir = os.path.dirname(output_pdf)
    if output_dir and not os.path.exists(output_dir):
        os.makedirs(output_dir, exist_ok=True)

    browser = await launch(
        executablePath=browser_exe,
        headless=True,
        autoClose=True,
        args=[
            "--no-sandbox",
            "--disable-setuid-sandbox",
            "--disable-dev-shm-usage",
            "--disable-gpu",
            "--allow-file-access-from-files",
            "--enable-local-file-accesses",
            "--disable-web-security",
        ],
    )

    try:
        page = await browser.newPage()

        if is_url(input_path):
            print(f"检测到输入为网页地址:{input_path}")
            await page.goto(input_path, {"waitUntil": "networkidle2"})
        else:
            print(f"检测到输入为本地 HTML 文件:{input_path}")
            file_url = path_to_file_url(input_path)
            await page.goto(file_url, {"waitUntil": "networkidle2"})

        await page.pdf({
            "path": output_pdf,
            "format": "A4",
            "printBackground": True,
            "margin": {
                "top": "15mm",
                "right": "15mm",
                "bottom": "15mm",
                "left": "15mm",
            }
        })

        print(f"PDF 生成成功:{output_pdf}")

    finally:
        await browser.close()


def main():
    try:
        asyncio.run(html_to_pdf(INPUT_HTML, OUTPUT_PDF, BROWSER_EXE))
    except Exception as e:
        print(f"转换失败:{e}")
        sys.exit(1)


if __name__ == "__main__":
    main()
相关推荐
Wang's Blog4 小时前
Java 项目部署之 Docker工具快速入门: 使用 Docker 镜像命令练习
java·docker
CJi0NG4 小时前
【自用】MySQL-存储引擎
数据库·mysql
weixin_460443565 小时前
在线考试人脸识别如何合规?本地活体检测、人脸模板加密与替代认证的技术架构设计
大数据·数据库·煤矿培训考试系统·煤矿在线考试系统·煤矿安全培训·煤矿考试系统
企业数字化笔记5 小时前
多租户系统从哪里开始设计?租户身份、数据隔离、权限与套餐的整体方案
java·spring boot·后端·junit
茶底世界之下5 小时前
羽毛颜色已经很鲜艳,还要继续加色吗?用 Awaking 试一次减饱和
前端·ios·运营
deepseek235 小时前
SQLite WAL 开了仍报 database is locked?Python 后台任务的事务与幂等修复
数据库·python·sqlite·并发编程·wal
tiger从容淡定是人生5 小时前
从 Gemini 的任务示例出发:AI 能否从知识中推导工作流?
java·人工智能·aigc·知识图谱·创业创新·零知识证明
风早爽太5 小时前
Mac 搭建 Vue 开发环境
前端·vue.js
Nebula_g5 小时前
JavaSE高级:动态代理
java·开发语言·算法·javase