puppeteer 生成pdf,转成图片
// server.js const express = require('express'); const puppeteer = require('puppeteer'); const app = express(); const port = 8700; // 中间件 app.use(express.json()); app.use(express.urlencoded({ extended: true })); // 启动浏览器实例(单例模式) let browser; async function getBrowser() { if (!browser) { browser = await puppeteer.launch({ headless: 'new', args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', '--disable-gpu' ] }); } return browser; } // 1. GET 接口 - 通过 URL 生成 PDF app.get('/api/generate-pdf', async (req, res) => { try { const { url, filename = 'document.pdf' } = req.query; if (!url) { return res.status(400).json({ error: 'URL parameter is required' }); } const browser = await getBrowser(); const page = await browser.newPage(); await page.goto(url, { waitUntil: 'networkidle2' }); const pdfBuffer = await page.pdf({ format: 'A3', landscape: true, printBackground: true, // margin: { top: '20mm', right: '20mm', bottom: '20mm', left: '20mm' } }); await page.setViewport({ width: 1920, height: 1080, deviceScaleFactor: 1, // 设备像素比,默认1,2为高清 }); await page.screenshot({path: 'screenshot.png'}); await page.close(); // 设置响应头 res.set({ 'Content-Type': 'application/pdf', 'Content-Disposition': `attachment; filename="${filename}"`, 'Content-Length': pdfBuffer.length }); res.send(pdfBuffer); } catch (error) { console.error('Error generating PDF:', error); res.status(500).json({ error: 'Failed to generate PDF', details: error.message }); } }); // 2. POST 接口 - 通过 HTML 内容生成 PDF app.post('/api/generate-pdf-from-html', async (req, res) => { try { const { html, css, filename = 'document.pdf', options = {} } = req.body; if (!html) { return res.status(400).json({ error: 'HTML content is required' }); } const browser = await getBrowser(); const page = await browser.newPage(); // 设置页面内容 const fullHTML = ` <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> ${css || ''} @media print { body { -webkit-print-color-adjust: exact; } } </style> </head> <body> ${html} </body> </html> `; await page.setContent(fullHTML, { waitUntil: 'networkidle0' }); const pdfOptions = { format: options.format || 'A4', printBackground: true, margin: options.margin || { top: '20mm', right: '20mm', bottom: '20mm', left: '20mm' }, ...options }; const pdfBuffer = await page.pdf(pdfOptions); await page.close(); res.set({ 'Content-Type': 'application/pdf', 'Content-Disposition': `attachment; filename="${filename}"`, 'Content-Length': pdfBuffer.length }); res.send(pdfBuffer); } catch (error) { console.error('Error generating PDF from HTML:', error); res.status(500).json({ error: 'Failed to generate PDF', details: error.message }); } }); // 3. 批量生成 PDF 接口 app.post('/api/generate-batch-pdfs', async (req, res) => { try { const { documents } = req.body; if (!Array.isArray(documents) || documents.length === 0) { return res.status(400).json({ error: 'Documents array is required' }); } const browser = await getBrowser(); const results = []; for (const doc of documents) { const page = await browser.newPage(); if (doc.url) { await page.goto(doc.url, { waitUntil: 'networkidle2' }); } else if (doc.html) { await page.setContent(doc.html, { waitUntil: 'networkidle0' }); } const pdfBuffer = await page.pdf(doc.options || {}); await page.close(); results.push({ filename: doc.filename || `document-${Date.now()}.pdf`, buffer: pdfBuffer.toString('base64'), size: pdfBuffer.length }); } res.json({ success: true, count: results.length, documents: results }); } catch (error) { console.error('Error generating batch PDFs:', error); res.status(500).json({ error: 'Failed to generate PDFs', details: error.message }); } }); // 4. 获取 PDF 配置选项接口 app.get('/api/pdf-options', (req, res) => { res.json({ formats: ['Letter', 'Legal', 'Tabloid', 'Ledger', 'A0', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6'], margins: { none: { top: 0, right: 0, bottom: 0, left: 0 }, minimal: { top: '10mm', right: '10mm', bottom: '10mm', left: '10mm' }, standard: { top: '20mm', right: '20mm', bottom: '20mm', left: '20mm' }, large: { top: '40mm', right: '40mm', bottom: '40mm', left: '40mm' } } }); }); // 优雅关闭 process.on('SIGINT', async () => { if (browser) { await browser.close(); } process.exit(0); }); // 启动服务器 app.listen(port, () => { console.log(`PDF Generation API running at http://localhost:${port}`); }); module.exports = app; // const puppeteer = require('puppeteer'); // // async function htmlToPdf() { // const browser = await puppeteer.launch({ headless: true }); // const page = await browser.newPage(); // // 加载 HTML 页面 // await page.goto('http://127.0.0.1', { waitUntil: 'networkidle0' }); // // 生成 PDF // await page.pdf({ // path: 'output.pdf', // 保存路径 // format: 'A4', // 页面格式 // printBackground: true, // 打印背景样式 // }); // await browser.close(); // console.log('PDF 已生成'); // } // htmlToPdf();
转成图片效果更好

浙公网安备 33010602011771号