Logo of unpdf

unpdf

在 Node.js、浏览器和 Worker 中处理 PDF 的工具

一个用于处理 PDF 的实用工具集合。专为 Deno、worker 和其他无节点环境设计。

unpdf 附带了 Mozilla PDF.js 的无服务器构建/重新分发版本,适用于无服务器环境。除了进行一些字符串替换和模拟,unenv 通过将 Node.js 特定代码转换为平台无关代码来完成繁重的工作。有关所有详细信息,请参阅 pdfjs.rollup.config.ts

此库也旨在作为已停止维护但仍流行的 pdf-parse 的现代替代方案。

功能特性

  • 🏗️ 适用于 Node.js、浏览器和 worker
  • 🪭 包含 PDF.js 的无服务器构建版本 (unpdf/pdfjs)
  • 💬 从 PDF 中提取文本和图像
  • 🧱 可选择使用旧版 PDF.js 构建
  • 💨 零依赖

PDF.js 兼容性

此包当前使用 PDF.js v4.0.189。

安装

运行以下命令将 unpdf 添加到您的项目中。

# pnpm
pnpm add unpdf

# npm
npm install unpdf

# yarn
yarn add unpdf

用法

从 PDF 中提取文本

import { extractText, getDocumentProxy } from "unpdf";

// Fetch a PDF file from the web
const buffer = await fetch(
  "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
).then((res) => res.arrayBuffer());

// Or load it from the filesystem
const buffer = await readFile("./dummy.pdf");

// Load PDF from buffer
const pdf = await getDocumentProxy(new Uint8Array(buffer));
// Extract text from PDF
const { totalPages, text } = await extractText(pdf, { mergePages: true });

访问 PDF.js API

这将返回已解析的 PDF.js 模块,并提供对 PDF.js API 的完全访问权限,例如

  • getDocument
  • version
  • ……以及所有其他方法

对于像 🦕 Deno 这样的平台,或者如果您想直接使用 PDF.js API,此功能特别有用。如果事先未定义自定义构建,则将初始化 unpdf 附带的无服务器构建版本。

import { getResolvedPDFJS } from "unpdf";

const { getDocument } = await getResolvedPDFJS();
const data = Deno.readFileSync("dummy.pdf");
const doc = await getDocument(data).promise;

console.log(await doc.getMetadata());

for (let i = 1; i <= doc.numPages; i++) {
  const page = await doc.getPage(i);
  const textContent = await page.getTextContent();
  const contents = textContent.items.map((item) => item.str).join(" ");
  console.log(contents);
}

使用官方或旧版 PDF.js 构建

一般来说,您无需担心 PDF.js 的构建问题。unpdf 附带了最新版 PDF.js 的无服务器构建。但是,如果您想使用官方 PDF.js 版本或旧版构建,可以定义一个自定义的 PDF.js 模块。

// Before using any other method, define the PDF.js module
// if you need another PDF.js build
import { configureUnPDF } from "unpdf";

await configureUnPDF({
  // Use the official PDF.js build (make sure to install it first)
  pdfjs: () => import("pdfjs-dist"),
});

// Now, you can use the other methods
// …

配置

interface UnPDFConfiguration {
  /**
   * By default, UnPDF will use the latest version of PDF.js compiled for
   * serverless environments. If you want to use a different version, you can
   * provide a custom resolver function.
   *
   * @example
   * // Use the official PDF.js build (make sure to install it first)
   * () => import('pdfjs-dist')
   */
  pdfjs?: () => Promise<PDFJS>;
}

方法

configureUnPDF

定义一个自定义的 PDF.js 模块,例如旧版构建。请务必在使用任何其他方法之前调用此方法。

function configureUnPDF(config: UnPDFConfiguration): Promise<void>;

getResolvedPDFJS

返回已解析的 PDF.js 模块。如果未定义构建,则将初始化最新版本。

function getResolvedPDFJS(): Promise<PDFJS>;

getMeta

function getMeta(data: BinaryData | PDFDocumentProxy): Promise<{
  info: Record<string, any>;
  metadata: Record<string, any>;
}>;

extractText

从 PDF 中提取所有文本。如果将 mergePages 设置为 true,则所有页面的文本将合并为一个字符串。否则,将返回一个包含每页文本的字符串数组。

function extractText(
  data: BinaryData | PDFDocumentProxy,
  { mergePages }?: { mergePages?: boolean },
): Promise<{
  totalPages: number;
  text: string | string[];
}>;

renderPageAsImage

此方法仅在 Node.js 和浏览器环境中有效。

要将 PDF 页面渲染为图像,您可以使用 renderPageAsImage 方法。此方法将返回渲染图像的 ArrayBuffer

要使用此方法,您必须满足以下要求

  • 使用官方 PDF.js 构建
  • 在 Node.js 环境中安装 canvas

示例

import { configureUnPDF, renderPageAsImage } from "unpdf";

await configureUnPDF({
  // Use the official PDF.js build
  pdfjs: () => import("pdfjs-dist"),
});

const pdf = await readFile("./dummy.pdf");
const buffer = new Uint8Array(pdf);
const pageNumber = 1;

const result = await renderPageAsImage(buffer, pageNumber, {
  canvas: () => import("canvas"),
});
await writeFile("dummy-page-1.png", Buffer.from(result));

类型声明

declare function renderPageAsImage(
  data: BinaryData,
  pageNumber: number,
  options?: {
    canvas?: () => Promise<typeof import("canvas")>;
    /** @default 1 */
    scale?: number;
    width?: number;
    height?: number;
  },
): Promise<ArrayBuffer>;

常见问题

为什么 canvas 是一个可选依赖项?

官方 PDF.js 库在 Node.js 环境中依赖于 canvas 模块,但该模块无法在 worker 线程中工作。这就是为什么 unpdf 附带了 PDF.js 的无服务器构建,它模拟了 canvas 模块。

但是,要在 Node.js 环境中将 PDF 页面渲染为图像,您需要安装 canvas 模块。这就是它作为对等依赖的原因。

许可

MIT 许可证 © 2023-PRESENT Johann Schopplich