CodeBlog

nodejs 生成pdf

https://pptr.dev/

https://github.com/puppeteer/puppeteer


pnpm add puppeteer # Downloads compatible Chrome during installation.
pnpm add puppeteer-core # Alternatively, install as a library, without downloading Chrome.


const fs = require('fs');
const http = require('http');
const puppeteer = require('puppeteer');
async function getPdf(res) {
    // 启动无头浏览器
   const browser = await puppeteer.launch({ headless: true });
//    this.ctx.logger.info('browser')
   // 打开一个新tab
   const page = await browser.newPage();
   // 设置窗口大小
   await page.setViewport({
     width: 1920,
     height: 1080
   })
//    this.ctx.logger.info('page')
   // 跳转到指定页面
   // const target = 'https://juejin.cn/post/7139047512085626911';
   const target = 'https://pnglog.com/';
   await page.goto(target, {waitUntil: 'networkidle0'});
//    this.ctx.logger.info('page2')


   // 页眉模板(图片使用base64,此处的src的base64为占位值)
   const headerTemplate = `<div
style="width: calc(100% - 28px); margin-top: -13px; font-size:8px;border-bottom:2px solid #e1dafb;padding:6px 14px;display: flex; justify-content: space-between; align-items:center;">
<span style="color: #9a7ff7; font-size: 12px; font-family: my-font;">张博的模板</span>
<img style="width: 80px; height: auto;" src="data:image/png;base64,iVBORw0KGgoAAAxxxxxx" />
</div>`
   // 页脚模板(pageNumber处会自动注入当前页码)
   const footerTemplate = `<div 
style="width:calc(100% - 28px);margin-bottom: -20px; font-size:8px; padding:15px 14px;display: flex; justify-content: space-between; ">
<span style="color: #9a7ff7; font-size: 10px;">蒲公英绩效</span>
<span style="color: #9a7ff7; font-size: 13px;" class="pageNumber"></span> 
</div>`;
   // 拿到PDF文件流
   const pdf = await page.pdf({
     headerTemplate,
     footerTemplate,
     margin: {
         top: 50,
         bottom: 50,
         left: 0,
         right: 0
     },
     displayHeaderFooter: true,
     printBackground: true,
   });


    await browser.close();

    fs.writeFileSync('test.pdf', pdf); // 保存到本地文件
    res.setHeader('Content-Type','application/pdf');
    res.setHeader('Content-Length', pdf.length );
    res.end(pdf);
}

const port = 8080;
const server = http.createServer((req, res) => {
    // console.log(res)
    getPdf(res)
});

server.listen(port, () => {
  console.log(`Server running at http://localhost:${port}/`);
});


node server.js


// 图片被截断问题

// page-break-after : auto | always | avoid | left | right

// page-break-before : auto | always | avoid | left | right

// page-break-inside : auto | avoid

// 需要处理的元素样式添加:

// page-break-inside:avoid

// page-break-before: always

// 一般采用向上插入空白占位进行分页以避免元素被分页截断

发布:2025-02-17 14:48:03

修改:2025-02-17 14:52:06

鲁ICP备17013715号 min-Blog powered by ZPHP-MIN