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

3 分钟学会使用 Puppeteer 将 HTML 转 PDF

方案一、wkhtmltopdf + python

  • https://wkhtmltopdf.org/

不推荐,实测效果不佳,2020已停止维护。

在这里插入图片描述

sudo apt-get install xfonts-75dpi
sudo dpkg -i wkhtmltox_0.12.6.1-2.jammy_amd64.deb 

在这里插入图片描述

在这里插入图片描述

# 使用示例
wkhtmltopdf http://google.com google.pdf

在这里插入图片描述

在这里插入图片描述

方案二、Puppeteer

推荐方案,效果最佳,高度还原浏览器打印效果

pnpm install puppeteer-core# which google-chrome
/usr/bin/google-chrome
const puppeteer = require('puppeteer-core');
const fs = require('fs');
const path = require('path');// 自动检测 Chrome 安装路径(支持 Linux/Windows)
const CHROME_PATHS = ['/usr/bin/google-chrome',      // Debian/Ubuntu 默认路径'/opt/google/chrome/chrome',   // 二进制实际位置'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'
];(async () => {try {// 自动查找可用浏览器路径const executablePath = CHROME_PATHS.find(p => fs.existsSync(p));if (!executablePath) throw new Error('未找到 Chrome 浏览器');const browser = await puppeteer.launch({headless: 'new',          // 启用新一代无头模式executablePath,args: ['--no-sandbox','--disable-setuid-sandbox','--disable-dev-shm-usage','--font-render-hinting=medium' // 提升中文字体渲染质量]});const page = await browser.newPage();// 加载内容(支持本地文件或远程URL)const htmlPath = path.resolve(__dirname, '/home/sam/下载/blender_python_reference_4_4/aud.html');await page.goto(`file://${htmlPath}`, {waitUntil: 'networkidle2',timeout: 30000});// 组合方案:CSS隐藏 + JS移除await page.addStyleTag({content: '.skip-to-content { display: none !important; }'});await page.evaluate(() => {const skipLink = document.querySelector('a.skip-to-content');if (skipLink) skipLink.remove();});// PDF生成配置await page.pdf({path: 'report.pdf',format: 'A4',printBackground: true,displayHeaderFooter: false,margin: {top: '25mm',right: '15mm',bottom: '25mm',left: '15mm'}});console.log('PDF 导出完成');await browser.close();} catch (error) {console.error('运行失败:', error.message);process.exit(1);}
})();

浏览器导出效果:

在这里插入图片描述

在这里插入图片描述

Puppeteer 导出效果:

在这里插入图片描述

在这里插入图片描述

补充:多线程处理导出

pnpm add tinypool
// main.mjs
import Tinypool from 'tinypool';
import fs from 'fs/promises'
import path from 'path'// 创建一个 Tinypool 实例
const pool = new Tinypool({filename: new URL('./worker.mjs', import.meta.url).href, // 指定工作线程文件minThreads: 10, // 设置最小线程数maxThreads: 20, // 设置最大线程数
});// 遍历目录
const folderPath = '/home/sam/MyWorkSpace/SOLIDWORKS/html/sldworksapi';
// const folderPath = '/home/sam/MyWorkSpace/SOLIDWORKS/html/swcommands';
// const folderPath = '/home/sam/MyWorkSpace/SOLIDWORKS/html/swconst';async function getAllFilesAsync(dirPath) {let filesList = [];async function traverse(currentPath) {const files = await fs.readdir(currentPath);for (const file of files) {const fullPath = path.join(currentPath, file);const stats = await fs.stat(fullPath);if (stats.isDirectory()) {await traverse(fullPath); // 递归处理子目录} else if (stats.isFile()) {filesList.push(fullPath); // 收集文件路径}}}await traverse(dirPath);return filesList;
}async function run() {// 遍历文件夹const filesList = await getAllFilesAsync(folderPath);// 使用 Promise.all 并行处理任务const promises = filesList.map(file => pool.run({ htmlPath: file, folderPath: folderPath }));// 等待所有任务完成await Promise.all(promises);// 销毁线程池await pool.destroy();
}await run();
// worker.mjs
import puppeteer from 'puppeteer-core'
import fs1 from 'fs'
import path from 'path'
import { fileURLToPath } from 'url';const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);// 自动检测 Chrome 安装路径(支持 Linux/Windows)
const CHROME_PATHS = ['/usr/bin/google-chrome',      // Debian/Ubuntu 默认路径'/opt/google/chrome/chrome',   // 二进制实际位置'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'
];async function html2pdf(file, folderPath, executablePath) {let flag1 = 0;let flag2 = 0;// 判断文件类型if (file.slice(-4) != '.htm') {flag1 = 1;}if (file.slice(-5) != '.html') {flag2 = 1}if (flag2 + flag1 == 2) {console.log('--> DOC IS NOT A TYPE OF HTML. SKIP');return;}// 判断是否已导出const outputPath = '/home/sam/MyWorkSpace/PDF/SW/sldworksapi' + file.replace(folderPath, '').replace('.htm', '').replace('.html', '') + '.pdf';// const outputPath = '/home/sam/MyWorkSpace/PDF/SW/swcommands' + file.replace(folderPath, '').replace('.htm', '') .replace('.html', '') + '.pdf';// const outputPath = '/home/sam/MyWorkSpace/PDF/SW/swconst' + file.replace(folderPath, '').replace('.htm', '') .replace('.html', '') + '.pdf';if (fs1.existsSync(outputPath)) {console.log('-> Exists. SKIP');return;}// 加载浏览器实例const browser = await puppeteer.launch({headless: 'new',          // 启用新一代无头模式executablePath,args: ['--no-sandbox','--disable-setuid-sandbox','--disable-dev-shm-usage','--font-render-hinting=medium' // 提升中文字体渲染质量]});const page = await browser.newPage();// 加载内容(支持本地文件或远程URL)const htmlPath = path.resolve(__dirname, file);await page.goto(`file://${htmlPath}`, {waitUntil: 'networkidle2',timeout: 30000});// PDF生成配置await page.pdf({path: outputPath,format: 'A4',printBackground: false,displayHeaderFooter: false,landscape: true,// 横向打印margin: {top: '25mm',right: '15mm',bottom: '25mm',left: '15mm'}});console.log('PDF导出完成');await browser.close();}export default async ({ htmlPath,folderPath }) => {// 自动查找可用浏览器路径const executablePath = CHROME_PATHS.find(p => fs1.existsSync(p));if (!executablePath) throw new Error('未找到 Chrome 浏览器');// 遍历目录// const folderPath = '/home/sam/MyWorkSpace/SOLIDWORKS/html/sldworksapi';// const folderPath = '/home/sam/MyWorkSpace/SOLIDWORKS/html/swcommands';// const folderPath = '/home/sam/MyWorkSpace/SOLIDWORKS/html/swconst';await html2pdf(htmlPath, folderPath, executablePath);
};

横向打印 PDF,效果不错,直接转了一万多个文档。

在这里插入图片描述

在这里插入图片描述

相关文章:

  • RK3568DAYU开发板-平台驱动开发--UART
  • STP配置
  • 【ConvLSTM第一期】ConvLSTM原理
  • day13 leetcode-hot100-24(链表3)
  • c++ opencv 形态学操作腐蚀和膨胀
  • OpenCV CUDA模块结构分析与形状描述符------在 GPU 上计算图像的原始矩(spatial moments)函数spatialMoments()
  • RV1126-OPENCV Mat理解
  • 基于React和TypeScript的金融市场模拟器开发与模式分析
  • 从 SWT Browser 迁移到 JxBrowser
  • C#·常用快捷键
  • kibana解析Excel文件,生成mapping es导入Excel
  • 职坐标AI算法实战:TensorFlow/PyTorch深度模型
  • Typora-macOS 风格代码块
  • K8S查看pod资源占用和物理机器IP对应关系
  • 小白的进阶之路系列之七----人工智能从初步到精通pytorch自动微分优化以及载入和保存模型
  • 【C++项目】:仿 muduo 库 One-Thread-One-Loop 式并发服务器
  • 解释滚动更新的过程,如何通过`kubectl set image`命令触发更新? 版本回滚的命令是什么?如何查看Deployment的更新历史?
  • 《Python 应用中的蓝绿部署与滚动更新:持续集成中的实践与优化》
  • 【VSCode-Qt】Docker远程连接的项目UI文件在 VSCode 上无法预览
  • 【基于SpringBoot的图书购买系统】操作Jedis对图书图书的增-删-改:从设计到实战的全栈开发指南
  • 网站建设公司江西/2023年6月份疫情严重吗
  • 网上拿手工做的网站/线上营销课程
  • 有了源码怎么做网站/百度pc端网页版
  • 网站建设的七个步骤/百度信息流广告怎么收费
  • 网站开发 微信 支付/什么是推广
  • 门户网站建设所需条件/chrome浏览器下载安卓手机