# extract-pdf 中文文档

规范地址：https://npmcn.com/package/extract-pdf/

版本：0\.1\.552
npm 元数据更新时间：2026-11-03T15:14:08.782Z
中文译文更新时间：2026-11-03T15:50:46.203Z
软件包许可：rights\.institute/PROSPER

本文由上游 README 机器翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/extract-pdf
原文对照：https://npmcn.com/package/extract-pdf/?lang=original
项目主页：https://github.com/OpenSourceAGI/qwksearch-research-agent#readme
源码仓库：https://github.com/OpenSourceAGI/qwksearch-research-agent

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：273 kB，95 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：1 个
- 首次发布：2026-06-03T23:27:12.233Z
- 最新版本发布：2026-11-03T15:14:08.357Z
- 已发布版本数：553（近 12 个月 553 个）

## 中文简介

转换PDF （URL或ArrayBuffer）到干净的HTML与结构标签-标题，列表，脚注，代码块，粗体/斜体。默认为Slim （PDF.js在运行时从pdfjs-无服务器CDN构建中加载），为页面w提供可选的Granite Docling OCR

## 安装

```sh
npm install extract-pdf
```

也可以使用：`pnpm add extract-pdf`、`yarn add extract-pdf`、`bun add extract-pdf`

## README

![](https://i.imgur.com/2ks47qa.png)  
[![Documentation](https://img.shields.io/badge/Docs-blue?logo=ReadTheDocs&logoColor=white)](https://qwksearch.com/api) [![GitHub Stars](https://img.shields.io/github/stars/OpenSourceAGI/qwksearch-research-agent)](https://github.com/OpenSourceAGI/qwksearch-research-agent/stargazers) [![NPM Monthly Downloads](https://img.shields.io/npm/dm/extract-pdf.svg)](https://www.npmjs.com/package/extract-pdf) [![npm version](https://img.shields.io/npm/v/extract-pdf.svg)](https://www.npmjs.com/package/extract-pdf) [![NPM Total Downloads](https://img.shields.io/npm/dt/extract-pdf.svg)](https://www.npmjs.com/package/extract-pdf) [![TypeScript types](https://img.shields.io/npm/types/extract-pdf)](https://www.npmjs.com/package/extract-pdf) [![Install size](https://packagephobia.com/badge?p=extract-pdf)](https://packagephobia.com/result?p=extract-pdf)  
[![GitHub Issues](https://img.shields.io/github/issues/OpenSourceAGI/qwksearch-research-agent?logo=github)](https://github.com/OpenSourceAGI/qwksearch-research-agent/issues) [![Open Pull Requests](https://img.shields.io/github/issues-pr/OpenSourceAGI/qwksearch-research-agent?logo=github&label=PRs)](https://github.com/OpenSourceAGI/qwksearch-research-agent/pulls) [![Merged Pull Requests](https://img.shields.io/github/issues-pr-closed/OpenSourceAGI/qwksearch-research-agent?logo=github&label=PRs%20merged&color=8957e5)](https://github.com/OpenSourceAGI/qwksearch-research-agent/pulls?q=is%3Apr+is%3Aclosed) [![GitHub Discussions](https://img.shields.io/github/discussions/OpenSourceAGI/qwksearch-research-agent)](https://github.com/OpenSourceAGI/qwksearch-research-agent/discussions) [![GitHub last commit](https://img.shields.io/github/last-commit/OpenSourceAGI/qwksearch-research-agent.svg)](https://github.com/OpenSourceAGI/qwksearch-research-agent/commits/master/)  
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/OpenSourceAGI/qwksearch-research-agent/tree/master/packages/extract-pdf) ![Bun](https://img.shields.io/badge/Bun-14151A?logo=bun&logoColor=white) ![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white) ![Vite](https://img.shields.io/badge/Vite-646CFF?logo=vite&logoColor=white)

**🤖座席技能** - - - - - - `npx skills@latest add https://github.com/OpenSourceAGI/qwksearch-research-agent --skill extract-pdf` （[它涵盖了什么](https://npmcn.com/skills/extract-pdf/SKILL.md)）

# extract-pdf

> **当用户上传PDF时，他们希望得到即时聊天响应，而不是在OCR模型上等待5分钟。**

即时无后端需要javascript转换PDF (URL或 `ArrayBuffer`)变成干净的HTML与结构标签-标题，列表，脚注，代码块，粗体/斜体，和目录条目。可以在Node.js、Cloudflare Workers和浏览器环境中工作 [pdfjs-serverless](https://github.com/johannschopplich/pdfjs-serverless)。

**默认为Slim：** 该软件包不捆绑PDF引擎。PDF.js是在运行时从jsdeliver的ESM构建中惰性加载的 `pdfjs-serverless` （`https://cdn.jsdelivr.net/npm/pdfjs-serverless@1/+esm`（固定在主版本上）-零依赖，单个~1.6 MB的Mozilla PDF.js的再分发，为无服务器/边缘运行时构建。Node.js和Bun不能导入远程url，所以加载器会返回到本地安装的 `pdfjs-serverless` 可选依赖。所有与ocr相关的东西（花岗岩） `@huggingface/transformers`， `@napi-rs/canvas`)同样是可选的，只在实际使用时才导入。

为了在包含信息图表、图表和表格的页面上实现ocr级保真度，软件包还附带了Granite Docling路径（从前者合并而来） `extract-pdf-docling` 包)：通过前端JS解析器运行所有页面，通过文档OCR运行所有页面 **混合动力** 模式，只对需要它的页面和ocr进行regex扫描，或者指向远程文档兼容处理器的URL(参见 `server/`）.

## 安装

```sh
bun add extract-pdf
```

## 文档和现场演示

[`site/`](https://npmcn.com/package/extract-pdf/site) 是否有一个Cloudflare Worker为这个包提供文档服务 [extract-webpage](https://npmcn.com/package/extract-webpage)，另外还有现场演示 `/demo`：上传PDF或粘贴URL，并获得HTML返回 `/api/convert`，配合OCR跟进，或通过提取网页 `/api/extract`． 运行它 `bun install` 然后在存储库根目录下 `cd site && bun run dev`． CI在每次涉及它的推送上部署它。看到 [网站/ README.md](https://npmcn.com/package/extract-pdf/site/README.md) 用于秘密，自定义域，CPU限制和加固。

## 用法

```ts
import { convertPDFToHTML } from "extract-pdf";

const { html, title, author } = await convertPDFToHTML(
  "https://example.com/paper.pdf",
);
// or pass an ArrayBuffer from fs.readFile / fetch
const { html } = await convertPDFToHTML(buffer, { addPageNumbers: true });
```

### 选项

| 选项 | 默认的 | 描述 |
| --- | --- | --- |
| `addPageNumbers` | `false` | 插入 `[n]` 每一页边界处的标记 |
| `addCitation` | `true` | 读取PDF元数据和要填充的第一页标题 `title`/`author` 在返回值中 |
| `method` | `"ts-block-algorithm"` | 解析引擎—— `"ts-block-algorithm"`， `"liteparse"`,或 `"liteparse-wasm"` (见下文) |
| `liteParseOptions` | `{}` | 传递给LiteParse的构造函数 `method` 是 `"liteparse"` 或 `"liteparse-wasm"` |
| `processor` | `"frontend"` | OCR发生在哪里 `"frontend"`， `"hybrid"`， `"docling"`，或处理器URL（见下文） |
| `processorUrl` | \- - - - - - | 使用的远程文档兼容API `"hybrid"`/`"docling"` 而不是进程内模型 |
| `ocrScanOptions` | `{}` | 混合页面扫描的阈值调优(`scanPagesForOCR`） |
| `doclingOptions` | `{}` | `prompt`， `maxTokens`， `scale` 为dooping OCR模型 `processorHeaders` 发送到 `processorUrl` |

### 返回值

```ts
{ html: string, title?: string, author?: string, format: "pdf",
  processor: string, ocrScan: OcrScanResult }
```

## 解析方法

`convertPDFToHTML` 支持三种可互换的解析引擎 `options.method`：

| 方法 | 引擎 | 环境 | 光学字符识别 |
| --- | --- | --- | --- |
| `"ts-block-algorithm"` (默认) | 下面记录的pure-TS管道（这个包） | Node.js, Cloudflare Workers，浏览器 | 否 |
| `"liteparse"` | [LiteParse](https://github.com/run-llama/liteparse) (本地, `@llamaindex/liteparse`） | node . js只 | 可选 |
| `"liteparse-wasm"` | [LiteParse](https://github.com/run-llama/liteparse) (WASM `@llamaindex/liteparse-wasm`） | Node.js, Cloudflare Workers，浏览器 | 可选（通过回调） |

```ts
import { convertPDFToHTML } from "extract-pdf";

const { html } = await convertPDFToHTML(buffer, { method: "liteparse" });

// Or the WASM build, which also runs in browsers and Cloudflare Workers:
const { html } = await convertPDFToHTML(buffer, { method: "liteparse-wasm" });
```

LiteParse附带了一个本地（napi）插件，所以 `method: "liteparse"` 只跑进去 Node.js——它没有被绑定到浏览器或Cloudflare Workers构建中。安装 它明确地(`bun add @llamaindex/liteparse`)，因为它是可选的 依赖;如果没有安装， `convertPDFToHTML` 返回 `{ error }` 而不是扔。

`method: "liteparse-wasm"` 将委托给LiteParse的WebAssembly构建， 它可以运行在WASM支持的任何地方——浏览器、Cloudflare Workers和Node.js。 显式安装它(`bun add @llamaindex/liteparse-wasm`)，因为它也是 可选的依赖项；如果没有安装， `convertPDFToHTML` 返回 `{ error }` 而不是扔。WASM构建没有内置OCR引擎 通过一项 `liteParseOptions.ocrEngine` 回调(例如由 `tesseract-js`） 启用OCR。

默认情况下，两个LiteParse路径在禁用OCR的情况下运行(`ocrEnabled: false`) - - - 符合这个包的“即时，无后端”的哲学。使用 `detectPdfNeedsOcr` （见下文）来决定何时值得重新解析文档 `liteParseOptions: { ocrEnabled: true }`。

## 处理器模式：前端、混合、文档OCR或远程URL

分开 `method`, `processor` 选项决定页面是否删除 通过 [花岗岩Docling](https://huggingface.co/ibm-granite/granite-docling-258M) OCR模型——保留布局、表格、图表、代码和公式 每页模型推理成本：

| `processor` | 会发生什么 |
| --- | --- |
| `"frontend"` (默认) | 所有页面都由纯js文本层管道解析。没有OCR，没有模型，即时。 |
| `"hybrid"` | JS管道无处不在+正则表达式扫描(`scanPagesForOCR`)标记带有信息图表/数字/表格或没有可用文本层的页面；只有那些页面是栅格化的，并使用文档进行OCR识别。 |
| `"docling"` | 每一页都栅格化了，用OCR打印。 |
| `"https://..."` (URL) | 就像 `"docling"`，但是每个页面都被post到与文档兼容的处理器API，而不是在进程中运行模型。 |

```ts
// Hybrid: fast JS parse, OCR only the pages that need it
const { html, ocrScan } = await convertPDFToHTML(buffer, { processor: "hybrid" });
console.log(ocrScan.pagesNeedingOcr); // e.g. [3, 7] — pages with tables/figures
// each ocrScan.pages[i] lists reasons: "table-caption", "figure-caption",
// "table-rows", "numeric-grid", "no-text", "sparse-text", "garbled-text"

// All pages through a remote Docling processor (this package's server/):
const { html } = await convertPDFToHTML(buffer, {
  processor: "http://localhost:3000",
});

// Hybrid with the OCR offloaded to a remote processor:
const { html } = await convertPDFToHTML(buffer, {
  processor: "hybrid",
  processorUrl: "http://localhost:3000",
});
```

使用OCR的页面以 `<section class="ocr-page" id="page-N">…</section>` (表格变得真实 `<table>` 标记、标题 `<figcaption>`,公式 `<code class="formula">`,……);OCR失败的页面保留其js解析的HTML。

运行Docling **进程内的** 需要可选的 `@huggingface/transformers` 依赖（ONNX模型） `onnx-community/granite-docling-258M-ONNX`， ~ 1gb； 第一次使用时下载)和-在Node.js中- `@napi-rs/canvas` 对页面 光栅化（浏览器/工作器使用） `OffscreenCanvas`）.

正则表达式扫描器也是独立导出的，OCR帮助器也是如此：

```ts
import { scanPagesForOCR, doctagsToHtml, ocrImageWithDocling } from "extract-pdf";

const scan = scanPagesForOCR(pageTexts); // string[] of per-page text
// { needsOcr, pagesNeedingOcr: number[], pages: [{ page, reasons, captions }] }
```

### 运行文档处理程序服务器

这个 `server/` 文件夹包含Hono HTTP API(以前是 `extract-pdf-docling` 暴露花岗岩Docling模型：

```sh
bun run serve:docling   # or dev:docling for --watch; port 3000
```

-   昂首阔步界面: `http://localhost:3000/docs`，说明 `/openapi.json`
-   `POST /api/v1/convert` - - - - - - `{ imageUrl, prompt?, maxTokens? }`
-   `POST /api/v1/convert-base64` - - - - - - `{ imageBase64, mimeType?, prompt?, maxTokens? }`
-   `POST /api/v1/convert-stream` - SSE令牌流
-   `GET /health`

一个 `server/wrangler.jsonc` 将其部署为Cloudflare Worker。 它的任何部署（或具有相同契约的任何API）都可以作为 `processor`/`processorUrl` 上面的选项。

### 在hug Face Spaces上托管处理器

[`docling-space/`](https://npmcn.com/package/extract-pdf/docling-space) 包装与“拥抱脸”相同的型号 Docker空间：令牌验证，每次生成一个有界队列 模型惰性加载，以及可选的经过处理的HTML输出。它的README有 部署步骤。发送空间的令牌（如果是私人空间，则发送拥抱脸） 读取令牌) `doclingOptions.processorHeaders`：

```ts
const { html } = await convertPDFToHTML(buffer, {
  processor: "hybrid",
  processorUrl: "https://YOUR_HF_USERNAME-extract-pdf-docling.hf.space",
  doclingOptions: {
    processorHeaders: {
      "X-Docling-Token": process.env.DOCLING_API_TOKEN,
      Authorization: `Bearer ${process.env.HF_SPACE_TOKEN}`, // private Space only
    },
    maxTokens: 1500,
  },
});
```

混合模式在返回之前仍然等待每个标记的页面。回答… 一旦增强，之后就跑 `processor: "frontend"`，返回它的HTML，和 光学字符识别 `ocrScan.pagesNeedingOcr` 作为后续；这个 [现场演示](https://npmcn.com/package/extract-pdf/site) 做 正是如此。

## 检测PDF是否需要OCR

在提交完整的（可能很慢的）OCR解析之前， `detectPdfNeedsOcr` 运行一个廉价的、仅限文本层的通道，并报告每个页面是否需要OCR或 其他繁重的解析——用于将文档路由到不同的管道 (快速路径vs. OCR vs.截图vs. LlamaParse或 Docling):

```ts
import { detectPdfNeedsOcr, convertPDFToHTML } from "extract-pdf";

const assessment = await detectPdfNeedsOcr(buffer);
// { needsOcr: boolean, pages: PageComplexityStats[], reasons: string[] }

if (!assessment.needsOcr) {
  const { html } = await convertPDFToHTML(buffer, { method: "liteparse" });
} else {
  console.log("Needs OCR:", assessment.reasons); // e.g. ["scanned", "sparse-text"]
  // Route to an OCR-enabled pipeline, e.g.:
  const { html } = await convertPDFToHTML(buffer, {
    method: "liteparse",
    liteParseOptions: { ocrEnabled: true },
  });
}
```

`reasons` 收集在页面上发现的每个不同的信号； `"scanned"`， `"no-text"`， `"sparse-text"`， `"embedded-images"`， `"garbled"`,或 `"vector-text"`。就像 `method: "liteparse"`，这是Node.js只需要 `@llamaindex/liteparse`。

## 管道

对象上运行一个顺序的转换链 `ParseResult` （页→项）：

```
Raw pdfjs text spans
  → CalculateGlobalStats   — font heights, distances, format map
  → CompactLines           — merge spans on the same y-line into LineItems
  → RemoveRepetitiveElements — strip recurring page headers/footers
  → VerticalToHorizontal   — rotate vertical character runs
  → DetectTOC              — identify Table of Contents pages, link headings
  → DetectHeaders          — classify items as H1–H6 by font height
  → DetectListItems        — detect bullet/numbered list items
  → GatherBlocks           — group adjacent same-type lines into blocks
  → DetectCodeQuoteBlocks  — mark indented blocks as CODE
  → DetectListLevels       — add indentation for nested list levels
  → ToTextBlocks           — flatten blocks to { category, text } pairs
  → ToHTML                 — render pairs as <p>, <h1>–<h6>, <ul>, <code>
```

## 文件夹结构

```
src/
  pdf-to-html.ts          — main entry point (convertPDFToHTML)
  liteparse-to-html.ts    — "liteparse" method (native napi addon)
  liteparse-wasm-to-html.ts — "liteparse-wasm" method (WASM, browser/edge)
  ocr-page-scan.ts        — regex scan flagging infographic/table pages for OCR
  docling-ocr.ts          — Granite Docling OCR (local ONNX or remote URL),
  │                         page rasterization, doctags → HTML
  detect-needs-ocr.ts     — LiteParse-based OCR routing (Node.js only)
  models/                 — data classes: Page, ParseResult, TextItem,
  │                         LineItem, LineItemBlock, Word, BlockType, …
  transforms/
  │  base/                — abstract Transformation, ToLineItem*, ToLineItemBlock*
  │  line-item/           — per-line-item transformations
  │  block/               — per-block transformations
  │  calculate-global-stats.ts
  │  to-text-blocks.ts
  │  to-html.ts
  utils/
     load-pdfjs.ts        — lazy CDN loader for pdfjs-serverless
     string-functions.ts
     page-item-functions.ts
     page-number-functions.ts
server/                   — Granite Docling HTTP processor (Hono):
   server.js, routes.js, schemas.js, model.js, wrangler.jsonc
```

## 常见问题

### extract-pdf 是什么？

转换PDF （URL或ArrayBuffer）到干净的HTML与结构标签-标题，列表，脚注，代码块，粗体/斜体。默认为Slim （PDF\.js在运行时从pdfjs-无服务器CDN构建中加载），为页面w提供可选的Granite Docling OCR

### 如何安装 extract-pdf？

在项目目录运行 npm install extract-pdf，或使用 pnpm add / yarn add / bun add。

### extract-pdf 支持 TypeScript 吗？

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

### extract-pdf 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### extract-pdf 可以商用吗？

extract-pdf 使用 rights\.institute/PROSPER 许可。声明的许可为 rights\.institute/PROSPER，请阅读许可原文确认使用条件。以上为概括，不构成法律意见，请以许可原文为准。

### extract-pdf 还在维护吗？

最新版本 0\.1\.552 发布于 2026/11/03（今天）；至今共发布 553 个版本，其中过去 12 个月发布了 553 个；首次发布于 2026/06/04。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

