学习必须与实干相结合。——泰戈尔

Kordoc:让韩文办公文档不再困在格式里

项目地址:https://github.com/chrisryugj/kordoc

在很多办公场景中,文档并不只是文字的容器。

它可能是一份层级严密的计划书,一张合并单元格密布的表格,一份带有复杂格式的行政公文,一份需要填写姓名、地址、日期与审批信息的申请表,也可能是一份扫描件、老旧 HWP 文件,或等待比对修订痕迹的新旧版本材料。

这些文档往往有一个共同问题:内容明明就在里面,却不容易被程序真正理解。

Kordoc 选择直面这片复杂地带。它是一套面向 HWP、HWPX、PDF、Office 文档与图像的文档处理工具,能够将内容转换为 Markdown 和结构化数据,并提供文档比较、表单填充、HWPX 生成、格式保留编辑、渲染预览、OCR、隐私信息遮盖与 MCP 工具调用能力。

它的目标并不只是把文件“读出来”,而是尽可能让文档中的结构、表格、页面、格式语义与办公流程重新变得可操作。

从 HWP 到 PDF:把文档翻译成可理解的结构

Kordoc 支持处理多种常见格式:

  • HWP 3.x
  • HWP 5.x
  • HWPX
  • HWPML
  • PDF
  • DOCX
  • XLS
  • XLSX
  • PNG
  • JPG
  • WebP

解析之后,文档可以被转换为 Markdown,也可以得到 IRBlock[] 形式的结构化中间表示。

这意味着输出不只是看起来方便阅读的文本,还可以成为后续程序处理、文档比较、表单识别、RAG 分块、格式编辑与文档生成的基础。

最基础的解析方式如下:

1
2
3
4
5
6
7
8
9
10
11
import { parse } from "kordoc"
import { readFileSync } from "fs"

const result = await parse(readFileSync("사업계획서.hwpx"))

if (result.success) {
result.markdown
result.blocks
result.metadata
result.pages
}

成功解析后,可以获得 Markdown 正文、结构化块数据、文档元信息以及按页拆分的内容。

对于 HWP、HWPX、PDF 与 XLS 系列等能够提供页码或等价页面结构的格式,Kordoc 还能返回页面级内容。XLS 与 XLSX 中,工作表可作为页面单位处理。

文档的页面边界并不总是同样可靠,因此 Kordoc 会通过 metadata.pageMode 标明页面来源。它可以是基于排版缓存的实际页面,也可以是基于章节结构的近似页面。

表格不是附属品,而是文档的骨架

在行政材料、预算表、申请表、计划书与统计文档中,表格常常承载最关键的信息。

但对很多文档工具来说,表格往往是最容易失真的部分。合并单元格、嵌套表格、没有边框的 PDF 表格、复杂布局表格、修订对照表,都可能让原本清晰的结构变成混乱文本。

Kordoc 把表格恢复作为核心能力之一。

它支持还原合并表格与嵌套表格,也能够处理无边框 PDF 表格以及新旧条文对照表。对于 HWPX,README 中给出的数据表明,Kordoc 以原始 HWPX 作为正确结果进行验证,覆盖了 13,041 个 HWPX 表格,并做到单元格级一致。

在 PDF 转 Markdown 的公开基准中,Kordoc 默认配置在阅读顺序、表格、标题与综合评分四项中均位列第一。该测试包含论文、报告、幻灯片与扫描 PDF 共 200 份,并以人工制作的结果作为比对依据。

默认配置的综合得分为 0.960,每页处理时间为 0.52 秒。

如果关闭 OCR,综合得分为 0.937,每页处理时间为 0.04 秒。

对于图像较多的文档,OCR 会带来更完整的文字识别能力,也可能增加处理时间。对于更关注速度的流程,可以关闭 OCR。

不只是转换:文档可以被逐块比较

新旧版本文档之间发生了什么变化,常常比文档本身更重要。

Kordoc 提供文档比较能力,可以在结构化层面比较两份文档,并支持 HWP 与 HWPX 的交叉比较。

1
2
3
4
5
6
import { compare } from "kordoc"

const diff = await compare(旧版本Buffer, 新版本Buffer)

diff.stats
diff.diffs

比较结果中可以得到新增、删除、修改与未变化内容的统计信息。对于表格,比较可以细化到单元格级别。

1
2
3
4
5
6
{
added: 3,
removed: 1,
modified: 5,
unchanged: 42
}

这让文档差异不再只依赖肉眼翻页检查。对于经常面对修订稿、条款调整、预算变更或格式更新的工作流,结构级比较能将注意力集中到真正发生变化的位置。

表单填写,尽量不碰坏原来的样子

很多文档的难点不在于阅读,而在于填写。

一张申请表、一份标准公文、一份带有输入框和提示字段的 HWPX 模板,往往要求填写内容准确,同时又要求字体、字号、对齐方式、表格结构与原始样式保持不变。

Kordoc 支持提取表单字段,也支持将数据填回文档。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { parse, extractFormFields, fillForm } from "kordoc"
import { readFileSync, writeFileSync } from "fs"

const parsed = await parse(buffer)

if (parsed.success) {
const form = extractFormFields(parsed.blocks)
form.fields
form.confidence
}

const filled = await fillForm(
readFileSync("신청서.hwpx"),
{
성명: "홍길동",
주민등록번호: "900101-1234567",
주소: "서울특별시 광진구 능동로 120",
},
"hwpx-preserve"
)

writeFileSync("신청서_작성완료.hwpx", Buffer.from(filled.output as ArrayBuffer))

hwpx-preserve 模式面向 HWPX 原始格式保留场景。填写时,文档原有的字体、字号与对齐方式可以被保留。

Kordoc 还支持提取 HWPX 中的点击填写字段。填写时,会优先根据字段名称匹配,未匹配的键再尝试按照标签查找。

对于一个模板中同一字段可能出现多次的情况,CLI 还提供唯一性约束,用于避免同一个键匹配到多个位置。

1
npx kordoc fill 신청서.hwpx -j 값.json --require-unique

内置标准公文模板,让 Markdown 走向 HWPX

Markdown 很适合撰写内容,但在公文与办公文档场景中,最终交付通常仍需要 HWPX。

Kordoc 支持从 Markdown 生成 HWPX,并支持标题、表格、公式与图表。

1
2
3
4
5
6
7
8
9
10
11
import { markdownToHwpx } from "kordoc"

const hwpx = await markdownToHwpx(`
# 标题

正文内容

| 姓名 | 职级 |
| --- | --- |
| 홍길동 | 과장 |
`)

对于显示公式,Kordoc 可以将支持范围内的 LaTeX 风格公式生成 HWPX 原生公式。

1
2
3
4
5
await markdownToHwpx(`
피타고라스

$$a^2 + b^2 = c^2$$
`)

它还提供面向公文的生成模式,包括多种预设:

  • official
  • report
  • plan
  • notice
  • minutes
  • gaejosik
  • press
  • ministry
  • bangchim

例如,生成报告类文档时可以指定公文预设:

1
2
3
4
5
6
7
8
await markdownToHwpx(
"1. 추진배경\n - 세부 항목\n2. 추진계획",
{
gongmun: {
preset: "보고서",
},
}
)

对于开条式报告风格,还可以设置机构名称、日期、目录、审批栏、页码与正文结束标记。

1
2
3
4
5
6
7
8
9
10
11
12
13
await markdownToHwpx(md, {
gongmun: {
preset: "개조식",
cover: {
org: "기관명",
date: "2026. 7. 11.",
},
toc: true,
approval: ["담당", "팀장", "과장"],
pageNumbers: true,
endMark: false,
},
})

在表格处理上,Kordoc 会按政府文档常见风格应用表头底纹、双下边框与按内容比例分配的列宽。

它还支持提取参考 HWPX 文档中的表格格式配置,并将该配置用于后续生成。

先写 Markdown,再把修改贴回原文

将文档转换成 Markdown 后进行编辑很方便,但如果编辑完成后必须重新手工恢复原始格式,工作就又绕回了起点。

Kordoc 提供格式保留编辑能力。

它可以将修改后的 Markdown 重新应用到原始 HWPX 或 HWP 文档中,只替换发生变化的文字内容,而尽量保留原始样式。

1
npx kordoc patch 原본.hwpx 编辑.md -o 反映.hwpx

在 API 中,也可以使用 patchHwpx 或 patchHwp。

1
import { patchHwpx, patchHwp } from "kordoc"

这种能力适合需要在文本层面进行批量修改,同时又不能轻易破坏原始版式的场景。

文档不必在转换为 Markdown 后彻底脱离原来的容器。它可以经历提取、理解、修改,再回到原有格式体系之中。

让文档直接拥有预览能力

很多格式处理任务最终都需要一个答案:处理后的结果看起来对不对。

Kordoc 提供渲染能力,可以将 HWPX 与 HWP 文档渲染为 SVG、PNG、JPEG、HTML 或 PDF。

对于含有 Hancom 排版缓存的 HWPX 文档,它可以利用缓存尽量保持原始视觉布局。对于没有排版缓存的新生成文档,则可以使用内置重排引擎进行排版。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import {
renderHwpxToSvg,
renderDocument,
extractRenderedRegions,
} from "kordoc"

const rendered = await renderHwpxToSvg(
readFileSync("결재문서.hwpx"),
{
highlights: ["예산"],
}
)

const generated = await renderHwpxToSvg(
generatedHwpx,
{
reflow: true,
}
)

const documentRender = await renderDocument(
"결재문서.hwp",
{
format: "png",
pages: "1-2",
}
)

const crops = await extractRenderedRegions(
"결재문서.hwp",
{
types: ["table"],
}
)

渲染结果中可以包含页面数量、尺寸、文本、图像、表格等统计信息,也可以用于提取表格、图片、段落与图形区域。

CLI 同样支持直接渲染:

1
npx kordoc render 결재문서.hwpx -o 미리보기.svg

也可以按页输出 PNG、JPEG、HTML 或 PDF:

1
npx kordoc render 결재문서.hwpx --format png --pages 2-4 -d ./pages

文档生成、表单填写、格式补丁之后,都可以通过渲染结果进行视觉检查。

OCR 不必依赖云端 API

扫描件和图片 PDF 是文档自动化里最常见的障碍之一。

Kordoc 内置 OCR 能力,可在本地 CPU 上处理扫描 PDF 与图像,并不要求 API 密钥。

1
2
3
await parse(buffer, {
ocr: true,
})

如果需要强制对全部页面执行 OCR,可以使用:

1
2
3
await parse(buffer, {
ocr: "force",
})

它也允许接入外部 OCR 服务:

1
2
3
4
5
await parse(buffer, {
ocr: async (pageImage, pageNumber, mimeType) => {
return myOcrService.recognize(pageImage)
},
})

内置 OCR 使用 PP-OCRv5 korean ONNX 模型,首次使用时会下载约 18MB 的模型。

Kordoc 会识别文本层不存在或质量异常的页面,并提供页面级质量信号。通过这些信号,可以将真正需要 OCR 的页面挑出来,而不必对所有页面采取同一种处理策略。

1
2
3
4
5
6
7
8
9
10
11
12
13
const result = await parsePdf(buffer)

if (result.success && result.qualitySummary?.needsOcr) {
await parse(buffer, {
ocr: true,
})
}

for (const page of result.pageQuality ?? []) {
if (page.needsOcr) {
console.log(`p${page.page} 검토 필요: ${page.ocrReason}`)
}
}

可用的质量信息包括文本字符数、韩文比例、控制字符比例、替换字符比例、私有区字符比例、是否需要 OCR,以及触发判断的原因。

对于扫描件处理来说,这让 OCR 不再是一项笼统的开关,而能成为更有针对性的处理步骤。

图像、表格、页面与 RAG 一起进入知识流程

Kordoc 的输出不止面向人工阅读。

它能够将结构化块转换为 RAG 所需的文档块,并保留标题层级与条目层级形成的 breadcrumb。表格也可以作为独立块存在。

1
npx kordoc 검토서.pdf --format chunks

API 中可以使用:

1
import { blocksToChunks } from "kordoc"

这意味着复杂文档不必只是被切割成无上下文的文本片段。

标题层级、列表层次、表格边界与页面信息可以成为检索结构的一部分。对于包含条例、报告、预算说明、审批材料与层级条目的文档,这种结构化拆分能更贴近原文组织方式。

CLI:把文档能力放进终端工作流

Kordoc 可以作为库使用,也可以直接通过 CLI 工作。

安装方式如下:

1
npm install kordoc

如果只想临时使用 CLI,也可以直接通过 npx 执行:

1
npx kordoc <文件>

最常见的文档转换命令包括:

1
2
3
4
5
6
7
8
npx kordoc 사업계획서.hwpx
npx kordoc 보고서.hwp -o 보고서.md
npx kordoc *.pdf -d ./변환결과/
npx kordoc 검토서.hwpx --format json
npx kordoc 검토서.pdf --format chunks
npx kordoc 보고서.hwpx --pages 1-3
npx kordoc 스캔본.pdf --ocr
npx kordoc 잠긴문서.hwpx --password '암호'

表单填写可以通过键值参数或 JSON 文件完成:

1
2
3
npx kordoc fill 신청서.hwpx -f '성명=홍길동,주소=서울' -o 결과.hwpx
npx kordoc fill 신청서.hwpx -j values.json -o 결과.hwpx
npx kordoc fill 신청서.hwpx --dry-run

生成、编辑与检查也都可以直接在命令行中完成:

1
2
3
4
5
npx kordoc generate 보고서.md -o 보고서.hwpx --preset 보고서
npx kordoc patch 원본.hwpx 편집.md -o 반영.hwpx
npx kordoc seal 신청서.hwpx --image 도장.png --anchor "(인)" -o 날인.hwpx
npx kordoc validate 산출물.hwpx
npx kordoc lint 보고서.md

对于文件夹中的持续到件处理,还可以使用监听模式:

1
npx kordoc watch ./수신함 -d ./변환결과

也可以在检测到文件后发送 webhook:

1
npx kordoc watch ./문서 --webhook https://api/hook

文档处理失败,也应该有可判断的结果

自动化工作流里,失败并不可怕。可怕的是失败结果无法被程序稳定识别。

Kordoc 对失败结果提供机器可读的 JSON 格式,并以退出码 1 结束。

1
2
3
4
5
6
7
{
"success": false,
"fileType": "hwpx",
"file": "보고서.hwpx",
"error": "암호화된 문서입니다 …",
"code": "ENCRYPTED"
}

错误类型包括:

  • ENCRYPTED
  • DRM_PROTECTED
  • UNSUPPORTED_FORMAT
  • CORRUPTED
  • IMAGE_BASED_PDF
  • ZIP_BOMB
  • DECOMPRESSION_BOMB
  • NO_SECTIONS
  • OUTPUT_TOO_LARGE
  • MISSING_DEPENDENCY
  • EMPTY_INPUT
  • FILE_NOT_FOUND
  • PARSE_ERROR

这些错误代码让脚本、服务或 AI 代理能够针对不同情况采取不同处理路径。

例如,遇到加密文档时可以请求密码,遇到纯扫描 PDF 时可以转入 OCR 流程,遇到缺少依赖时可以提示补齐运行环境。

MCP:让 AI 代理直接使用文档工具

Kordoc 同时提供 MCP 服务,能够让 Claude、Cursor、Codex 等客户端直接调用文档工具。

最简单的安装方式是:

1
npx -y kordoc setup

该命令会识别已安装的 AI 客户端,并自动加入配置。

对于 Codex,也可以手工注册:

1
codex mcp add kordoc -- npx -y kordoc mcp

MCP 服务提供 17 个工具,覆盖文档解析、格式识别、元数据读取、分页解析、表格读取、RAG 分块、文档比较、表单解析、表单填写、格式保留补丁、格式配置提取、HWPX 生成、印章放置、文档渲染、隐私遮盖、区域裁剪与表格提取。

其中包括:

  • parse_document
  • detect_format
  • parse_metadata
  • parse_pages
  • parse_table
  • parse_chunks
  • compare_documents
  • parse_form
  • fill_form
  • patch_document
  • extract_profile
  • generate_document
  • place_seal
  • render_document
  • redact_document
  • crop_regions
  • extract_tables

对于 AI 代理来说,这意味着文档不再只能作为上传附件等待阅读。

代理可以直接解析文档、识别字段、生成 HWPX、填写模板、对比新旧版本、渲染结果进行检查,或者提取适合知识检索的结构化内容。

隐私信息遮盖,也需要保留文档可用性

在真实办公流程中,隐私信息处理不能只停留在文本替换层。

Kordoc 支持识别居民登记号码、电话号码、账户信息等敏感数据,并执行遮盖。对于 HWPX 与 HWP,它能够尽量保留原始格式。

1
npx kordoc redact 민원서류.hwpx -o 마스킹.hwpx

可以指定遮盖符号:

1
npx kordoc redact 민원서류.hwpx --mask-char '*' -o 마스킹.hwpx

也可以选择规则并先执行仅报告模式:

1
npx kordoc redact 계약서.hwp --rules rrn,phone,crn --json --dry-run

姓名与地址也可以作为可选规则加入:

1
npx kordoc redact 민원서류.hwpx --rules rrn,phone,email,name,address -o 마스킹.hwpx

对于 HWPX 与 HWP,README 说明其遮盖范围还覆盖页眉、脚注、预览与文档信息,并会进行残留检查。

对于其他格式,输出为遮盖后的 Markdown。

一套面向真实文档复杂性的工具

Kordoc 的能力分布很广,但它们都围绕同一件事:让复杂文档重新成为可理解、可修改、可验证、可自动化处理的对象。

它可以读取老旧 HWP 3.x 文档,也可以处理 HWP 5.x、HWPX 与 HWPML。

它可以从 PDF 中恢复文字、标题、阅读顺序、图片、表格、公式与页面质量信号。

它可以处理 DOCX、XLSX 与 XLS,也能让 PNG、JPG、WebP 等图片直接进入 OCR 与表格恢复流程。

它可以把文档变成 Markdown,也可以把 Markdown 重新生成 HWPX。

它可以识别字段、填写模板、保留格式、放置印章、比较版本、渲染页面、提取区域、生成 RAG 分块,并通过 MCP 进入 AI 代理的操作范围。

文档世界里最麻烦的从来不是文件扩展名本身,而是格式背后层层叠叠的结构、规则、表格、页面与流程。

Kordoc 所做的,是把这些原本难以触碰的细节,一点点变成能够被代码和 AI 代理真正调用的能力。