Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

PptxGenJS 教程

设置与基本结构

const pptxgen = require("pptxgenjs");

let pres = new pptxgen();
pres.layout = 'LAYOUT_16x9';  // or 'LAYOUT_16x10', 'LAYOUT_4x3', 'LAYOUT_WIDE'
pres.author = 'Your Name';
pres.title = 'Presentation Title';

let slide = pres.addSlide();
slide.addText("Hello World!", { x: 0.5, y: 0.5, fontSize: 36, color: "363636" });

pres.writeFile({ fileName: "Presentation.pptx" });

布局尺寸

幻灯片尺寸(以英寸为单位):

  • LAYOUT_16x9:10英寸 × 5.625英寸(默认值)
  • LAYOUT_16x10:10英寸 × 6.25英寸
  • LAYOUT_4x3:10英寸 × 7.5英寸
  • LAYOUT_WIDE:13.3英寸 × 7.5英寸

文本与格式设置

// Basic text
slide.addText("Simple Text", {
  x: 1, y: 1, w: 8, h: 2, fontSize: 24, fontFace: "Arial",
  color: "363636", bold: true, align: "center", valign: "middle"
});

// Character spacing (use charSpacing, not letterSpacing which is silently ignored)
slide.addText("SPACED TEXT", { x: 1, y: 1, w: 8, h: 1, charSpacing: 6 });

// Rich text arrays
slide.addText([
  { text: "Bold ", options: { bold: true } },
  { text: "Italic ", options: { italic: true } }
], { x: 1, y: 3, w: 8, h: 1 });

// Multi-line text (requires breakLine: true)
slide.addText([
  { text: "Line 1", options: { breakLine: true } },
  { text: "Line 2", options: { breakLine: true } },
  { text: "Line 3" }  // Last item doesn't need breakLine
], { x: 0.5, y: 0.5, w: 8, h: 2 });

// Text box margin (internal padding)
slide.addText("Title", {
  x: 0.5, y: 0.3, w: 9, h: 0.6,
  margin: 0  // Use 0 when aligning text with other elements like shapes or icons
});

提示: 文本框默认具有内部边距。若需让文本与形状、线条或图标在完全相同的 X 坐标上对齐,可将其 margin 值设置为 0


列表与项目符号

// ✅ CORRECT: Multiple bullets
slide.addText([
  { text: "First item", options: { bullet: true, breakLine: true } },
  { text: "Second item", options: { bullet: true, breakLine: true } },
  { text: "Third item", options: { bullet: true } }
], { x: 0.5, y: 0.5, w: 8, h: 3 });

// ❌ WRONG: Never use unicode bullets
slide.addText("• First item", { ... });  // Creates double bullets

// Sub-items and numbered lists
{ text: "Sub-item", options: { bullet: true, indentLevel: 1 } }
{ text: "First", options: { bullet: { type: "number" }, breakLine: true } }

形状

slide.addShape(pres.shapes.RECTANGLE, {
  x: 0.5, y: 0.8, w: 1.5, h: 3.0,
  fill: { color: "FF0000" }, line: { color: "000000", width: 2 }
});

slide.addShape(pres.shapes.OVAL, { x: 4, y: 1, w: 2, h: 2, fill: { color: "0000FF" } });

slide.addShape(pres.shapes.LINE, {
  x: 1, y: 3, w: 5, h: 0, line: { color: "FF0000", width: 3, dashType: "dash" }
});

// With transparency
slide.addShape(pres.shapes.RECTANGLE, {
  x: 1, y: 1, w: 3, h: 2,
  fill: { color: "0088CC", transparency: 50 }
});

// Rounded rectangle (rectRadius only works with ROUNDED_RECTANGLE, not RECTANGLE)
// ⚠️ Don't pair with rectangular accent overlays — they won't cover rounded corners. Use RECTANGLE instead.
slide.addShape(pres.shapes.ROUNDED_RECTANGLE, {
  x: 1, y: 1, w: 3, h: 2,
  fill: { color: "FFFFFF" }, rectRadius: 0.1
});

// With shadow
slide.addShape(pres.shapes.RECTANGLE, {
  x: 1, y: 1, w: 3, h: 2,
  fill: { color: "FFFFFF" },
  shadow: { type: "outer", color: "000000", blur: 6, offset: 2, angle: 135, opacity: 0.15 }
});

阴影选项:

属性类型取值范围备注
type字符串"outer""inner"
color字符串6位十六进制值(例如 "000000"无需添加 # 前缀,也不支持8位十六进制格式——详见常见错误
blur数字0-100磅
offset数字0-200磅必须为非负值——负数值会导致文件损坏
angle数字0-359度阴影的投射方向(135度表示右下方,270度表示向上)
opacity数字0.0-1.0用于控制透明度,切勿将其编码到颜色字符串中

若需将阴影向上投射(例如在页脚栏上),请使用 angle: 270 并设置正数偏移值——切勿使用负数偏移值。

注意:系统不原生支持渐变填充。建议改用渐变图像作为背景。


图像

图像来源

// From file path
slide.addImage({ path: "images/chart.png", x: 1, y: 1, w: 5, h: 3 });

// From URL
slide.addImage({ path: "https://example.com/image.jpg", x: 1, y: 1, w: 5, h: 3 });

// From base64 (faster, no file I/O)
slide.addImage({ data: "image/png;base64,iVBORw0KGgo...", x: 1, y: 1, w: 5, h: 3 });

图像选项

slide.addImage({
  path: "image.png",
  x: 1, y: 1, w: 5, h: 3,
  rotate: 45,              // 0-359 degrees
  rounding: true,          // Circular crop
  transparency: 50,        // 0-100
  flipH: true,             // Horizontal flip
  flipV: false,            // Vertical flip
  altText: "Description",  // Accessibility
  hyperlink: { url: "https://example.com" }
});

图像尺寸调整模式

// Contain - fit inside, preserve ratio
{ sizing: { type: 'contain', w: 4, h: 3 } }

// Cover - fill area, preserve ratio (may crop)
{ sizing: { type: 'cover', w: 4, h: 3 } }

// Crop - cut specific portion
{ sizing: { type: 'crop', x: 0.5, y: 0.5, w: 2, h: 2 } }

计算尺寸(保持宽高比)

const origWidth = 1978, origHeight = 923, maxHeight = 3.0;
const calcWidth = maxHeight * (origWidth / origHeight);
const centerX = (10 - calcWidth) / 2;

slide.addImage({ path: "image.png", x: centerX, y: 1.2, w: calcWidth, h: maxHeight });

支持的格式

  • 标准格式:PNG、JPG、GIF(动画GIF可在Microsoft 365中使用)
  • SVG格式:可在现代版本的PowerPoint/Microsoft 365中正常使用

图标

建议使用react-icons生成SVG图标,再将其转换为PNG格式,以确保在各类环境中都能正常显示。

设置步骤

const React = require("react");
const ReactDOMServer = require("react-dom/server");
const sharp = require("sharp");
const { FaCheckCircle, FaChartLine } = require("react-icons/fa");

function renderIconSvg(IconComponent, color = "#000000", size = 256) {
  return ReactDOMServer.renderToStaticMarkup(
    React.createElement(IconComponent, { color, size: String(size) })
  );
}

async function iconToBase64Png(IconComponent, color, size = 256) {
  const svg = renderIconSvg(IconComponent, color, size);
  const pngBuffer = await sharp(Buffer.from(svg)).png().toBuffer();
  return "image/png;base64," + pngBuffer.toString("base64");
}

为幻灯片添加图标

const iconData = await iconToBase64Png(FaCheckCircle, "#4472C4", 256);

slide.addImage({
  data: iconData,
  x: 1, y: 1, w: 0.5, h: 0.5  // Size in inches
});

注意:为确保图标清晰显示,建议使用 256 及更高分辨率。该尺寸参数控制的是图像的渲染精度,而非幻灯片上的显示大小(后者由以英寸为单位的 wh 参数决定)。

图标库

安装命令:npm install -g react-icons react react-dom sharp

react-icons 中常用的图标集包括:

  • react-icons/fa - Font Awesome
  • react-icons/md - Material Design
  • react-icons/hi - Heroicons
  • react-icons/bi - Bootstrap Icons

幻灯片背景

// Solid color
slide.background = { color: "F1F1F1" };

// Color with transparency
slide.background = { color: "FF3399", transparency: 50 };

// Image from URL
slide.background = { path: "https://example.com/bg.jpg" };

// Image from base64
slide.background = { data: "image/png;base64,iVBORw0KGgo..." };

表格

slide.addTable([
  ["Header 1", "Header 2"],
  ["Cell 1", "Cell 2"]
], {
  x: 1, y: 1, w: 8, h: 2,
  border: { pt: 1, color: "999999" }, fill: { color: "F1F1F1" }
});

// Advanced with merged cells
let tableData = [
  [{ text: "Header", options: { fill: { color: "6699CC" }, color: "FFFFFF", bold: true } }, "Cell"],
  [{ text: "Merged", options: { colspan: 2 } }]
];
slide.addTable(tableData, { x: 1, y: 3.5, w: 8, colW: [4, 4] });

图表

// Bar chart
slide.addChart(pres.charts.BAR, [{
  name: "Sales", labels: ["Q1", "Q2", "Q3", "Q4"], values: [4500, 5500, 6200, 7100]
}], {
  x: 0.5, y: 0.6, w: 6, h: 3, barDir: 'col',
  showTitle: true, title: 'Quarterly Sales'
});

// Line chart
slide.addChart(pres.charts.LINE, [{
  name: "Temp", labels: ["Jan", "Feb", "Mar"], values: [32, 35, 42]
}], { x: 0.5, y: 4, w: 6, h: 3, lineSize: 3, lineSmooth: true });

// Pie chart
slide.addChart(pres.charts.PIE, [{
  name: "Share", labels: ["A", "B", "Other"], values: [35, 45, 20]
}], { x: 7, y: 1, w: 5, h: 4, showPercent: true });

更美观的图表展示

默认的图表样式略显过时。应用以下设置即可获得现代感强且整洁的视觉效果:

slide.addChart(pres.charts.BAR, chartData, {
  x: 0.5, y: 1, w: 9, h: 4, barDir: "col",

  // Custom colors (match your presentation palette)
  chartColors: ["0D9488", "14B8A6", "5EEAD4"],

  // Clean background
  chartArea: { fill: { color: "FFFFFF" }, roundedCorners: true },

  // Muted axis labels
  catAxisLabelColor: "64748B",
  valAxisLabelColor: "64748B",

  // Subtle grid (value axis only)
  valGridLine: { color: "E2E8F0", size: 0.5 },
  catGridLine: { style: "none" },

  // Data labels on bars
  showValue: true,
  dataLabelPosition: "outEnd",
  dataLabelColor: "1E293B",

  // Hide legend for single series
  showLegend: false,
});

主要样式选项:

  • chartColors: [...] - 系列/数据段的十六进制颜色
  • chartArea: { fill, border, roundedCorners } - 图表背景
  • catGridLine/valGridLine: { color, style, size } - 网格线(设置 style: "none" 可隐藏)
  • lineSmooth: true - 曲线显示(适用于折线图)
  • legendPos: "r" - 图例位置:"b""t""l""r""tr"

幻灯片母版

pres.defineSlideMaster({
  title: 'TITLE_SLIDE', background: { color: '283A5E' },
  objects: [{
    placeholder: { options: { name: 'title', type: 'title', x: 1, y: 2, w: 8, h: 2 } }
  }]
});

let titleSlide = pres.addSlide({ masterName: "TITLE_SLIDE" });
titleSlide.addText("My Title", { placeholder: "title" });

常见问题

⚠️ 这些问题会导致文件损坏、显示错误或输出异常。请务必避免。

  1. 切勿在十六进制颜色值中使用“#”符号——这会引发文件损坏。

    color: "FF0000"      // ✅ CORRECT
    color: "#FF0000"     // ❌ WRONG
    
  2. 切勿在十六进制颜色字符串中编码透明度值——长度为8位的颜色代码(例如 "00000020")会导致文件损坏。请改用 opacity 属性来设置透明度。

    shadow: { type: "outer", blur: 6, offset: 2, color: "00000020" }          // ❌ CORRUPTS FILE
    shadow: { type: "outer", blur: 6, offset: 2, color: "000000", opacity: 0.12 }  // ✅ CORRECT
    
  3. 使用 bullet: true —— 绝对不要使用“•”之类的 Unicode 符号(否则会导致出现双项目符号)。

  4. 在数组元素之间或连续的文本段之间,使用 breakLine: true

  5. 对于项目符号,避免使用 lineSpacing——它会造成过大的间距;请改用 paraSpaceAfter

  6. 每次生成演示文稿都需要创建新的实例——切勿重复使用 pptxgen() 对象。

  7. 绝不要在多次调用之间重复使用选项对象——PptxGenJS 会直接修改对象内容(例如将阴影值转换为 EMU 单位)。如果在多次调用间共享同一个对象,将会破坏后续生成的图形。

    const shadow = { type: "outer", blur: 6, offset: 2, color: "000000", opacity: 0.15 };
    slide.addShape(pres.shapes.RECTANGLE, { shadow, ... });  // ❌ second call gets already-converted values
    slide.addShape(pres.shapes.RECTANGLE, { shadow, ... });
    
    const makeShadow = () => ({ type: "outer", blur: 6, offset: 2, color: "000000", opacity: 0.15 });
    slide.addShape(pres.shapes.RECTANGLE, { shadow: makeShadow(), ... });  // ✅ fresh object each time
    slide.addShape(pres.shapes.RECTANGLE, { shadow: makeShadow(), ... });
    
  8. 请勿将 ROUNDED_RECTANGLE 与带装饰边框的样式一起使用——矩形覆盖条无法覆盖圆角区域。此时应改用 RECTANGLE 样式。

    // ❌ WRONG: Accent bar doesn't cover rounded corners
    slide.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 1, y: 1, w: 3, h: 1.5, fill: { color: "FFFFFF" } });
    slide.addShape(pres.shapes.RECTANGLE, { x: 1, y: 1, w: 0.08, h: 1.5, fill: { color: "0891B2" } });
    
    // ✅ CORRECT: Use RECTANGLE for clean alignment
    slide.addShape(pres.shapes.RECTANGLE, { x: 1, y: 1, w: 3, h: 1.5, fill: { color: "FFFFFF" } });
    slide.addShape(pres.shapes.RECTANGLE, { x: 1, y: 1, w: 0.08, h: 1.5, fill: { color: "0891B2" } });
    

快速参考

  • 形状:RECTANGLE(矩形)、OVAL(椭圆形)、LINE(线条)、ROUNDED_RECTANGLE(圆角矩形)
  • 图表类型:BAR(柱状图)、LINE(折线图)、PIE(饼图)、DOUGHNUT(环形图)、SCATTER(散点图)、BUBBLE(气泡图)、RADAR(雷达图)
  • 布局格式:LAYOUT_16x9(10英寸×5.625英寸)、LAYOUT_16x10、LAYOUT_4x3、LAYOUT_WIDE(宽屏布局)
  • 对齐方式:“left”(左对齐)、“center”(居中对齐)、“right”(右对齐)
  • 图表数据标签位置:“outEnd”(数据端点)、“inEnd”(起始端点)、“center”(中间位置)