导航菜单

PDF 生成

本章将指导你使用 Puppeteer 将简历页面导出为高质量的 A4 PDF。

Puppeteer 简介

Puppeteer 是一个 Node.js 库,它提供了一个高级 API 来控制 Chrome 或 Chromium 浏览器。我们可以利用它来:

  • 在无头浏览器中渲染页面
  • 捕获页面截图
  • 生成 PDF

创建 PDF 生成脚本

创建 scripts/generate-pdf.ts

import puppeteer from 'puppeteer'
import { createServer } from 'vite'
import { resolve } from 'path'

async function generatePDF() {
  console.log('Starting PDF generation...')

  const vite = await createServer({
    configFile: resolve('./vite.config.ts'),
  })
  await vite.listen()

  const port = vite.config.server?.port || 5173
  const url = `http://localhost:${port}`

  console.log(`Vite server running at ${url}`)

  const browser = await puppeteer.launch({
    headless: true,
    args: ['--no-sandbox', '--disable-setuid-sandbox']
  })

  try {
    const page = await browser.newPage()

    await page.setViewport({
      width: 643,
      height: 971,
      deviceScaleFactor: 2
    })

    await page.goto(url, {
      waitUntil: 'networkidle0',
      timeout: 30000
    })

    await page.waitForSelector('#app')
    await new Promise(resolve => setTimeout(resolve, 1000))

    await page.pdf({
      path: 'temp/output.pdf',
      format: 'A4',
      printBackground: true,
      margin: {
        top: '20mm',
        right: '20mm',
        bottom: '20mm',
        left: '20mm'
      }
    })

    console.log('PDF generated successfully: temp/output.pdf')
  } catch (error) {
    console.error('Error generating PDF:', error)
    throw error
  } finally {
    await browser.close()
    await vite.close()
  }
}

generatePDF().catch(console.error)

脚本解析

1. 启动 Vite 开发服务器

const vite = await createServer({
  configFile: resolve('./vite.config.ts'),
})
await vite.listen()

我们动态启动 Vite 开发服务器,这样就不需要手动运行 pnpm dev

2. 设置视口尺寸

await page.setViewport({
  width: 643,
  height: 971,
  deviceScaleFactor: 2
})
  • width: 643:A4 内容区宽度(170mm ≈ 643px @ 96 DPI)
  • height: 971:A4 内容区高度(257mm ≈ 971px @ 96 DPI)
  • deviceScaleFactor: 2:提高清晰度,适合打印

3. 等待页面渲染

await page.goto(url, {
  waitUntil: 'networkidle0',
  timeout: 30000
})

await page.waitForSelector('#app')
await new Promise(resolve => setTimeout(resolve, 1000))
  • networkidle0:等待网络完全空闲
  • waitForSelector('#app'):等待 Vue 应用挂载
  • 额外等待 1 秒确保所有内容渲染完成

4. 生成 PDF

await page.pdf({
  path: 'temp/output.pdf',
  format: 'A4',
  printBackground: true,
  margin: {
    top: '20mm',
    right: '20mm',
    bottom: '20mm',
    left: '20mm'
  }
})
  • format: 'A4':A4 纸张尺寸
  • printBackground: true:打印背景颜色
  • margin:20mm 边距

运行 PDF 生成

执行以下命令生成 PDF:

pnpm pdf

脚本会自动:

  1. 启动 Vite 开发服务器
  2. 在无头浏览器中打开页面
  3. 渲染页面并生成 PDF
  4. 关闭浏览器和服务器
  5. 输出 PDF 到 temp/output.pdf

常见问题

1. PDF 内容不完整

如果 PDF 内容不完整,可以增加等待时间:

await new Promise(resolve => setTimeout(resolve, 2000))

2. 字体或样式问题

确保在 CSS 中使用 @media print 规则:

@media print {
  body {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}

3. 超时错误

如果页面加载超时,可以增加超时时间:

await page.goto(url, {
  waitUntil: 'networkidle0',
  timeout: 60000
})

4. Puppeteer 找不到浏览器

确保已安装 Chromium:

npx puppeteer browsers install chrome

下一步

现在我们已经完成了 PDF 生成功能,接下来我们将在 自定义样式 章节中学习如何定制简历的样式。

搜索