🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

LibreOffice 演示生成 pawpress/office-ppt

DeepSeek Harness
pawpress10 天前有提交已提供中文文档扫描:含敏感能力

让 DSH 直接驱动本机安装的 LibreOffice 做 PPT —— 通过 UNO 真开一份 Impress…

32.2/100
综合分
3
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/25 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add pawpress/office-ppt
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · other
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 10 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 19 处,展示前 18 条)
  • 读取本地文件
    lib/engine.js:29
    if (explicit && existsSync(explicit)) return explicit;
  • 读取本地文件
    lib/engine.js:32
    if (value && existsSync(value)) return value;
  • 读取本地文件
    lib/engine.js:35
    if (existsSync(candidate)) return candidate;
  • 读取本地文件
    lib/engine.js:48
    if (explicit && existsSync(explicit)) return explicit;
  • 读取本地文件
    lib/engine.js:50
    if (fromEnv && existsSync(fromEnv)) return fromEnv;
  • 读取本地文件
    lib/engine.js:53
    if (existsSync(bundled)) return bundled;
  • 发起网络请求
    lib/engine.js:88
    return worker.request(payload, { timeoutMs, signal });
  • 执行外部命令来自配置/变量
    lib/engine.js:109
    child = spawn(python, ['-X', 'utf8', BRIDGE], {
  • 执行外部命令固定命令
    lib/worker.js:33
    const killer = spawn('taskkill', ['/T', '/F', '/PID', String(pid)], {
  • 执行外部命令来自配置/变量
    lib/worker.js:78
    const child = spawn(this.python, ['-X', 'utf8', BRIDGE, '--serve'], {
  • 读取本地文件
    bin/lo-ppt.mjs:49
    const spec = JSON.parse(await readFile(resolve(target), 'utf8'));
  • 读取本地文件
    lib/store.js:52
    if (fromEnv && existsSync(join(fromEnv, 'package.json'))) return resolve(fromEnv);
  • 读取本地文件
    lib/store.js:57
    if (existsSync(profiles)) return resolve(profiles, process.env.DSH_PROFILE ?? 'desktop');
  • 读取本地文件
    lib/store.js:63
    if (existsSync(join(profile, 'package.json'))) return resolve(profile);
  • 读取本地文件
    lib/store.js:188
    if (!path || !existsSync(path)) return null;
  • 读取本地文件
    lib/store.js:189
    const text = await readFile(path, 'utf8');
  • 读取本地文件
    lib/store.js:196
    if (!path || !existsSync(path)) {
  • 写入本地文件
    lib/store.js:203
    await writeFile(path, next, 'utf8');
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery@deepseek-ai/dsh
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

dsh-plugin 用 LibreOffice 的 UNO 接口处理 pptx,让 DeepSeek Harness 直接生成和编辑 PowerPoint 演示文稿。

README

由 DeepSeek 最新模型翻译生成
office-ppt 让 DSH 直接驱动本机安装的 LibreOffice 做 PPT —— 通过 UNO 真开一份 Impress 文档、真往上画形状,再让 LibreOffice 自己导出 PPTX / ODP / PDF / 逐页 PNG。 不是纯 JS 的 PPTX 写入器:字体、表格、母版、备注页、导出过滤器全走 Impress 那条路,产物和你在桌面上「另存为」得到的是同一种东西。 npm 包名 dsh-lo-office(插件 id 同),仓库名 office-ppt,当前版本 v0.2.0。 装法只要一行:github:pawpress/office-ppt#v0.2.0 —— 详见安装。
展开完整文档(README 剩余 1 节)
office-ppt

让 DSH 直接驱动本机安装的 LibreOffice 做 PPT —— 通过 UNO 真开一份 Impress 文档、真往上画形状,再让 LibreOffice 自己导出 PPTX / ODP / PDF / 逐页 PNG。

不是纯 JS 的 PPTX 写入器:字体、表格、母版、备注页、导出过滤器全走 Impress 那条路,产物和你在桌面上「另存为」得到的是同一种东西。

npm 包名 dsh-lo-office(插件 id 同),仓库名 office-ppt,当前版本 v0.2.0。
装法只要一行:github:pawpress/office-ppt#v0.2.0 —— 详见安装。

lo_build ──▶ python/lo_bridge.py ──▶ UNO socket ──▶ Impress 文档 ──▶ storeToURL ├─ pptx ├─ odp ├─ pdf └─ png × N

English — A DeepSeek Harness plugin that builds presentations by driving the installed LibreOffice over UNO: it opens a real Impress document, draws real shapes, and lets LibreOffice export PPTX / ODP / PDF / per-slide PNG. Not a pure-JS OOXML writer — so fonts, tables, master pages, notes and the export filters are all LibreOffice's own. Five tools: lo_probe, lo_build, lo_render, lo_convert, lo_config. Requires LibreOffice (verified on 26.8.1.1); the bundled Python is used, so no system Python is needed. Ships a settings panel (paths, theme, ratio, formats, timeouts) and keeps one warm soffice process between calls. Package name dsh-lo-office, repository office-ppt. Changelog · MIT

封面

和 dsh-ppt 的区别

| | dsh-ppt | dsh-lo-office |
| PPTX 由谁生成 | 纯 JS(@office-kit/pptx) | 本机 LibreOffice / Impress |
| 需要装 Office 吗 | 不需要 | 需要 LibreOffice |
| 渲染预览 | 依赖外部渲染引擎 | 同一套 LibreOffice 直接出 PDF/PNG |
| 强项 | 零依赖、跨平台、快 | 真 Impress 文档、格式保真、顺手转任意文档 |

两个可以并存:要开箱即用选 dsh-ppt,要「交付的就是 LibreOffice 能打开的那个文件」选这个。

要求

- 本机装有 LibreOffice(Community 版即可)。已在 26.8.1.1 上验证;lo_probe 会告诉你实测结果。
- 插件自己找 soffice:Windows 先查注册表 HKLM\SOFTWARE\LibreOffice\UNO\InstallPath(含 WOW6432Node),再查常见安装路径,最后看环境变量 DSH_LO_SOFFICE / LO_SOFFICE。
- Python 用 LibreOffice 自带的那份(<安装目录>/program/python.exe,带 uno 模块),不需要系统 Python。Linux 上会退回 python3,需要 python3-uno。

安装

不需要发行版(Release)。 装插件只要 git 仓库 + 可选的 tag。

方式一:插件管理器(推荐)

在 设置 → 插件 里粘贴下面任一行,或让助手调用 plugin_manager 的 install_bundle:

github:pawpress/office-ppt # 跟最新 main github:pawpress/office-ppt#v0.2.0 # 锁定版本(推荐)

两种规格都实测可用(pnpm 11.8,装上版本 0.2.0)。

装完确认:

Select-String -Path "$env:APPDATA\DSH Desktop\logs\host\dsh-.log" -Pattern 'dsh-lo-office' | Select-Object -Last 3

期望看到 已注册 5 个工具(…)、2 个斜杠命令。

Release 与 Tag 的区别:装插件只需要 Tag(给 commit 打标记)。Release 是 Tag 加更新说明和附件,纯粹给人看,安装用不到。

方式二:npm(等发布后可用)

dsh-lo-office

一行装完,有版本号和更新提示。目前还没发布到 npm。

方式三:本地开发(改代码用)

1) 把仓库链进 profile 的 node_modules cmd /c mklink /J <profile>\node_modules\dsh-lo-office <仓库路径>

// 2) profile 的 package.json {json
"dependencies": { "dsh-lo-office": "link:D:/dsh1/dsh-lo-office" },
"dsh": { "profile": { "bundles": [ / … */, "dsh-lo-office" ] } }
}

bundle 条目由本仓库自带的 cordis.patch.yml 注入,不需要手改 cordis.yml(它是启动时由 bundles 组合出来的生成物,手改会被覆盖): yaml
- insert:
- id: dsh-lo-office
name: dsh-lo-office
config: {}

⚠️ 改配置一律用编辑器或 [System.IO.File]::WriteAllText + UTF8Encoding($false)。PowerShell 5.1 的 Set-Content -Encoding UTF8 会写 BOM,YAML 解析会挂。

⚠️ 插件源码改动由 HMR 热重载代码,但不会刷新斜杠命令的 UI 列表 —— 那要刷新页面或重启 Desktop。
斜杠命令

在输入框敲 / 就能用的两条命令(不经过模型,不消耗 token):

| 命令 | 作用 |
| /ppt-config | 查看配置 |
| /ppt-config theme=swiss | 改一项 |
| /ppt-config theme=swiss autoFit=off pngWidth=2000 | 改多项 |
| /ppt-config formats=pptx,pdf | 数组用逗号 |
| /ppt-config footer="由 LibreOffice 生成" | 带空格的值用引号 |
| /ppt-config reset | 恢复出厂 |
| /ppt-status | 探测 LibreOffice 是否可用 |

改动写进 profile 的 cordis.patch.yml,重启 Desktop 后生效;要当场生效可以用 lo_config 工具(见下)。

为什么不是设置页

DSH 桌面端(0.1.7)不会给第三方插件渲染设置表单:

- dsh-settings 里写着「每个表单报告 autoGenerate…目前没有已发布的客户端这样做」
- 侧边栏里像「演示文稿」那种条目,是 dsh-ppt 自己写 React 组件注册进 settings.section 的结果,不是自动生成
- 插件的 Config schema 只负责装载时校验,不产出 UI

所以配置面分成两条:给用户的是斜杠命令,给模型的是 lo_config 工具。两者写的是同一份 cordis.patch.yml。

可配置项

| 字段 | 默认 | 说明 |
| soffice | 空(自动探测) | soffice.exe 完整路径 |
| python | 空(用自带的) | 带 uno 模块的 python |
| theme | light | light / dark / slate / warm / swiss / atelier / noir |
| ratio | 16:9 | 16:9 / 4:3 |
| formats | pptx,pdf,png | 默认导出格式,可加 odp |
| pngWidth | 1600 | 逐页 PNG 宽度(320–3840) |
| footer | office-ppt · 由本机 LibreOffice 生成 | 页脚文字,空字符串=不画 |
| pageNumbers | true | 是否显示页码 |
| autoFit | shrink | 自动排版:shrink 缩字号 / off 不干预 |
| minFontSize | 12 | 自动排版最小字号(6–72) |
| timeoutMs | 240000 | 单次调用超时 |
| keepWarm | true | 复用常驻 soffice |
| idleMs | 60000 | 常驻进程空闲回收(毫秒) |

任何字段都能被单次工具调用的同名参数覆盖,配置里的值只是默认值。

自动排版

配置里的 autoFit(默认 shrink)解决「文字塞不下」这个最常见的排版事故:文案一长,字就冲出文本框盖住页脚。

做法不是估字宽——估算是排版事故的最大来源——而是让 LibreOffice 自己排一遍:把文本框的 TextAutoGrowHeight 打开、宽度固定、高度设成极小值,再读回 shape.Size.Height,就得到这段文字在给定宽度下需要多高。放不下就用二分法缩小字号重新量,直到塞进去或触到 minFontSize。

所以:

- 文字放得下 → 一个字都不动;
- 放不下 → 缩到刚好放下的最大字号(实测 10 行要点从 17pt 缩到 13.9pt);
- 缩到下限还放不下 → 保持下限字号并计入 fitOverflow,返回结果里会提示「缩到下限仍放不下,请缩短文案」。

每次 lo_build 的结果里都有 autoFit / fitAdjusted / fitOverflow 三个字段,生成后的汇报也会直接告诉你调了几处、有没有溢出。

为什么不用 LibreOffice 自带的 TextFitToSize:实测 PROPORTIONAL 会把文字放大到填满文本框(小框里出现一个字占半页的巨大字形),AUTOFIT 导出成 后同样依赖对方渲染器。只有「自己量、自己缩」是可控的。

常驻进程

keepWarm 打开时,Node 侧会保持一个 python 桥进程 + 一个无头 soffice(lib/worker.js):

- 请求串行排队,一次 spawn 之后连续用;
- 空闲超过 idleMs 自动回收;
- 进程崩了下次调用自动重起;
- 插件卸载时(dispose)一起收掉,不留孤儿进程。

关掉它就是每次调用重开一遍 —— 排查「是不是状态没清干净」时有用。

取消

lo_build / lo_render / lo_convert / lo_probe 都接了 DSH 的 abort signal:会话里打断,Node 侧会杀掉整棵子进程树(taskkill /T /F),不会留下跑到一半的 soffice。

五个工具 lo_probe

先跑这个。返回 soffice 路径、版本、自带 Python 版本、uno 能否导入,并真的开一份无头 Impress 文档(只探测不实开是骗人的)。参数:soffice(可选,自动探测失败时指定路径)。

lo_build

给标题 + 结构化 slides,拿可编辑 PPTX(可选 ODP / PDF / 逐页 PNG)。

| 参数 | 说明 |
| title | 必填。封面与默认文件名 |
| slides | 必填。幻灯片数组,见下 |
| theme | light(默认)/ dark / slate / warm / swiss / atelier / noir |
| ratio | 16:9(默认)/ 4:3 |
| footer | 页脚文字,默认取设置里的页脚(出厂值 office-ppt · 由本机 LibreOffice 生成) |
| pageNumbers | 是否显示页码,默认 true |
| outputDir | 输出目录,缺省用会话工作目录 |
| fileName | 文件名主干,缺省取标题 |
| formats | 默认 ["pptx","pdf","png"],可用 odp |
| pngWidth | 逐页 PNG 宽度,默认 1600 |
| overwrite | 覆盖同名旧文件,默认 true |

每页字段:layout、title、subtitle、kicker(标题上方小字)、text、bullets、rows(首行为表头的二维数组)、image(绝对路径)、caption(图注,图文版式与整页图都画)、imageSide(left / right,覆盖版式默认的一侧)、notes(讲者备注)。

版式:cover / section / bullets / editorial / statement / quote / table / kpi / index / hero / image / image-left / image-right / closing。缺省 bullets。

其中 editorial / kpi / index / hero 是配合 atelier / noir 的高级版式,只在高级主题下生效;基础主题下会按 bullets 渲染,并在结果里给出 warnings 提示。hero 的配图是可选的——不给 image 就用深色渐变底,不会画占位框。

kpi 的数据可以给两种写法,取前 4 组:

- rows:两列二维数组,第一列是大数字,第二列是说明。[["42%", "效率提升"], ["3.1x", "发布频率"]]
- bullets:每条写成 数值|标签,全角 | 和半角 | 都认。["42%|效率提升", "3.1x|发布频率"]

两种都不给时,本页只画标题,并在 warnings 里明确说明——不会安静地留一张空白页。
json
{
"title": "季度回顾", "theme": "swiss",
"slides": [
{ "layout": "cover", "kicker": "Q3 REVIEW", "title": "季度回顾", "subtitle": "增长、成本与下一步" }, { "layout": "bullets", "title": "三件事", "bullets": ["留存提升", "成本下降", "新渠道跑通"] }, { "layout": "table", "title": "指标", "rows": [["指标", "本季"], ["留存", "72%"], ["成本", "-18%"]] }, { "layout": "quote", "text": "把复杂留给自己。", "subtitle": "设计原则" } ] }

lo_render

把已有的 PPTX / PPT / ODP 渲染成 PDF 和/或逐页 PNG —— 用来肉眼验收刚生成的东西。参数:source(必填)、formats、outputDir、pngWidth。

lo_convert

任意格式互转(docx / xlsx / pptx / odt / ods / odp / pdf …),走 soffice --convert-to。参数:source、to(必填)、outputDir。

lo_config

查看与修改本插件配置 —— DSH 桌面端不渲染第三方插件的设置表单,所以这是唯一的改配置通道。参数:action(show / set / reset)、key+value 或 changes(一次改多项)。
text
lo_config { action: "set", changes: { theme: "swiss", autoFit: "off" } }
→ ✅ 已更新 2 项配置 theme: light → swiss autoFit: shrink → off 磁盘 patch:D:\dsh1\.dsh\profiles\desktop\cordis.patch.yml 已在当前进程生效。

写入是幂等的:只把和出厂默认不同的字段写进 patch,重复设同一个值不会产生改动,也不会碰其它插件条目。

样张

同一份 7 页规格(test/sample-build.json)的产物,2.4 秒生成:

| 封面 | 要点 | 表格 |
| 陈述 | 引文 | 小节 |

命令行

不经过 DSH 也能用: bash
node bin/lo-ppt.mjs probe
node bin/lo-ppt.mjs build test/sample-build.json --formats pptx,pdf,png
node bin/lo-ppt.mjs render test/out/sample.pptx
bash
node bin/lo-ppt.mjs convert 报告.docx --to pdf

装成本地依赖后可以直接 lo-ppt probe(bin 字段已声明)。

测试 bash
npm test # 工具 schema 必须是合法 JSON Schema(不需要 LibreOffice)
npm run test:config # 设置 schema / 归一化兜底 / volatile 容器(不需要 LibreOffice)
npm run test:store # 14 项:lo_config 的 YAML 解析 / 渲染 / 替换 / 字段校验(不需要 LibreOffice)
npm run test:config-tool # 19 项:lo_config 的 show/set/reset 契约与写盘行为(不需要 LibreOffice)
npm run test:commands # 19 项:斜杠命令的解析 / 注册 / 写盘(不需要 LibreOffice)
npm run test:json # 返回值必须过 DSH 的 lossless-JSON 校验
npm run test:autofit # 12 项:自动排版真的缩字 / 真的不误报(需要 LibreOffice)
npm run test:smoke # 28 项:真跑各工具、产物落盘校验

check-json.mjs 优先 import 桌面端自带的 @deepseek-ai/dsh-util-values 校验器(DSH_APP_DIR 可覆盖路径);没有桌面端的机器(CI)自动退回同规则的本地镜像。

CI 见 .github/workflows/ci.yml:三平台跑 schema 检查,Ubuntu 装真 LibreOffice 跑端到端。

性能

7 页 deck(pptx + pdf + 7 张 png)在正常机器上约 2.4–2.6 秒:连接 UNO 0.5s、排版 1.4s、导出累计 2.4s。首次跑要多花 ~10 秒建独立的 LibreOffice 配置目录,之后走缓存。

开了 keepWarm 之后第二次调用起省掉整段 soffice 启动开销 —— 实测同一进程内第二次 build 只要 0.26 秒。

本机实测到过一次异常:某个时刻起 LibreOffice 无论用什么参数、什么 profile,冷启动都卡 32 秒才建 socket(soffice.bin 的 CPU 时间从 t=2s 到 t=22s 一直冻结在 0.39s,说明在等而不是在算;默认用户 profile 也一样)。和本插件无关,是环境侧的问题。常驻进程对这种环境收益最大:第一次 33 秒,之后每次 0.26 秒。

实现里的几个坑(改代码前先看)

- 逐页 PNG 必须切页。无头模式下 FilterData.PageNumber 会被忽略,直接循环导出会得到 N 张一模一样的图。必须 controller.setCurrentPage(pages.getByIndex(i)) 再 storeToURL。
- private:factory/simpress 的默认页是 28000×15750,不是 16:9。建完页要逐页把 page.Width/Height 改成目标几何尺寸,否则按 33867×19050 算出来的页脚会掉到页外被裁掉。
- Windows 路径要转 URL。storeToURL 传原生路径会报 com.sun.star.io.IOException: SfxBaseModel::impl_store … 0x81a(Error Area:Io Class:Parameter Code:26),必须 uno.systemPathToFileUrl()。
- soffice.exe 是 GUI 子系统程序,不接管道:subprocess.run([soffice,'--version'], capture_output=True) 会挂死。用同目录的 soffice.com,并给 stdin=DEVNULL。
- 不要用用户的默认配置目录。插件起的是独立 -env:UserInstallation,否则会抢用户正在开的 Impress,或者被用户开的实例挡住。
- 工具返回值必须是纯 JSON。任何不可枚举的自有属性都会被 DSH 判为 value is not lossless JSON(见 lib/tools.js 里的 renderCwd WeakMap)。
- 工具的 parameters 是原生 JSON Schema,required 必须写成字符串数组;写成 required: true 会让整个请求报 Invalid schema for function。
- soffice.exe 的退出码不等于成功。--convert-to 失败时它照样返回 0,必须检查产物文件在不在、字节数是否非零。
- inject 只能是数组(或「服务名→拦截配置」映射)。写成 { required: [...], optional: [...] } 会被 cordis 当成两个名叫 required/optional 的服务,插件永远卡在 pending (waiting for services),连工具都不会注册。可选服务要用 ctx.inject(['commands'], cb) 子上下文挂。
- 常驻进程要连带杀掉整个进程树。soffice.exe 会再建一个 soffice.bin,只 kill 父进程会留下孤儿,下次启动被它挡住。Windows 上用 taskkill /T /F /PID。

已知边界

- 切页动画:TransitionType / Duration 设置后导出 XML 里确实有 ,但 LibreOffice 自己回读是 0 —— 导出保住,内部回读不保。
- 图表:用 OLE2Shape 做容器导出成 graphicFrame,但空图表回读会少一个形状。要图表就喂真数据。
- SWF 导出:26.8 没有这个过滤器,别试。
- 备注页在 26.8 里没有 com.sun.star.presentation.NotesShape 服务名,是按「备注页上的 Text 形状」写的。
- 只在 Windows + LibreOffice 26.8.1.1 上做过完整验证;macOS / Linux 的路径探测和 CI 已就位,但未人工目视验收。
- 还没有 chart 版式(图表要用 OLE2Shape 喂真数据,见上),也没有「拿现成 pptx 当模板继承」的能力。

排错

1. 先跑 lo_probe。它失败会直接告诉你缺哪一环。
2. LibreOffice 装在非常规位置 → 设 DSH_LO_SOFFICE 指向 soffice.exe,或给 lo_probe 传 soffice 参数。
3. 生成慢或超时 → 检查是不是有别的 soffice 实例占着 socket;插件已经随机端口 + 独立配置档,正常不会撞。
4. 桌面端日志:%APPDATA%\DSH Desktop\logs\host\dsh-<日期>.log,搜 dsh-lo-office。

仓库信息

- 仓库:<https://github.com/pawpress/office-ppt>
- npm 包名 / 插件 id:dsh-lo-office
- 安装规格:github:pawpress/office-ppt

克隆并推送到自己的 fork: bash
git clone https://github.com/pawpress/office-ppt.git
cd office-ppt
npm install # 只为拿 @deepseek-ai/schemastery(设置 schema)
npm run test:all # 需要本机装 LibreOffice

许可

MIT
预览分享卡片长什么样 ↓pawpress/office-ppt
分享 · DeepSeek Harness Hub
pawpress/office-ppt

让 DSH 直接驱动本机安装的 LibreOffice 做 PPT —— 通过 UNO 真开一份 Impress…

这是你的仓库?认领条目

回到顶部