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 及更高分辨率。该尺寸参数控制的是图像的渲染精度,而非幻灯片上的显示大小(后者由以英寸为单位的 w 和 h 参数决定)。
图标库
安装命令:npm install -g react-icons react react-dom sharp
react-icons 中常用的图标集包括:
react-icons/fa- Font Awesomereact-icons/md- Material Designreact-icons/hi- Heroiconsreact-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" });
常见问题
⚠️ 这些问题会导致文件损坏、显示错误或输出异常。请务必避免。
-
切勿在十六进制颜色值中使用“#”符号——这会引发文件损坏。
color: "FF0000" // ✅ CORRECT color: "#FF0000" // ❌ WRONG -
切勿在十六进制颜色字符串中编码透明度值——长度为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 -
使用
bullet: true—— 绝对不要使用“•”之类的 Unicode 符号(否则会导致出现双项目符号)。 -
在数组元素之间或连续的文本段之间,使用
breakLine: true。 -
对于项目符号,避免使用
lineSpacing——它会造成过大的间距;请改用paraSpaceAfter。 -
每次生成演示文稿都需要创建新的实例——切勿重复使用
pptxgen()对象。 -
绝不要在多次调用之间重复使用选项对象——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(), ... }); -
请勿将
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”(中间位置)