@bendyline/squisq-formats

中文文档
2.8.16发布于 2026/11/08MITTypeScriptES Module构建来源已验证近 30 天下载 6718

文件格式转换器 — DOCX, PDF, OOXML 导入/导出

中文使用文档
文档目录19 节
  1. 安装
  2. 转换方式
  3. 支持的格式
  4. 快速示例
  5. DOCX 数据库
  6. 专题报告
  7. 图表作为图片
  8. HTML 语言
  9. 联布办事处
  10. PPTX 密码
  11. 简历
  12. XLSX 密码
  13. 集装箱 ZIP
  14. 归档导入安全
  15. Doc- 级别召集函数
  16. 程序化 convert()
  17. 子路径导出
  18. 相关软件包
  19. 许可证

@bendyline/squisq-formats (中文(简体) )

Squisq 的文档格式转换器。 在斯奎斯克基于Markdown的文档模式和常见文件格式之间导入和导出——DOCX,PDF,HTML,EPUB,PPTX,XLSX,和CSV. 所有转换器都在浏览器或节点中运行,不需要服务器或本地二进制.

部分 斯奎斯克语Name 单相机.

npm MIT License

安装

npm install @bendyline/squisq-formats @bendyline/squisq

转换方式

所有转换器都使用 Squisq 的 MarkdownDocument AST(从 @bendyline/squisq/markdown)作为枢轴格式:

  • 导入 将文件解析为 MarkdownDocument编辑 xxxToContainer 变体(DOCX、PDF、PPTX)还将嵌入式图像提取到一个 ContentContainer 与减分.
  • 导出 序列化 a MarkdownDocument 打开目标格式。 每种格式还有一个 docToXxx 编号 : xxxToDoc 转换到 MarkdownDocument 内部.

转换保留了文档结构和来源的大部分口味——标题、文本格式、列表、表格、链接、图像,但它们是 不是无损失的回程. 下文列出每个格式的忠诚限度.

所有接受 themeId (DOCX,PDF,EPUB,PPTX,Plain HTML) 应用斯奎斯克主题颜色/打字法,并倒回了道克的前题主题(英语:squisq-theme 编号 : themeId 编号 : theme 键),当该选项被省略时.

对于每个转换器上的统一、格式不可识别的切入点,请使用 格式登记册 财务报告和审定财务报表 convert() (单位:千美元)@bendyline/squisq-formats/registry)——见 程序化 convert() 见下文.

支持的格式

格式导入导出主题子路径
DOCX 数据库 (恶语)✅✅✅@bendyline/squisq-formats/docx
专题报告✅✅✅@bendyline/squisq-formats/pdf
HTML 语言✅✅✅@bendyline/squisq-formats/html
联布办事处 (电子书)—— 说✅✅@bendyline/squisq-formats/epub
PPTX 密码 (PowerPoint) (英语)✅✅✅@bendyline/squisq-formats/pptx
XLSX 密码 (外语)✅页:1—— 说@bendyline/squisq-formats/xlsx
简历✅✅—— 说@bendyline/squisq-formats/csv
集装箱 ZIP✅✅—— 说@bendyline/squisq-formats/container

1 XLSX 导出为 仅限表格 (v1.5)——见 XLSX 密码 节.

快速示例

DOCX 数据库

import {
  markdownDocToDocx,
  docxToMarkdownDoc,
  docxToContainer,
} from '@bendyline/squisq-formats/docx';

// Export: MarkdownDocument → DOCX (ArrayBuffer)
const docxBytes = await markdownDocToDocx(markdownDoc, { title: 'Report', themeId: 'documentary' });

// Import: DOCX (ArrayBuffer | Blob) → MarkdownDocument
const imported = await docxToMarkdownDoc(docxBuffer, { extractImages: true });

// Import with assets: DOCX → ContentContainer (markdown + images/ files)
const container = await docxToContainer(docxBuffer);

忠诚: 导入涵盖标题、段落、内置格式(粗体、斜体、切换、内置代码)、超链接、列表、表格、块引文、代码块、脚注和嵌入式图像(通过 extractImages永远 docxToContainer) (中文(简体) ). 导出嵌入图像时只能通过 options.images;否则,它们作为占位符文本出现.

专题报告

import {
  markdownDocToPdf,
  pdfToMarkdownDoc,
  pdfToContainer,
  configurePdfWorker,
} from '@bendyline/squisq-formats/pdf';

// Configure the PDF.js worker (needed for import in some environments)
configurePdfWorker('/pdf.worker.min.mjs');

// Export: MarkdownDocument → PDF (ArrayBuffer)
const pdfBytes = await markdownDocToPdf(markdownDoc, { pageSize: 'a4' });

// Import: PDF → MarkdownDocument (heuristic structure detection)
const imported = await pdfToMarkdownDoc(pdfBuffer);

// Import with assets: PDF → ContentContainer (markdown + extracted images)
const container = await pdfToContainer(pdfBuffer);

忠诚: 导出使用pdf-lib的标准14字体(themeId 仅影响颜色)。 他们无法编码的文字——希腊语,西里尔语,越南语,箭头,数学,框图,符号——用嵌入的Unicode字体来绘制:被捆绑的DejaVu Sans面相,外加单色的Noto Emoji,Noto Sans SC和Noto Sans KR,用于emoji,中文,日文和韩文,每个都只为需要它而加载并分集的文档unicodeFonts 供给自己的脸,或 false 关掉这个). 这些封面,如泰文等,都没有被替换,一次通过 onWarning. 中日两行字符间断. 换行符 <br> (一个表格单元格唯一可控的行间断),表格列按其内容大小,一个单词对于其行间或字符间的单元格间断太长. 页面保持白色用于打印. 主题文本、标题和链接颜色在遇到4.5:1时与白纸和阴影表头相对照;否则出口商会使用其默认的暗墨来取用这一角色。 这也适用于继承主题和自定义主题. 过 images (由下调的 URL 键入, 如 DOCX 键入) 绘制 PNG 和 JPEG 图像, 在段落中单独显示; 其他图像打印为 [Image: alt] 注释。 PDF 没有语义结构, 因此导入时具有弹性和最佳效果: 标题由字体大小检测出, 表格 / 代码块 / 块 / 链接通过 detectTables 编号 : detectCodeBlocks 编号 : detectBlockquotes 编号 : detectLinks 选项(所有默认为真). pdfToMarkdownDoc 仅为文本; pdfToContainer 还在浏览器和节点中提取嵌入式 XObject 和内置光栅图像,放置 按页数 ——每个图像被插入到其页面上最后一个内容块后(仅图像的页面会倒回最接近的上一个有内容的页面,否则文件端). PDF.js 不能曝光的图像, 因为解码像素不会被释放.

图表作为图片

DOCX, EPUB, PDF 和 PPTX 无法绘制美人鱼图或 Squisq 图表, 因此 拥有它们导出图表源为文本 . rasterizeDiagrams 找到每个 图表-人鱼围栏,ASCII diagram编号 :timeline编号 :tree 围栏,以及 {[drawing]}编号 :{[layout]}编号 :{[diagram]} 标题块 - 请求渲染器 a 每一图的PNG,并用每个图替换返回文档 图像加出口商的字节 images 选项。 绘图需要a 浏览器; @bendyline/squisq-react/diagram-pictures 提供渲染器.

import { rasterizeDiagrams } from '@bendyline/squisq-formats/diagrams';
import { createDiagramPictureRenderer } from '@bendyline/squisq-react/diagram-pictures';

const pictured = await rasterizeDiagrams(markdownDoc, createDiagramPictureRenderer());
const docx = await markdownDocToDocx(pictured.markdownDoc, { images: pictured.images });
const pdf = await markdownDocToPdf(pictured.markdownDoc, { images: pictured.images });

// PPTX keeps drawings, timelines and ASCII diagrams as native shapes;
// only Mermaid needs a picture.
const pptx = await docToPptx(doc, { diagramImages: pictured.mermaid });

图形化器无法绘制为源; 导出从未失败 这个 图像条目带有其显示大小( E)width编号 :height 在 CSS 像素中, 照片在2x打印到1x.

HTML 语言

import { PLAYER_BUNDLE } from '@bendyline/squisq-react/standalone-source';
import {
  docToHtml,
  docToHtmlZip,
  markdownDocToPlainHtml,
  htmlToMarkdownDoc,
} from '@bendyline/squisq-formats/html';

// Interactive player export: Doc → single self-contained HTML string
// (player inlined, images as data URIs, timer-based playback — no audio)
const html = docToHtml(doc, { playerScript: PLAYER_BUNDLE, images });

// Interactive player export: Doc → ZIP Blob (external assets + optional audio)
const zipBlob = await docToHtmlZip(doc, { playerScript: PLAYER_BUNDLE, images, audio });

// Static export: MarkdownDocument → semantic HTML page (no player)
const page = markdownDocToPlainHtml(markdownDoc, { themeId: 'warm-earth' });

// Import: HTML → MarkdownDocument (sanitized by default)
const imported = await htmlToMarkdownDoc(htmlString);

将一个文档放在自己的页面内——一个站点头、导航、页脚和样式表——将页面写成带有标准的HTML模板 <slot> 元素并填入:

import { applyHtmlPageTemplate, markdownDocToPlainHtmlParts } from '@bendyline/squisq-formats/html';

// template: <title><slot name="title">Post</slot> · My Blog</title> … <h1><slot name="title"></slot></h1> <slot></slot>
const parts = markdownDocToPlainHtmlParts(markdownDoc);
const page = applyHtmlPageTemplate(
  template,
  {
    bodyHtml: parts.bodyHtml,
    headHtml: parts.featureHeadHtml,
    title: 'Hello',
    values: { date: '2026-10-28' },
  },
  { templatePath: '_templates/post.html', outputPath: 'posts/hello.html' },
);

无名者 <slot> 接受身体(介于 <!-- squisq:content --> 标记,哪些 htmlToMarkdownDoc 在再导入时的荣誉,被命名的槽接收了文本值或保留了倒置子,相对的URL从模板的文件夹重置到页面,模板中的其他所有内容都会被复制为字节.

子路径也输出 markdownDocsToPlainHtmlBundle 编号 : markdownDocsToHtmlBundle (重复多功能ZIP捆绑 .md 链接重写为 .html, (中文(简体) ), htmlToMarkdownDocSync 编号 : htmlToMarkdown和助手(collectImagePaths, (中文(简体) ), collectLinkRefs, (中文(简体) ), inferMimeType) (中文(简体) ).

联布办事处

import { markdownDocToEpub } from '@bendyline/squisq-formats/epub';

// Export: MarkdownDocument → EPUB 3 (ArrayBuffer). No import path.
const epubBytes = await markdownDocToEpub(markdownDoc, {
  title: 'My Book',
  author: 'Jane Doe',
  images, // Map<string, ArrayBuffer> — embedded when provided
  coverImage, // optional JPEG/PNG
});

分会分出H1/H2边界. 提供 audio + 键 audioSegments 生成EPUB 3 Media Overlays(SMIL)用于同步解说.

PPTX 密码

import {
  docToPptx,
  markdownDocToPptx,
  pptxToMarkdownDoc,
  pptxToContainer,
} from '@bendyline/squisq-formats/pptx';

// Export: MarkdownDocument → PPTX (ArrayBuffer)
// slideBreak: 'h1' | 'h2' (default — H1 and H2 both break) | 'heading'
const pptxBytes = await markdownDocToPptx(markdownDoc, { slideBreak: 'h2', images });

// Export: player-ready Doc -> 16:9 PPTX using the slideshow's canonical
// block expansion and materialized visual layers (managed cover included by default)
const visualDeck = await docToPptx(slideshowDoc, { images });

// Import: PPTX → MarkdownDocument (add { extractImages: true } to reference slide images)
const imported = await pptxToMarkdownDoc(pptxBuffer);

// Import with assets: PPTX → ContentContainer (markdown + extracted slide images)
const container = await pptxToContainer(pptxBuffer);

忠诚: markdownDocToPptx 保留内线格式化为 DraigmL 运行. docToPptx 处理模板备份/玩家准备 Doc 作为可视化的甲板:它使用与幻灯片显示视图相同的可渲染区块平整,计时扩展,被管理-覆盖策略,主题,过渡,和可实现的地层堆栈,因此PPTX有相同的幻灯片计数和相匹配的16:9画布. 文本、形状、表格、路径和提供的图像成为可编辑的本地PowerPoint对象;只有浏览器的地图/视频/人造相片层在提供或标有标签的文本倒置时会降解为静态图像。 导入读取幻灯片顺序 ppt/presentation.xml ,并转换每张幻灯片的标题(~H2),正文(~正文列表)和表格. 幻灯片图像提取( v1.5) : 导入现在可以提取幻灯片级别 <p:pic> 位图进入 images/ —— 说 pptxToContainer 返回带有这些文件和力量的容器 extractImages: true时 pptxToMarkdownDoc 默认情况下离开它。 诚实限制: 只有幻灯片级别 <p:pic> 取出位图——布局/主图像、图表、智能艺术和图片填充 没有。 。 。 .

简历

import { csvToMarkdownDoc, markdownDocToCsv, parseCsv } from '@bendyline/squisq-formats/csv';

// Import: CSV (string | ArrayBuffer | Blob) → single-table MarkdownDocument
const tableDoc = await csvToMarkdownDoc(csvText, { delimiter: ',', hasHeader: true });

// Export: serializes one table node to CSV text (the first by default)
const csv = markdownDocToCsv(markdownDoc);
// Pick another table in a multi-table document:
const second = markdownDocToCsv(markdownDoc, { tableIndex: 1 });

自成一体的 RFC-4180 解析器/序列器(不是OOXML). 导出时单元格格式被平整为纯文本 。 导出一个表格——第一个,或 tableIndex (零基数). 远道而来 tableIndex 抛出; 无表格的文档导出为空字符串.

XLSX 密码

import { xlsxToMarkdownDoc, markdownDocToXlsx } from '@bendyline/squisq-formats/xlsx';

// Import: XLSX → MarkdownDocument (one table per sheet; or pick one via `sheet`)
const imported = await xlsxToMarkdownDoc(xlsxBuffer, { sheet: 0 });

// Export: MarkdownDocument → XLSX (ArrayBuffer) — one worksheet per markdown table
const xlsxBytes = await markdownDocToXlsx(markdownDoc);

导出执行(v1.5),只使用表格的忠诚度: 每一次减价 table 成为一个工作表,以最近的前一个标题命名(自动命名) Sheet1, (中文(简体) ), Sheet2,否则). 所有非表内容被删除. 数字外观的单元格被写成数字;其他的则被写成内线字符串. 没有表格的文档产生一个空的(但有效)工作表——导出从不丢出. markdownDocToXlsx 编号 : docToXlsx 现在返回 Promise<ArrayBuffer> (以前投掷/返回) Blob) (中文(简体) ).

集装箱 ZIP

import {
  containerToZip,
  zipToContainer,
  ZipSafetyError,
} from '@bendyline/squisq-formats/container';

// ContentContainer → ZIP Blob (paths preserved)
const zipBlob = await containerToZip(container);

// ZIP → MemoryContentContainer (directories skipped, path traversal rejected)
const container2 = await zipToContainer(zipData, {
  maxUncompressedBytes: 128 * 1024 * 1024,
});

归档导入安全

每次生产ZIP读作"容器ZIP/DBK嗅觉和OOXML后置DOCX", PPTX 和 XLSX 导入“使用一个 JSZip 支持的限定读取会话 。 会议 在通货膨胀之前检查路径和中央目录元数据,然后消费 JSZip的增量成员流,同时分享实际排放的字节预算 包括所有成员。 重复的OOXML部分读取被缓存并充电一次; 并行的流都暂停在第一次失败上 . [Content_Types].xml 在DOM解析前,上限为 1 MiB,每个关系部分为 4 MiB. OoxmlPackage 不透明 : 用 openPackage() 和通过 而不是进入一个原始的JSZip档案.

ZipSafetyLimits 由 zipToContainer 由OOXML继承 导入选项类型 :

外地默认含义
maxEntries10_000中央记录共计,包括目录记录
maxEntryUncompressedBytesmaxUncompressedBytes为一名成员保留的最大排放字节数
maxUncompressedBytes512 * 1024 * 1024整个归档中释放的总字节
maxCompressionRatio1_000一名成员的最大未压缩/压缩比率

失败的是 ZipSafetyError 实例,从软件包根导出 页:1 /container 财务报告和审定财务报表 /ooxml 潜行道. 他们暴露了 code,并酌情 path, (中文(简体) ), limit, (中文(简体) ), actual,以及 cause。稳定代码是 invalid-limit, (中文(简体) ), invalid-archive, (中文(简体) ), unsafe-path, (中文(简体) ), invalid-entry-metadata, (中文(简体) ), too-many-entries, (中文(简体) ), entry-too-large, (中文(简体) ), archive-too-large, (中文(简体) ), compression-ratio-exceeded, (中文(简体) ), size-mismatch, (中文(简体) ), crc-mismatch,以及 decompression-failed。 。 。 .

JSZip的公开暂停是合作性的:它阻止了下一次压缩输入 勾选,但 pako 可能已完成在当前同步状态下已经生成块 勾选。 一旦限值失败,斯奎斯克立即丢弃这些块...” 保留、计算或写入容器.

Doc- 级别召集函数

每种格式也出口 Doc- 处理 Markdown 文档内部转换的关卡:

import { docToDocx, docxToDoc } from '@bendyline/squisq-formats/docx';
import { docToPdf, pdfToDoc } from '@bendyline/squisq-formats/pdf';
import { docToPptx, pptxToDoc } from '@bendyline/squisq-formats/pptx';
import { docToEpub } from '@bendyline/squisq-formats/epub';
import { csvToDoc } from '@bendyline/squisq-formats/csv';
import { xlsxToDoc, docToXlsx } from '@bendyline/squisq-formats/xlsx';

程序化 convert()

@bendyline/squisq-formats/registry (也从包根再出)是一个统一,格式不可知的前门,覆盖每个转换器. 每个格式都是 FormatDefinition 能够将原始字节导入到 MarkdownDocument 转轴和/或再出口; convert() 将任何源常态化为 a Doc,可选择性地应用主题/变换,然后向目标出口商交接。 每个结果都一样 ConversionResult (单位:千美元)bytes + 键 mimeType + 键 suggestedFilename + 键 warnings) (中文(简体) ). 转换器模块可以懒散地装入,因此导入注册时从来不急于捆绑一个重的转换器.

import { convert } from '@bendyline/squisq-formats/registry';

const result = await convert(
  { kind: 'markdown', markdown: '# Hello', baseName: 'greeting' },
  'docx',
);
// result.bytes, result.mimeType, result.suggestedFilename === 'greeting.docx'

ConvertOptions 还接受 themeRegistry 财务报告和审定财务报表 transformRegistry 页:1 用户自定义. transformStyle 可以是样式 id 或 呼叫范围 TransformStyleConfig; 这些选项永远不会改变进程- 全球 状态.

来源是 { kind: 'bytes' | 'markdown' | 'doc', … }; 字节来源是被魔法字节+扩展(通过)所闻的格式 from 跳过). 失败投出结构化 ConversionError 拥有稳定 code (单位:千美元)unknown-format, (中文(简体) ), unsupported-input, (中文(简体) ), unsupported-output, (中文(简体) ), invalid-input, (中文(简体) ), missing-dependency, (中文(简体) ), conversion-failed加上一个 hint。 。 。 .

玩家嵌入的 HTML 导出( E)html 编号 : htmlzip(中文(简体) ) 需要独立的玩家捆绑。 过 resolvePlayerScript,否则你会得到一个 missing-dependency 错误 :

const html = await convert({ kind: 'markdown', markdown: src }, 'html', {
  resolvePlayerScript: () =>
    import('@bendyline/squisq-react/standalone-source').then((m) => m.PLAYER_BUNDLE),
});

也导出 : createRegistry 编号 : defaultRegistry 编号 : defaultFormats, (中文(简体) ), BUILTIN_FORMAT_IDS, (中文(简体) ), ConversionError,则 ConvertSource 编号 : ConvertOptions 编号 : ConversionResult 编号 : FormatDefinition 编号 : FormatRegistry 类型.

子路径导出

子路径目录
@bendyline/squisq-formats/docxDOCX 进出口(+) docxToContainer(中文(简体) )
@bendyline/squisq-formats/pdfPDF 进出口(+) pdfToContainer, (中文(简体) ), configurePdfWorker(中文(简体) )
@bendyline/squisq-formats/html玩家 HTML 导出, 静态 Plain- HTML 导出 + 捆绑, HTML 导入
@bendyline/squisq-formats/html-prepareprepareMarkdownDocForPlainHtml: plain-HTML 页面的数据表和图片
@bendyline/squisq-formats/html-iconsplainHtmlIcons: 内置图标作为平版 HTML 页面的 SVG 大纲
@bendyline/squisq-formats/epubEPUB 3 电子图书导出(带有可选的媒体重叠)
@bendyline/squisq-formats/pptxPPTX 导出 + 导入( 文本/ 列表/ 表格 + 幻灯片图像)
@bendyline/squisq-formats/xlsxXLSX 导入 + 只用表格导出
@bendyline/squisq-formats/csvCSV进出口(RFC 4180)
@bendyline/squisq-formats/ooxml共享OOXML基础设施(包装读取器/写作机、XML公用事业、命名空间)
@bendyline/squisq-formats/diagramsrasterizeDiagrams 编号 : findDiagrams: 图表作为文档导出图片
@bendyline/squisq-formats/containerContentContainer ZIP序列化
@bendyline/squisq-formats/registry登记册格式+程序 convert() (也从根上再出)

包根再导出普通转换器; ./container,平面-HTML/bundle函数, docxToContainer, (中文(简体) ), pdfToContainer, (中文(简体) ), PdfPageSize,图像公用设施只能是子路径.

见全 API 参考 每个签名和选项接口.

软件包说明
@bendyline/squisq (英语)无头核心——计划,模板,空间,标记下,存储
@bendyline/squisq-反应渲染道克的反射组件( +) PLAYER_BUNDLE(中文(简体) )
@bendyline/squisq-cli (英语)squisq CLI — 批量转换 + MP4 渲染
@bendyline/squisq-editor-反应使用原始/ WYSIWYG/ 预览模式进行反应编辑器

许可证

麻省理工学院

版本与发布记录

@bendyline/squisq-formats 共发布 84 个版本,首次发布于 2026/03/16;过去 12 个月发布了 84 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
2.8.16latest2026/11/08今天
2.8.152026/11/07今天
2.8.142026/11/052 天前
2.8.132026/11/053 天前
2.8.122026/11/017 天前
2.8.112026/10/308 天前

关于 @bendyline/squisq-formats 的常见问题

@bendyline/squisq-formats 是什么?

文件格式转换器 — DOCX, PDF, OOXML 导入/导出

如何安装 @bendyline/squisq-formats?

在项目目录运行 npm install @bendyline/squisq-formats,或使用 pnpm add / yarn add / bun add。

@bendyline/squisq-formats 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@bendyline/squisq-formats 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@bendyline/squisq-formats 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js ^22.22.2 || ^24.15.0 || >=26.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@bendyline/squisq-formats 可以商用吗?

@bendyline/squisq-formats 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@bendyline/squisq-formats 的下载量有多少?

根据 npm 官方下载统计,@bendyline/squisq-formats 在 2026/10/08 – 2026/11/06 这 30 天内被下载 6,718 次,日均约 224 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@bendyline/squisq-formats 还在维护吗?

最新版本 2.8.16 发布于 2026/11/08(今天);至今共发布 84 个版本,其中过去 12 个月发布了 84 个;首次发布于 2026/03/16。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。