SuperAPI AI 工具集

export-pdf

办公与效率

查看项目

更新于 10-16 08:29

技能介绍

用途

export-pdf 用于把 HTML 产物导出为 PDF。它使用 puppeteer 的 Page.pdf(),当源文件是 HTML/CSS/SVG 时输出为无损矢量 PDF。对于多页幻灯片(deck),每个 <section> 对应一页。

为什么用 puppeteer 而不是 Chrome DevTools MCP

资料说明:MCP 没有直接暴露 Page.printToPDF(只有 take_screenshot、list_console_messages、evaluate_script 等)。通过 Node 脚本使用 puppeteer 是确定性的,并且与 /export-pptx 保持一致。

使用前检查(Preflight)

  • Bash(which node) — 必需。
  • Bash(test -d node_modules/puppeteer && echo yes || echo no) — 如果没有,告知用户 /doctor 或运行 npm i -D puppeteer。

使用方式(步骤)

  1. 解析路径:
    • $0 = 输入 HTML(必需)
    • $1 = 输出(默认:把输入扩展名替换为 .pdf)
  2. 如需要,执行 Bash(mkdir -p $(dirname <output>))。
  3. 运行导出脚本: Bash(node scripts/export-pdf.mjs "<input>" "<output>") (脚本位于 scripts/export-pdf.mjs;如果缺失,按下方模板编写。)
  4. 报告文件大小与路径。

脚本模板(scripts/export-pdf.mjs)

#!/usr/bin/env node
// Usage: node export-pdf.mjs <input.html> [output.pdf]
import puppeteer from 'puppeteer';
import { pathToFileURL } from 'node:url';
import path from 'node:path';
import fs from 'node:fs/promises';

const [, , input, output = input.replace(/\.html?$/i, '.pdf')] = process.argv;
if (!input) { console.error('Usage: export-pdf.mjs <input.html> [output.pdf]'); process.exit(1); }

const inAbs = path.resolve(process.cwd(), input);
const outAbs = path.resolve(process.cwd(), output);

const browser = await puppeteer.launch({ args: ['--no-sandbox'] });
const page = await browser.newPage();
await page.goto(pathToFileURL(inAbs).toString(), { waitUntil: 'networkidle0' });

// If it's a deck, set noscale so deck-stage renders at natural dims
const deckDims = await page.evaluate(() => {
  const d = document.querySelector('deck-stage');
  if (!d) return null;
  d.setAttribute('noscale', '');
  return [parseInt(d.getAttribute('width') || '1920', 10), parseInt(d.getAttribute('height') || '1080', 10)];
});

await page.emulateMediaType('print');
const pdfOpts = {
  path: outAbs,
  printBackground: true,
};
if (deckDims) {
  // Deck: one section per page — @media print in deck_stage.js handles page-break
  pdfOpts.width = `${deckDims[0]}px`;
  pdfOpts.height = `${deckDims[1]}px`;
  pdfOpts.pageRanges = '';
} else {
  pdfOpts.format = 'A4';
}

await page.pdf(pdfOpts);
await browser.close();

const stat = await fs.stat(outAbs);
console.log(`wrote ${outAbs} (${(stat.size / 1024).toFixed(1)} KB)`);

说明(Notes)

  • 对于 deck:deck_stage.js 必须在其注入的全局 <style> 中包含 @media print { @page { size: ... } section { page-break-after: always } } —— 资料称已存在。
  • 对于普通页面:默认使用 A4。要覆盖,用户可传入内联 CSS @page { size: letter } 或类似写法。
  • networkidle0 会等待所有网络活动停止 —— 如果产物使用懒加载图片,把超时提高到 15000ms。

适用场景

适用于需要把 HTML 产物(包括多页幻灯片 deck 与普通页面)导出为 PDF 的场合,尤其是希望保留 HTML/CSS/SVG 矢量质量时。

限制

  • 需要 Node 环境与 puppeteer 依赖;缺失时需先安装。
  • 依赖 scripts/export-pdf.mjs 脚本,缺失时需按模板创建。
  • 懒加载图片场景需手动调整超时。
  • 资料未提供收费、价格、平台支持范围等信息。