PDF4me JavaScript SDK 入门
这 pdf4me 包裹 npm 是官方的 TypeScript/JavaScript ESM 客户 PDF4me REST API它提供 18 个模块共 106 个操作:使用异步函数和类型化结果,对文档进行转换、优化、合并、拆分、加盖戳记和提取内容。类型已包含在包内,因此 TypeScript 项目无需单独 @types 安装。
包装信息
| 场地 | 价值 |
|---|---|
| 软件包名称 | pdf4me |
| 当前版本 | 10.0.1 (发布于 2026 年 9 月 14 日) |
| 执照 | MIT |
| Node.js 支持 | >=22声明于 engines |
| 模块格式 | ESM 仅有的 ("type": "module") |
| 类型 | 捆绑式(dist/index.d.ts) |
| 副作用 | 没有任何 ("sideEffects": false) |
| 行动 | 106 个跨 18 个导入子路径 |
| 运行时依赖项 | 微软 Kiota 包(抽象加上 JSON(表单、文本和多部分序列化器) |
| 来源 | github.com/pdf4me/pdf4me-clientapi-javascript |
| npm | npmjs.com/package/pdf4me |
先决条件
- Node.js 22 年或更新款。
- A PDF4me 账户和 API 钥匙。
- 一个可以使用的项目 ESM
import语法("type": "module"你的package.json, 或者.mjs文件)。
安装
- npm
- pnpm
- Yarn
npm install pdf4me@^10
pnpm add pdf4me@^10
yarn add pdf4me@^10
这 ^10 范围很重要。 ^9 依赖范围将 不是 请单独选择版本 10,因为版本 10 是重写版本,包含一些重大更改。参见 从 9.x 版本升级 以下。
:::警告 Node.js 需要22个,但是 npm 仅作警告
engines 声明 node: ">=22"默认情况下 npm 如果匹配失败,则发出警告而不是错误。项目仍在运行。 Node.js 版本 18 将成功安装版本 10,但在运行时失败。请检查。 node --version发货前。
:::
要从源代码检出而不是注册表进行操作,请运行 npm install 和 npm run build 在软件包目录内,然后运行 npm install /absolute/path/to/pdf4me 从您的应用程序目录中。
认证
设置你的 API 环境中的关键因素:
- Bash / Zsh
- PowerShell
- Windows CMD
export PDF4ME_API_KEY="your-api-key"
$env:PDF4ME_API_KEY = "your-api-key"
set PDF4ME_API_KEY=your-api-key
客户端将密钥作为……发送。 Authorization: Basic <apiKey> 每次请求都会包含标头。该库不会记录凭据或文档内容。使用空密钥构造客户端会抛出异常。 TypeError 立即,在任何网络呼叫之前。
快速入门
将此保存为 optimize-pdf.mjs 并放置一个 input.pdf 在同一工作目录中。示例上传了 PDF 为了进行优化并将结果保存为 optimized.pdf。
import { readFile, writeFile } from "node:fs/promises";
import { Pdf4meClient } from "pdf4me";
import { optimize } from "pdf4me/optimize";
const apiKey = process.env.PDF4ME_API_KEY;
if (!apiKey) {
throw new Error("Set PDF4ME_API_KEY before running this example.");
}
const client = new Pdf4meClient(apiKey);
const data = await readFile("input.pdf");
const result = await optimize(client, data, { docName: "input.pdf" });
await writeFile("optimized.pdf", result);
console.log("Saved optimized.pdf");
运行命令:
node optimize-pdf.mjs
相同的导入在以下情况下有效: TypeScript ESM 项目,软件包中包含各种类型。
三点需要注意:
- 一个客户,多个操作。
new Pdf4meClient(apiKey)包含配置信息。fetch它拥有连接池,所以不存在close()调用该方法,完成后无需释放任何资源。 - Actions 是独立函数,而不是客户端方法。 每个都是从其自身的子路径导入的(
pdf4me/optimize,pdf4me/merge-split,pdf4me/edit)并被称为action(client, source, options)。 - 论证顺序是固定的。 首先是可重用的客户端,其次是当操作需要时提供的源内容,最后是选项对象。
包根目录导出的内容
根子路径(pdf4me) 承载客户端及其支持类型。操作永远不会驻留在这里。
| 出口 | 种类 | 目的 |
|---|---|---|
Pdf4meClient | 班级 | 持有 API 密钥和传输设置;作为每个操作的第一个参数传递 |
Pdf4meException | 班级 | 当服务返回失败时抛出此异常 |
Pdf4meTimeoutError | 班级 | 当请求或作业达到时间限制时抛出此异常 |
Pdf4meClientOptions | 类型 | 客户端构造函数接受的选项对象 |
DocumentSource | 类型 | Uint8Array | string — 源内容的公认形式 |
DEFAULT_BASE_URL | 常量 | https://api.pdf4me.com |
DEFAULT_TIMEOUT | 常量 | 100000 |
DEFAULT_MAX_WAIT | 常量 | 300000 |
DEFAULT_POLL_INTERVAL | 常量 | 10000 |
请求和结果
每次操作都会提交。 isAsync: true 并等待最终结果。立即 HTTP 立即返回200。 HTTP 202 返回一个作业 ID,客户端随后轮询该 ID。 GetActionStatus 直到任务完成。你的代码会看到一个。 await 无论哪种方式。
你传递的内容
DocumentSource 是 Uint8Array | string涵盖四种实用形式:
| 来源表格 | 笔记 |
|---|---|
Uint8Array | 包括 Node.js Buffer哪些子类 Uint8Array字节已为您进行 base64 编码,并以有界块的形式存储,因此大型文档不会溢出堆栈。 |
| base64字符串 | 直接通过了。 |
pdf4meblobid://... | 引用已持有的内容 PDF4me。 |
| URL | 该服务会自动获取文档。 |
本地会拒绝空内容。 TypeError 而不是被发送。
支持多输入操作的函数接受有序数组。 addAttachmentToPdf 例外情况是:它需要一个 attachments 对象将文件名映射到内容。
你得到的回报
| 结果类型 | 类型 | 例子 |
|---|---|---|
| 文件操作 | Uint8Array | 直接接受 Node.js writeFile |
| JSON 行动 | 类型模型 | DocMetadata, SplitPdfRes |
模型和枚举常量既可以从操作自身的模块导出,也可以从其他模块导出。 pdf4me/models 子路径。未知响应字段保留在 additionalData所以,更新的 API 字段永远不会悄无声息地丢失。
还有两次通话
import { merge } from "pdf4me/merge-split";
import { stamp, StampAlignX } from "pdf4me/edit";
const merged = await merge(client, [firstPdf, secondPdf]);
const stamped = await stamp(client, merged, {
text: "DRAFT",
alignX: StampAlignX.Center,
});
StampAlignX.Center 是一个类型化的常量,因此您的编辑器会自动补全合法值。 tsc 在发送请求之前就能发现拼写错误。
选项和默认值
所有选项接口均已导出,例如 OptimizeOptions有两种行为值得了解:
- 当选项为“ 缺席的默认优化配置文件为
Max明确的null做 不是 选择默认值。 - 每个行动都接受
extra一个序列化为附加请求字段的对象。使用 API使用自己的字段名称,并避免使用操作选项已提供的键。
客户端配置
const client = new Pdf4meClient(apiKey, {
baseUrl: "https://api.pdf4me.com",
timeout: 100_000,
maxWait: 300_000,
pollInterval: 10_000,
});
:::信息 所有持续时间均以毫秒为单位 Python 客户端使用秒来执行相同的设置。如果您正在两个客户端之间移植代码。 SDKs,每次持续时间重新调整。 :::
| 选项 | 默认 | 它所涵盖的内容 |
|---|---|---|
baseUrl | https://api.pdf4me.com | 这 API 每个请求都会发送到主机。 |
timeout | 100000 多发性硬化症 | 每个单独的请求,包括读取其正文 |
maxWait | 300000 多发性硬化症 | 首次提交作业后的轮询,包括作业进行中状态请求 |
pollInterval | 10000 多发性硬化症 | 状态检查之间的备用差距 |
fetch | globalThis.fetch | 自定义传输,可用于测试或代理配置 |
每个默认值也作为常量导出(DEFAULT_TIMEOUT 以及朋友们),因此您可以根据交付值进行扩展,而不是硬编码一个数字。
构造函数会验证你传递的参数:
baseUrl必须是http:或者https:URL 没有凭据、查询字符串或片段。任何其他情况都会抛出异常。TypeError。timeout,maxWait, 和pollInterval每个值都必须是不超过一定值的有限正数毫秒数。2147483647其他任何情况都会抛出异常。RangeError。
数值和 HTTP-日期 Retry-After 服务中的值控制轮询频率; pollInterval 仅当服务未发送轮询时才使用。如果下一次轮询会超过…… maxWait 如果到了最后期限,客户宁愿直接放弃,也不愿先花光剩下的预算。
注意:重定向已被拒绝
客户端设置 redirect: "error"如果您通过代理服务器路由流量,而该代理服务器返回 3xx 错误,请指向该服务器。 baseUrl到达最终目的地,而不是依赖于重定向。
:::
错误
| 扔 | 什么时候 |
|---|---|
Pdf4meException | 服务返回失败。携带 message, responseStatusCode, traceId, 和 responseHeaders。 |
Pdf4meTimeoutError | 请求时间限制(timeout)或工作时间限制(maxWait已达到。 |
TypeError | 无效的本地输入:空白 API 钥匙,一个坏的 baseUrl或者文档内容为空。 |
RangeError | 持续时间选项超出可接受的范围。 |
普通的 Error | 一架202型飞机,其机体上没有任何可用物品 jobId或者 JSON 执行了返回空结果的操作。 |
| 网络错误 | 由……传播 fetch 未改变。 |
Pdf4meException.message 摘自该服务自身 message 字段存在时,回退到 HTTP 状态文本。引用 traceId 当您联系支持人员时:它会在服务端识别出确切的工作。
import { Pdf4meException, Pdf4meTimeoutError } from "pdf4me";
import { optimize } from "pdf4me/optimize";
try {
const result = await optimize(client, data, { docName: "input.pdf" });
} catch (error) {
if (error instanceof Pdf4meTimeoutError) {
// The job exceeded maxWait. Retry, or raise maxWait for large documents.
} else if (error instanceof Pdf4meException) {
console.error(error.responseStatusCode, error.traceId);
} else {
throw error;
}
}
这18个模块
每个模块都有自己的导入子路径,因此打包工具和编辑器只会加载你使用的部分。该软件包设置 "sideEffects": false这样一来,打包程序就可以完全丢弃未使用的模块。
有些操作位于一个你可能无法从名称上猜到的模块中—— OCR 是 find-search, PDF/A 创造在于 convert, 和 pdf4me 包含单个超链接操作。下表列出了所有导出的操作,您无需猜测。
| 导入子路径 | 行动 | 导出函数 |
|---|---|---|
pdf4me/ai-document-extraction | 14 | aiDocumentParser, processBankCheque, processBankStatement, processContract, processCreditCard, processHealthCard, processInvoice, processMarriageCertificate, processMortgageDocument, processOrder, processPayStub, processReceipt, processShippingLabel, processTaxDocument |
pdf4me/barcode | 7 | addBarcode, createBarcode, createSwissQrBill, readBarcodes, readSwissQrBill, createEpcQrCode, readBarcodesFromImage |
pdf4me/convert | 13 | convertHtmlToPdf, convertJsonToExcel, convertMdToPdf, convertPdfToExcel, convertPdfToPowerpoint, convertPdfToWord, convertToPdf, convertUrlToPdf, convertVisio, convertWordToPdfForm, createPdfA, flattenPdf, linearizePdf |
pdf4me/edit | 7 | addAttachmentToPdf, addHtmlHeaderFooter, imageStamp, addMargin, addPageNumber, stamp, signPdf |
pdf4me/excel | 1 | findAndReplaceTextInExcel |
pdf4me/extract | 8 | classifyDocument, extractAttachmentFromPdf, extractPdfFormData, extractResources, extractTableFromPdf, extractTextByExpression, extractTextFromWord, parseDocument |
pdf4me/find-search | 2 | findAndReplace, convertOcrPdf |
pdf4me/forms | 2 | addFormField, fillPdfForm |
pdf4me/generate | 6 | enableTrackingChangesInWord, generateDocumentSingle, generateDocumentMultiple, getTrackingChangesInWord, replaceTextWithImageInWord, generateDocumentSingleV2 |
pdf4me/image | 13 | addImageWatermarkToImage, addTextWatermarkToImage, compressImage, convertImageFormat, createImages, cropImage, flipImage, getImageMetadata, imageExtractText, removeExifTagsFromImage, resizeImage, rotateImage, rotateImageByExifData |
pdf4me/merge-split | 5 | merge, mergeOverlay, splitPdf, splitPdfByBarcode, splitByText |
pdf4me/optimize | 1 | optimize |
pdf4me/organize | 5 | deleteBlankPages, deletePages, extractPages, rotate, rotatePage |
pdf4me/pdf | 16 | getPdfMetadata, repairPdf, createHyperlinkAnnotation, deleteHyperlinkAnnotation, digitalSignPdf, extractHyperlinkAnnotation, getDocumentByText, getTextAndCoordinates, getTextByPosition, highlightText, mergeV3, prepareForPrint, replaceTextWithImage, resizePdf, setPdfMetadata, signDocument |
pdf4me/pdf4me | 1 | updateHyperlinkAnnotation |
pdf4me/security | 2 | protect, unlock |
pdf4me/word | 2 | disableTrackingChangesInWord, findAndReplaceTextInWord |
pdf4me/zugferd | 1 | createZugferdInvoice |
与操作模块并列的还有两个子路径:包根(pdf4me如上所述, pdf4me/models它会重新导出每个模型和枚举常量。
有关每个动作的参数和响应形状,请参阅 PDF4me REST API 参考 或者生成的类型声明 node_modules/pdf4me/dist/。
从 9.x 版本升级
版本 10 是重写的版本。要继续使用 9.x 版本,请固定版本。 pdf4me@^9.10.15。
两项改动破坏了所有呼叫站点
你会立即发现这些问题,因为在修复这些问题之前,任何程序都无法编译或运行。
1. ESM 仅有的。 require("pdf4me") 不再解析。使用 import。
2. 客户端加上独立操作。 pdf4me.createClient(key)返回单个方法对象的函数被替换为 new Pdf4meClient(key) 此外,还有从子路径导入并调用的操作函数。 action(client, source, options)。
// 9.x
const pdf4me = require("pdf4me");
const client = pdf4me.createClient(key);
const result = await client.optimize(/* ... */);
// 10
import { Pdf4meClient } from "pdf4me";
import { optimize } from "pdf4me/optimize";
const client = new Pdf4meClient(key);
const result = await optimize(client, data, { docName: "input.pdf" });
三处修改可以编译运行,但运行异常
这些需要手动检查,因为没有任何方法可以告诉你它们错了。
1. 二元结果是 Uint8Array, 不是 Buffer。 Buffer 子类 Uint8Array, 所以 writeFile 朋友们还在工作。 Buffer只有那些会静默产生无意义结果而不是抛出异常的方法:
result.toString("base64"); // 9.x: base64. 10: "0,255,65,128"
Buffer.from(result).toString("base64"); // do this instead
2. 每次行动都会进行民意调查。 版本 10 提交 isAsync: true 并会一直轮询直到任务完成,因此原本只需一次往返的调用现在可能会阻塞长达…… maxWait (默认 300000 毫秒)并可以抛出 Pdf4meTimeoutError ——9.x 版本所没有的故障模式。
3. 重定向被拒绝。 9.x 版本紧随其后;版本 10 也包含在内。 redirect: "error"如果您将流量路由到响应 3xx 请求的代理,请指向 baseUrl 到达最终目的地。
也值得了解
- Node.js 22 现在是必需的,并且已声明
engines, 但 npm 默认情况下,仅在不匹配时发出警告。 - 创建缩略图(
createThumbnail/createThumbnails) 和 PDF/A 验证 (validate/validateDocument) 有 没有版本 10 的等效版本因为 v2 API 不会暴露它们。 - 许可证已从 ISC 到 MIT。
完整的逐方法映射,包括重命名和 integrationConfig 替换件随包裹寄出。详情请见: node_modules/pdf4me/MIGRATION.md 安装后。
故障排除
Error [ERR_REQUIRE_ESM] 或者 require() of ES Module ... not supported。 版本 10 是 ESM 仅限添加 "type": "module" 致你 package.json将条目文件重命名为 .mjs或别针 pdf4me@^9.10.15 如果项目无法推进 CommonJS 然而。
ERR_MODULE_NOT_FOUND 为了 pdf4me/optimize。 子路径导入通过包解析 exports 这需要一张相当新的地图。 Node.js 以及打包器。确认 node --version 报告版本为 22 或更高版本,并且您导入的子路径与模块表中指定的路径完全一致(例如)。 pdf4me/merge-split(用连字符连接)。
Base64 输出看起来像 "0,255,65,128"。 你打电话 .toString("base64") 在 Uint8Array先包好: Buffer.from(result).toString("base64")。
Pdf4meTimeoutError 处理大型文档。 这项工作超出了预期。 maxWait默认值为 300000 例如,请在客户端提出这个问题。 new Pdf4meClient(apiKey, { maxWait: 900_000 })并确认 timeout 仍然足够大,可以读取响应正文。请注意,这两个值都已达到上限。 2147483647 多发性硬化症。
401 Pdf4meException.responseStatusCode。 这 API 密钥存在但被拒绝。请在以下位置重新生成密钥: PDF4me 仪表板 并确认该环境变量确实对进程可见—— set 在 Windows 系统中 CMD 不会跨会话持久化,因此请使用 setx 具有永久价值。
TypeError: an API key is required。 构造函数接收到的字符串为空或仅包含空格,通常是因为 process.env.PDF4ME_API_KEY 未定义。请在构建客户端之前检查该变量,就像快速入门指南中所做的那样。
TypeError: document content is empty。 这 Uint8Array 或者您传递的字符串长度为零。这是本地检查,因此未发送任何请求——请验证文件是否实际读取成功。
请求通过企业代理服务器失败。 客户设定 redirect: "error" 并且不会遵循代理的 3xx 点。 baseUrl 在最终目的地,或提供定制服务 fetch 负责你的交通运输。
createThumbnail 或者 validate 未导出。 这两个选项都在版本 10 中被移除,因为 v2 API 不会暴露它们。没有可直接替代的方案;如果您依赖这些功能,请继续使用 9.x 版本。