核心 API
核心 API
本指南展示了如何使用 Document 和 Page 类打开、编辑、组装和保存 PDF 文档——它们是 Aspose.PDF FOSS for TypeScript 中所有操作的入口点。Document 加载、创建、组装并保存完整的 PDF 文件;通过 doc.Pages 访问的 Page 则提供每页的文本、图像、注释和内容流操作。
文档生命周期
Document.OpenFile() 从文件路径打开 PDF;Document.Open() 接受内存中的 Uint8Array。页面可以就地检查和编辑,Document.WriteTo() 将结果写回——可选地使用 xref-stream 和 object-stream 压缩。
import { Document } from '@asposefoss/pdf';
// Open from disk (or Document.Open(uint8array) for in-memory data)
const doc = Document.OpenFile('input.pdf');
// Inspect and edit pages
const pages = doc.Pages;
console.log(pages.length);
pages[0].Rotate = 90;
doc.RemovePage(2); // 1-based page number
doc.Reorder([3, 1, 2]);
// Metadata
doc.SetMetadata({ title: 'Report', author: 'Jane', custom: { Dept: 'R&D' } });
// Save
doc.WriteTo('output.pdf'); // or: const bytes = doc.Save();
doc.WriteTo('small.pdf', { compressed: true }); // xref stream + object streams
拆分、合并和提取页面
Document.Split() 为每页返回一个 Document。Document.ExtractPages() 接受基于 1 的、允许重复的页码列表,并返回仅包含这些页面的新 Document。Document.Append() 和 Document.InsertPage() 在文档之间复制页面,而 Document.Merge() 将多个文档合并为一个。
const parts = doc.Split(); // one Document per page
const chapter = doc.ExtractPages([3, 4, 5]); // subset (1-based, repeats allowed) as a new Document
docA.Append(docB); // copy all of docB's pages onto docA
docA.InsertPage(1, docB.Pages[0]); // copy a single page across documents
创建新文档
Document.New() 在给定的 PageFormat 上启动一个空白文档。Page.AddText() 放置定位文本,Document.AddPage() 追加更多页面,包括诸如 PageFormat.A4.landscape() 之类的旋转格式。
import { Document, PageFormat } from '@asposefoss/pdf';
const doc = Document.New(PageFormat.A4); // one blank A4 page
doc.Pages[0].AddText('Hello', 72, 720, { fontSize: 14 });
doc.AddPage(PageFormat.A4.landscape()); // append more as you go
doc.WriteTo('scratch.pdf');水印和页码
Page.AddText() 还支持旋转、颜色和不透明度,这足以在不使用任何额外类的情况下渲染页码和对角水印。
const doc = Document.OpenFile('in.pdf');
const page = doc.Pages[0];
// Page number, right-aligned near the bottom-right corner.
const w = page.Rect[2] - page.Rect[0];
page.AddText(`Page ${page.Number}`, w - 40, 20, { fontSize: 10, align: 'right' });
// Semi-transparent diagonal watermark, centered on the page.
page.AddText('DRAFT', page.Rect[2] / 2, page.Rect[3] / 2, {
font: 'Times-Bold', fontSize: 64, color: [0.7, 0.7, 0.7], opacity: 0.4, rotate: 45, align: 'center',
});
doc.WriteTo('out.pdf');内容流内省
parseContentStream() 将页面的原始 /Contents 流解码为操作符/操作数对的列表,而 serializeContentStream() 则将编辑后的操作符列表转换回字节。
import { parseContentStream, serializeContentStream } from '@asposefoss/pdf';
const ops = parseContentStream(doc.Pages[0].Contents);
// ops: { operator: string, operands: PdfObject[], inlineImage?: {...} }[]
for (const op of ops) {
if (op.operator === 'Tj') console.log('text op:', op.operands);
}
const bytes = serializeContentStream(ops); // round-trips operators + operands
多列文本流动
Page.AddTextBlock() 将长文本字符串流入矩形区域,并返回所有未能容纳的文本,这些文本可以在第二次调用时继续流入另一列。
const rest = page.AddTextBlock(longText, [72, 600, 200, 150], {
font: 'Times-Roman', fontSize: 11, align: 'justify', valign: 'top', leading: 14,
});
if (rest) page.AddTextBlock(rest, [300, 600, 200, 150]); // continue into a 2nd column
提示与最佳实践
- 对文件路径使用
Document.OpenFile(),对内存中的Uint8Array数据使用Document.Open()。 - 传递给类似
RemovePage()和ExtractPages()方法的页码是从 1 开始的,而doc.Pages是一个从 0 开始的数组。 - 将
{ compressed: true }传递给Document.WriteTo(),以在输出时启用 xref-stream 和 object-stream 压缩。 Document.ExtractPages()接受重复的页码,因此同一源页可以在结果中出现多次。- 读取
page.Rect以计算相对于页面实际宽度和高度的位置,而不是硬编码坐标。
常见问题
| 问题 | 原因 | 修复 |
|---|---|---|
Document.Open() / OpenFile() 抛出 InvalidPasswordError | PDF 受密码保护,但未提供密码(或提供了错误的密码) | 将 { password: '...' } 传递给 Document.OpenFile() / Document.Open() |
RemovePage() 删除了错误的页面 | 传递给 RemovePage() 的页码是从 1 开始的,而不是从 0 开始 | 传入基于 1 的页码,区别于 doc.Pages 数组索引 |
WriteTo() 输出大于预期 | 默认保存不使用 xref/object-stream 压缩 | 将 { compressed: true } 传递给 Document.WriteTo() |
FAQ
Document.Open() 是否同时接受文件路径和内存数据?
Document.OpenFile() 从文件路径打开;Document.Open() 接受一个 Uint8Array 的内存字节。
页码是从0开始还是从1开始?
两者皆可,取决于API:doc.Pages是一个纯0基数组,但诸如RemovePage()和ExtractPages()的方法使用1基页码。
我可以在保存时加密文档吗?
可以——向WriteTo()/Save()传递一个encrypt选项,并使用algorithm: 'aes256' | 'aes128' | 'rc4'以及可选的用户/所有者密码。
如何减小输出文件的大小?
将{ compressed: true }传递给Document.WriteTo()以启用xref-stream和object-stream压缩。
我可以检查页面的原始内容流操作符吗?
可以——parseContentStream(doc.Pages[0].Contents)返回操作符列表,而serializeContentStream()将编辑后的列表转换回字节。
API Reference 摘要
| 类 / 方法 | 描述 |
|---|---|
Document | 用于创建、加载和保存 PDF 文档的核心入口点 |
Document.OpenFile() / Document.Open() | 从文件路径或内存字节加载 PDF |
Document.New() | 使用给定的 PageFormat 开始一个空白文档 |
Document.WriteTo() / Document.Save() | 将文档写入文件路径或返回字节 |
Document.Split() / Document.Merge() / Document.ExtractPages() | 在文档之间拆分、合并和提取页面 |
Document.Append() / Document.InsertPage() | 将页面从一个文档复制到另一个文档 |
Page | 单页 PDF;提供文本、图像、注释和 content-stream 方法 |
Page.AddText() / Page.AddTextBlock() | 向页面添加定位或流式文本 |
parseContentStream() / serializeContentStream() | 解析并重新序列化页面的原始 content-stream 操作符 |