npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

gbpptx

v0.2.0

Published

Office-style PowerPoint (pptx) editor: real PresentationML read/write, ribbon UI, slide sorter, presenter view.

Readme

gbpptx

Office 式 PowerPoint 编辑器:真实的 .pptx(PresentationML)读写 + 原生 HTML 界面。打开外部演示文稿、像 PowerPoint 一样查看和编辑、再导出 .pptx,整条链路都走本包自己的 OOXML 内核。

没有 React/Vue,没有 ProseMirror,没有第三方 PPT 库;整个包只依赖 gbooxml 做 ZIP 与 XML。渲染走 DOM + SVG,不使用 <canvas> 元素。

界面一览

标题栏:快速保存 / 撤销 / 重做 / 放映 · 文档名 · 保存状态 · 自动保存 · 设置
Ribbon:文件 | 开始 | 插入 | 设计 | 切换 | 幻灯片放映 | 审阅 | 视图
        + 形状格式 / 图片格式 / 表格(上下文标签)
左窗格:幻灯片缩略图 / 大纲
画布:  多选、框选、吸附参考线、组缩放、旋转、就地文字与表格编辑
右窗格:设置形状格式(大小与位置 / 填充与线条 / 文本 / 图片 / 表格)
底部:  幻灯片浏览 / 阅读视图 / 普通视图 · 备注 · 缩放滑块
  • 文件后台:主页、新建(7 种版式模板)、打开、信息、另存为、导出(PPTX / PDF)、打印、关闭。
  • 开始:剪切/复制/粘贴、新建幻灯片、隐藏、重设、字体/字号/加粗/斜体/下划线/删除线/颜色、项目符号/编号/缩进/行距/对齐、形状库、填充/轮廓/阴影、排列/对齐/分布、查找/替换/全选。
  • 插入:新建幻灯片、表格(Office 式 10×8 尺寸选择器)、图片、18 种形状、文本框、线条、箭头、备注。
  • 设计:6 套主题预览、页面背景、幻灯片大小(16:9 / 4:3)。
  • 切换:无、淡出、推进、擦除、覆盖、分割、缩放;持续时间、应用到全部、预览。
  • 幻灯片放映:从头开始(F5)、从当前页(Shift+F5)、演讲者视图、循环放映、隐藏幻灯片。
  • 审阅:备注窗格、字数统计。
  • 视图:普通 / 幻灯片浏览 / 阅读视图、网格线、参考线、备注、格式窗格、适应窗口、缩放。
  • 就地编辑:双击文本或形状改文字;选中文字后可对部分 run 设字体/字号/颜色/加粗等;双击表格单元格编辑,Tab/Enter 在单元格间移动。
  • 放映:全屏、单击/方向键翻页、B 黑屏、W 白屏、Esc 退出;演讲者视图带计时器、下一页预览和备注。
  • 文件工作流:拖入 .pptx 直接打开;拖入 PNG/JPEG/GIF 直接插图;有本地文件句柄时自动保存;关闭页面前提示未保存更改。

安装与运行

npm install gbpptx
npm start                 # node web/serve.mjs,默认 http://localhost:5274/web/
npm test                  # 内核往返 + 外部 pptx 导入 + XML 合法性测试

web/serve.mjs 是零依赖静态服务器。web/index.html 用 importmap 把 gbooxml 映射到 /vendor/gbooxml/index.js,服务器把该前缀指向同级目录的 gbooxml/src。这个 demo 依赖 monorepo 目录布局;从 npm 单独安装后要把 importmap 指到 node_modules/gbooxml/src/index.js。

页面依次加载 tokens.css、slides.css、office.css,自己装配页面时三份都要引入。

三层结构

| 层 | 入口 | 职责 | | --- | --- | --- | | 模型 | gbpptx/model | 快照结构、画幅、主题、形状/线条/表格/图片/文本工厂、版式、几何 | | 文件 | gbpptx(根入口) | parsePptx 读、buildPptx 写、buildPptxVerified 自检写 | | 界面 | web/ | SlidesApp:Ribbon、窗格、画布、格式窗格、后台视图、放映 |

根入口把模型层与文件层的名字一起导出:

import { createDraft, parsePptx, buildPptxVerified } from 'gbpptx';
import { createSlideWithLayout } from 'gbpptx/model';
import { fontSizeToSz, isPptx } from 'gbpptx/pptx';

通配规则是 ./* → ./src/*.js,深层路径不带 .js。

快速开始

造一份演示文稿并写出 .pptx

import {
  createDraft, createShapeObject, createTableObject, createTextObject,
  buildPptxVerified,
} from 'gbpptx';

const pres = createDraft();                // 960×540,一页空白
pres.title = '季度回顾';
pres.theme = 'midnight';

const slide = pres.slides[0];
const title = createTextObject(80, 60, 1);
title.props.html = '<div>季度回顾</div>';
title.props.fontSize = 40;
slide.objects.push(title);

const shape = createShapeObject('star', 120, 220, 2);
shape.props.text = '重点';
slide.objects.push(shape);

const table = createTableObject(520, 120, 3, 3, 3);
table.props.rows = [['指标', 'Q1', 'Q2'], ['收入', '120', '150'], ['成本', '80', '92']];
table.props.tableStyle = 'banded';
table.props.bandedRows = true;
slide.objects.push(table);

const bytes = await buildPptxVerified(pres);   // Promise<Uint8Array>

buildPptxVerified 写完后会读回来比对画幅、页序、背景、备注、隐藏状态、切换、对象内容与列表结构;不一致会抛错并拒绝写出。只想强行生成用 buildPptx。

读一个外部 .pptx

import { parsePptx, normalizeSnapshot, isPptx } from 'gbpptx';

if (isPptx(bytes)) {
  const raw = await parsePptx(bytes);
  console.log(raw.size, raw.slides.length, raw.warnings);
  const pres = normalizeSnapshot(raw);
}

parsePptx 会:

  • 按 sldSz 保留长宽比缩放到 960/540 基准(4:3 得到 720×540,自定义画幅等比缩放);
  • 从版式/母版继承占位符几何(外部文件标题/正文没有 xfrm 也能落位);
  • 解析主题 clrScheme,把 schemeClr、tx1/bg1/accentN、lumMod/lumOff/tint/shade 落成具体颜色;
  • 把组合形状 grpSp 按组变换摊平成页内元素;
  • 还原真正的项目符号/编号(buChar/buAutoNum → <ul>/<ol>);
  • 读取表格样式、图片裁剪、双端箭头、虚线、切换、隐藏页、备注;
  • 跳过图表/SmartArt/音视频/未知元素,并在 warnings 里计数。

对象模型(v2)

{
  version: 2,
  title: '',
  theme: 'clean',
  size: { w: 960, h: 540 },       // 逻辑像素,保留源画幅
  slides: [{
    id: 's-1',
    bg: '',                        // '' = 跟随主题
    notes: '',
    hidden: false,
    transition: { type: 'fade', dir: 'l', speed: 'med' },
    objects: [{
      id: 'o-1',
      type: 'text',                // text | image | shape | line | table
      x: 120, y: 100, w: 360, h: 110, rot: 0, z: 1,
      props: { /* 按类型 */ },
    }],
  }],
}

z 升序叠放,rot 角度制;线条的 w/h 是从 (x,y) 出发的向量,可为负。

| type | props | | --- | --- | | text | html、font、fontSize、color、align、bold、italic、underline、strike、anchor、lineSpacing、fill、stroke、strokeW | | image | src(data URL)、alt、crop:{l,t,r,b}(百分比)、shadow | | shape | kind、fill、stroke、strokeW、dash、shadow、text、textColor、font、fontSize、bold、italic、underline、strike、align、anchor、lineSpacing | | line | stroke、strokeW、dash、arrowStart、arrowEnd | | table | rows、headerRow、bandedRows、tableStyle、font、fontSize、color、colW、rowH |

  • 18 种形状:矩形、圆角矩形、椭圆、等腰/直角三角形、菱形、平行四边形、梯形、五/六/八边形、五角星、上下左右箭头、V 形、十字形。
  • 4 种表格样式:无样式、标题行、镶边行、深色;样式颜色跟随主题。
  • 7 种切换:无、淡出、推进、擦除、覆盖、分割、缩放。
  • 主题:clean / midnight / ocean / sunset / forest / paper。
  • 文本 HTML 支持 div/p/br/b/strong/i/em/u/s/span/font/ul/ol/li;列表会写成真正的 PowerPoint 项目符号/编号,而不是「• 」字面量。

坐标系与单位

逻辑画布默认 960×540 px,写出为 sldSz 的 EMU(96dpi)。导入 4:3 或自定义画幅时按长宽比换算到 960/540 基准,导出时按快照 size 原样写回。

  • EMU_PER_PX = 9525,pxToEmu / emuToPx 互转。
  • 旋转:模型角度制,OOXML 1/60000 度。
  • 字号:模型 px,OOXML 百分之一磅(× 0.75 × 100)。
  • 界面缩放只改 CSS transform: scale(),模型坐标不变。

导出兼容性

  • 母版/版式是空白版式,所有元素写在页内 spTree,导出即所见即所得。
  • 表格样式落成显式单元格填充/边框;表头文字按主题强调色自动选黑白。
  • 图片按导入时的原始格式内嵌(PNG/JPEG/GIF/SVG/BMP/TIFF/EMF/WMF/WebP),不抓远程 URL。
  • 切换写成 <p:transition>;隐藏页写 show="0"。
  • 写出后自检会重新打开字节并比对;测试还会用严格 XML 解析器检查每个 XML 部件,避免 PowerPoint 的「需要修复」提示。

已知限制

  1. 对象动画(进入/强调/退出)尚未支持;只支持页切换。
  2. 图表、SmartArt、音视频、批注、超链接等元素在导入时会被跳过(warnings 会给出计数),导出不会凭空生成。
  3. 组合形状导入时摊平,导出后不再保留组合语义。
  4. 合并单元格、逐单元格边框/填充、单元格内富文本暂不支持;表格样式按整表近似。
  5. 外部主题的字体方案只取第一个字族;渐变填充按首站近似为纯色,背景图片不导入。
  6. EMF/WMF 等浏览器不能直接解码的图片会在编辑画布里显示为空白,但字节仍会原样导出。
  7. 纯 Node 写出含文本的对象需要 DOM:请挂 jsdom(测试里已这么做);形状/线/表格在裸 Node 可写。
  8. 自检摘要对几何取整到 0.1px,并忽略文本颜色、列宽/行高这类派生值;它是内容级比对,不是逐字节 diff。
  9. 老二进制 .ppt 会被 isPptx 判假(只认 ZIP 魔数并显式排除 OLE 容器)。

开发

node web/serve.mjs           # 默认 5274
node web/serve.mjs 8080      # 或 GBPPTX_PORT=8080
npm test

控制台暴露 window.gbpptx,可直接调 await window.gbpptx.selfTest() 做一次前端全链路自检。

目录

src/kernel/model.js      快照/画幅/主题/形状/版式
src/kernel/read.js       .pptx → 快照(占位符/主题色/组/切换)
src/kernel/write.js      快照 → .pptx
src/kernel/roundtrip.js  写出并读回自检
src/kernel/text.js       HTML ⇄ 段落/run/列表
src/kernel/print.js      A4 横向打印 / PDF 通道
web/app/slides-app.js    编辑器控制器
web/app/ui/              Ribbon/画布/窗格/后台/放映/图标/浮层
web/styles/              tokens / 幻灯片渲染 / Office 外壳
test/                    往返与外部导入测试

许可

MIT