Chuyển đến nội dung chính
PPDF123

@pdf123/sdk: SDK TypeScript của PDF123

@pdf123/sdk là SDK TypeScript cho API PDF của PDF123. Nó chạy 95 công cụ như gộp, tách, nén và OCR, gán kiểu cho tùy chọn của từng công cụ, đồng thời bổ sung xử lý hàng loạt, pipeline, xử lý mật khẩu và lỗi có kiểu. Đây là ES module, không có phụ thuộc lúc chạy.

@pdf123/sdkNode 20.3 trở lên, hoặc Bun

Cài đặt

npm install @pdf123/sdk
Trên trang này

Làm sao cài SDK?

Cài gói bằng trình quản lý gói của bạn. Cần Node 20.3 trở lên, Bun hoặc một bundler. Gói đã kèm kiểu TypeScript nên không cần @types/node.

Installbash
npm install @pdf123/sdk

bun add @pdf123/sdk và pnpm add @pdf123/sdk hoạt động tương tự.

Làm sao gộp hai PDF?

Tạo một client, chạy công cụ merge trên hai tệp rồi lưu kết quả. Khi không truyền tùy chọn nào, client gọi API công khai ở chế độ ẩn danh.

Merge and savets
import { Pdf123Client } from "@pdf123/sdk";
import { readFileInput, saveResult } from "@pdf123/sdk/node";

const client = new Pdf123Client();
const result = await client.run("merge", {
  input: [await readFileInput("a.pdf"), await readFileInput("b.pdf")],
});
const path = await saveResult(result, { output: "merged.pdf" });
console.log(path);

Kết quả chứa các byte trong data, cùng contentType, filename do máy chủ trả về, và json cho những công cụ trả về báo cáo. Thao tác tương tự có trên website với tên Gộp PDF.

Nên import entry point nào?

Entry pointCầnCung cấp
@pdf123/sdkChỉ fetchPdf123Client, TOOLS, getTool, Pdf123Error và các hàm hỗ trợ danh mục
@pdf123/sdk/nodeNode hoặc BunreadFileInput, fileSource, saveResult, checkOutput và clientFromEnv

Hãy import từ entry gốc trong trình duyệt và edge runtime, và chỉ thêm entry node ở nơi bạn đọc hoặc ghi tệp.

Client có những phương thức nào?

Phương thứcChức năng
run(tool, { input, params })Chạy một công cụ và trả về một kết quả
runBatch(tool, inputs, options)Chạy công cụ một tệp trên nhiều đầu vào và trả về một mục cho mỗi đầu vào
pipeline(steps, input, options)Chạy nhiều công cụ trong một yêu cầu
call(target, files, fields)Gửi yêu cầu thô tới một id công cụ, id thao tác hoặc đường dẫn /api/...
upload(file)Tải một tệp lên qua API tải lên theo từng phần và trả về id của nó

Các hàm hỗ trợ danh mục là hàm thông thường: TOOLS liệt kê mọi công cụ, getTool(id) trả về các trường, giá trị mặc định và loại tệp được chấp nhận của một công cụ, còn toolGroup, toolSummary, matchesQuery và suggestTools giúp xây bộ chọn công cụ. Dòng lệnh in cùng danh mục này bằng pdfx list và pdfx describe.

Làm sao truyền tùy chọn cho một công cụ?

params có kiểu theo từng công cụ. Nó chỉ nhận các trường của công cụ đó, và các trường dạng lựa chọn chỉ nhận giá trị được phép. Trường số được kiểm tra theo giá trị nhỏ nhất và lớn nhất, còn tệp được kiểm tra theo các loại được chấp nhận, trước khi có gì được tải lên. Những giá trị mặc định mà máy chủ cần sẽ được điền sẵn.

Watermark with optionsts
const marked = await client.run("watermark", {
  input: await readFileInput("a.pdf"),
  params: { watermarkText: "DRAFT", fontSize: 40, rotation: -45 },
});
await saveResult(marked, { output: "draft.pdf" });

Chuỗi rỗng nghĩa là "chưa đặt", khi đó áp dụng giá trị mặc định. Xem Thêm hình mờ để biết từng tùy chọn có tác dụng gì.

Làm sao xử lý nhiều tệp?

runBatch chạy một công cụ một tệp, chẳng hạn Nén, Xoay hoặc Bảo vệ, trên từng đầu vào với cùng tùy chọn. Mặc định chạy hai tệp cùng lúc. Một tệp lỗi không bao giờ làm dừng các tệp khác.

Batch with cancellationts
import { fileSource, saveResult } from "@pdf123/sdk/node";

const controller = new AbortController();
const entries = await client.runBatch("compress", [fileSource("a.pdf"), fileSource("b.pdf")], {
  concurrency: 2,
  signal: controller.signal,
  onResult: async (entry, index) => {
    if (entry.ok) await saveResult(entry.result, { output: "compressed/" });
  },
});
console.log(entries.map((entry) => entry.ok));
  • fileSource(path) là nguồn tải lười, chỉ được đọc khi một worker lấy đến, nên nhiều tệp lớn không bao giờ cùng nằm trong bộ nhớ.
  • onResult nhận từng kết quả ngay khi nó hoàn tất. Hãy lưu kết quả tại đây, và nếu hủy ở tệp thứ 50 trong 100 tệp thì 49 tệp đầu vẫn được giữ lại. Với retainData: false, mảng trả về không giữ các byte.
  • Mọi lời gọi đều nhận timeoutMs và signal để hủy.
  • idempotencyKey trở thành <key>:<index> cho từng tệp.

Các công cụ lọc (id bắt đầu bằng filter-) trả về matched: false thay vì ném lỗi khi điều kiện không thỏa. Trong một lô, tệp như vậy vẫn được tính là ok.

Làm sao nối các công cụ trong một yêu cầu?

pipeline gửi một danh sách bước và một hoặc nhiều đầu vào. Máy chủ chuyển đầu ra của mỗi bước làm đầu vào cho bước kế tiếp.

Merge, watermark, compressts
const piped = await client.pipeline(
  [{ tool: "merge" }, { tool: "watermark", params: { watermarkText: "DRAFT" } }, { tool: "compress" }],
  [await readFileInput("a.pdf"), await readFileInput("b.pdf")],
);
await saveResult(piped, { output: "out.pdf" });

Pipeline nhận cùng các tùy chọn mật khẩu như run.

Làm sao xử lý PDF đã mã hóa?

Truyền password cho run để mở đầu vào đã mã hóa trước. Việc mở khóa và chạy công cụ diễn ra trong cùng một yêu cầu. Với công cụ nhận nhiều tệp, chẳng hạn Gộp, hãy truyền passwords với một mục cho mỗi đầu vào, dùng chuỗi rỗng cho tệp không có mật khẩu. Mỗi tệp được mở khóa riêng.

Passwordsts
await client.run("compress", { input: await readFileInput("locked.pdf"), password: "secret" });
await client.run("merge", {
  input: [await readFileInput("locked.pdf"), await readFileInput("open.pdf")],
  passwords: ["secret", ""],
});

Với một lô, passwordFor(file, index) trả về mật khẩu cho từng đầu vào. Để gỡ bảo vệ vĩnh viễn, hãy dùng công cụ Gỡ mật khẩu.

Lỗi hoạt động thế nào?

Khi thất bại, SDK ném Pdf123Error. Nó có status (là undefined khi không có phản hồi), code, reason cho nguyên nhân chi tiết như password_required, và problem chứa chi tiết lỗi từ máy chủ, trong đó có hint nếu có. Lỗi xác thực được ném ra trước khi có gì được tải lên.

Handle an errorts
import { Pdf123Error } from "@pdf123/sdk";

try {
  await client.run("compress", { input: await readFileInput("locked.pdf") });
} catch (error) {
  if (error instanceof Pdf123Error) {
    console.error(error.status, error.code, error.reason, error.problem?.hint);
  } else {
    throw error;
  }
}

Các mã từ máy chủ được liệt kê ở trang Mã lỗi. Client tự bổ sung các mã sau:

MãÝ nghĩa
network_errorYêu cầu không nhận được phản hồi
timeoutMột yêu cầu vượt quá timeoutMs
cancelledsignal của bạn đã hủy lời gọi
input_unreadableKhông đọc được một đường dẫn cục bộ
output_unwritableKhông lưu được kết quả vào đường dẫn đã cho
output_mismatchsaveResult từ chối ghi tệp ZIP vào tên có đuôi .pdf
unsupported_file_typeCông cụ không chấp nhận loại tệp này
unknown_toolId công cụ không tồn tại; thông báo gợi ý các id gần giống
invalid_targetcall từ chối đường dẫn /api/... có đoạn .., . hoặc đoạn rỗng
no_contentCông cụ không có gì để trả về (HTTP 204)

saveResult không bao giờ ghi đè một tệp trong thư mục. Hãy gọi checkOutput(output, { several }) trước để biết, trước khi tải lên, liệu đường dẫn có ghi được hay không.

Cài đặt TypeScript và module nào hoạt động?

Các kiểu được phân giải với các cài đặt moduleResolution là nodenext, node16, bundler và node10 cũ hơn, kể cả subpath @pdf123/sdk/node. Gói là ES module nên import dùng được ở mọi nơi. require("@pdf123/sdk") từ CommonJS hoạt động trên Node 22.12 trở lên và không dùng được trên Node 20.

Làm sao cấu hình client?

Tùy chọnBiến môi trườngMặc định
baseUrlPDFX_API_BASEhttps://pdf123.xyz
apiKeyPDFX_API_KEYkhông có, tức ẩn danh
timeoutMskhông có300000

new Pdf123Client() không bao giờ đọc biến môi trường. clientFromEnv() từ @pdf123/sdk/node đọc hai biến này, và tùy chọn bạn truyền vào được ưu tiên. Khóa được gửi trong header X-API-KEY; xem Xác thực.

Để dùng máy chủ của riêng bạn, hãy đặt baseUrl là địa chỉ của nó, ví dụ http://localhost:8080. Xem Tự host.

Tôi có thể dùng SDK trong trình duyệt không?

Có. Entry gốc @pdf123/sdk chỉ cần fetch và không phụ thuộc Node. Hãy tự tạo các đối tượng FileInput từ File hoặc Uint8Array, vì các hàm hỗ trợ tệp nằm trong entry node. Đừng đưa khóa API vào mã trình duyệt mà người khác có thể đọc được.

Câu hỏi thường gặp

SDK có cần khóa API không?

Không. Client tạo không kèm tùy chọn sẽ gọi API công khai ở chế độ ẩn danh. Hãy truyền apiKey để gửi header X-API-KEY.

SDK cần phiên bản Node nào?

Node 20.3 trở lên, hoặc Bun. Entry gốc chỉ cần fetch, nên cũng chạy được trong trình duyệt và bundler.

Làm sao dùng công cụ mới hơn SDK?

Hãy dùng client.call. Nó nhận một id công cụ, một id thao tác như general/merge-pdfs hoặc một đường dẫn /api/..., cùng các tệp và trường. Không có gì được kiểm tra hay điền mặc định ở phía cục bộ.

Tôi có thể tải lên tệp lớn đến mức nào?

Đầu vào có tổng dung lượng trên 95 MB sẽ tự động đi qua API tải lên theo từng phần. Body của một yêu cầu trực tiếp bị giới hạn ở 100 MiB.

Vì sao lời gọi của tôi ném lỗi với PDF không có bảng?

Các công cụ như pdf-to-csv và pdf-to-xlsx trả về không có nội dung khi PDF không có bảng nào phát hiện được. SDK ném Pdf123Error với mã no_content thay vì trả về tệp rỗng. Hãy kiểm tra mã đó nếu kết quả rỗng là chấp nhận được.