@quirekit/lit-docx 做两件事:parseDocx 把 DOCX 文件读成 LitAST(一棵普通 JSON 对象组成的文档树),generateDocx 把 LitAST 写回 DOCX。它不依赖任何编辑器,也不读写文件系统,只处理字节,因此同一份代码可以跑在浏览器和 Node 中。它是 QuireKit 商业组件,以编译产物分发:开发与评估免费,免费版可带评估提示用于生产,设置授权码后去除提示;个人、教育、开源项目与小团队可免费申请社区授权码。
安装
lit-docx 目前是预览版,尚未发布到 npm。发布后的安装方式:
pnpm add @quirekit/lit-docx
运行环境要求 Node 18 及以上,或现代浏览器。包同时提供 ESM 与 CommonJS 两种格式。
在浏览器中试一试
下面的示例完全在当前页面中运行。默认载入一份由 lit-docx 生成的示例报告,也可以切换到“我的文件”打开自己的 .docx;解析结果可以看排版预览或 LitAST,再从 LitAST 生成新的 .docx。
读取一个 DOCX
parseDocx 接收完整文件的字节(Uint8Array),返回文档树 ast 与非致命警告 warnings。不是 DOCX 的文件会抛出 DocxPackageError。
先理解两个步骤:拿到文件字节,再解析文档。下面假设 file 是用户通过文件选择器选中的浏览器 File:
import { parseDocx } from '@quirekit/lit-docx'
const bytes = new Uint8Array(await file.arrayBuffer())
const { ast, warnings } = await parseDocx(bytes)
ast 是后续遍历或修改的文档树,warnings 是需要向用户说明的解析问题。Node 中可以用 readFile() 取得字节,解析调用不变。
需要提取段落文字时,再看以下完整模块:recipes/read-text.ts 负责读文件与调用解析,shared/text.ts 负责遍历文字。
import { readFile } from "node:fs/promises";
import { DocxPackageError, parseDocx } from "@quirekit/lit-docx";
import { collectParagraphText } from "../shared/text";
/**
* Reads a DOCX file and prints its paragraphs and parser warnings.
* @param path - DOCX file on disk.
* @returns Resolves after printing.
*/
export async function printDocx(path: string): Promise<void> {
try {
const { ast, warnings } = await parseDocx(new Uint8Array(await readFile(path)));
for (const line of collectParagraphText(ast)) console.log(line);
for (const warning of warnings) console.warn(`[${warning.code}] ${warning.message}`);
} catch (error) {
// Not a DOCX ZIP package at all, or an encrypted / legacy .doc container.
if (error instanceof DocxPackageError) console.error(`Cannot open ${path}: ${error.code}`);
else throw error;
}
}
这里的 collectParagraphText 只是递归遍历节点:段落与标题的文字都在它们的 text 子节点里。
生成一个 DOCX
LitAST 就是普通对象,可以手写,也可以用包里的 docx 创作辅助函数来写,二者生成的结构完全相同。上面示例里的报告就是这样生成的:标题、带格式的文字、无序列表、带边框和底纹表头的表格、链接,以及带页眉页脚的 A4 页面设置。完整报告由 shared/report.ts 构造;recipes/create-report.ts 只负责生成字节并写入文件。先从一个段落开始,理解生成过程:
import { generateDocx } from '@quirekit/lit-docx'
const bytes = await generateDocx({
type: 'document',
children: [{ type: 'paragraph', children: [{ type: 'text', text: '你好' }] }],
})
返回的 bytes 可以写入 Node 文件,也可以在浏览器中下载。下面按文件查阅完整报告:
import { writeFile } from "node:fs/promises";
import { generateDocx } from "@quirekit/lit-docx";
import { createReport } from "../shared/report";
/**
* Writes the report to disk.
* @param path - Destination `.docx` path.
* @returns Resolves once the file is written.
*/
export async function writeReport(path: string): Promise<void> {
await writeFile(path, await generateDocx(createReport()));
}
接下来
- 读取 DOCX:输入类型、解析选项、警告与错误。
- 生成 DOCX:手写节点与
docx辅助函数,以及单位约定。 - LitAST 节点模型:有哪些节点和标记,各自长什么样。
- 往返与保留:读进来再写回去时,哪些内容会原样保留,哪些不会。
- 支持范围:各项 Word 功能在读取和生成两个方向上的支持情况。