mcpField
E
export-pdf

export-pdf

github.com/bluzir文档处理10778 次安装27 周前更新
代码仓库

关于 export-pdf

export-pdf 是一项将 HTML 成品导出为 PDF 的技能,适合需要生成文档或幻灯片 PDF 的用户。它通过 Node.js 脚本调用 Puppeteer 生成文件。

主要功能

  1. 01将 HTML 成品导出为 PDF
  2. 02使用 Puppeteer Page.pdf()
  3. 03默认输出为 .pdf 扩展名
  4. 04支持 A4 和内联页面尺寸 CSS

适用场景

  1. 01将 HTML 页面转换为 PDF
  2. 02将幻灯片导出为 PDF

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bluzir/claude-code-design --skill export-pdf

安装后在 Claude Code 中输入/export-pdf确认已加载。

详细介绍

导出 PDF

从 HTML 成品生成 PDF。使用 puppeteer 的 Page.pdf(),当源文件为 HTML/CSS/SVG 时,可生成无损矢量图。

**为什么使用 puppeteer,而不是 Chrome DevTools MCP:**MCP 未直接开放 Page.printToPDF(仅提供 take_screenshot、list_console_messages、evaluate_script 等)。通过 Node 脚本使用 puppeteer,结果更可预测,也与 /export-pptx 保持一致。

预检

  1. Bash(which node) — 必需
  2. Bash(test -d node_modules/puppeteer && echo yes || echo no) — 如果结果为 no,请告知用户运行 /doctor 或执行 npm i -D puppeteer

步骤

  1. 解析路径:

    • $0 = 输入 HTML(必需)
    • $1 = 输出文件(默认:输入文件的 .pdf 扩展名)
    • 如有需要,执行 Bash(mkdir -p $(dirname <output>))
  2. 运行导出脚本:

    Bash(node scripts/export-pdf.mjs "<input>" "<output>")
    

    (脚本位于 scripts/export-pdf.mjs;如果不存在,请按以下模板编写。)

  3. 报告文件大小和路径。

脚本模板(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)`);

说明

  • 对于演示文稿:deck_stage.js 注入的全局 <style> 中必须包含 @media print { @page { size: ... } section { page-break-after: always } } — 已包含。
  • 对于普通页面:默认使用 A4。要覆盖默认设置,用户可以传入内联 CSS,例如 @page { size: letter }。
  • networkidle0 会等待所有网络活动停止 — 如果成品使用延迟加载的图片,请将超时时间增至 15000ms。

评论

支持 Markdown