PDF 版式固定、便于分发,但单个 PDF 只能承载正文内容。业务中经常需要把主文档与配套资料一并交给对方:例如把合同正文与签章图片、报表正文与底稿数据、说明文档与相关图片打包在一起,方便归档与流转。PDF 的附件(嵌入文件)机制为此提供了标准做法——它允许在 PDF 的嵌入文件树中携带任意类型的文件,接收方打开一个 PDF,即可在查看器的“附件”面板中同时找到主文档与配套文件,无需再通过邮件或网盘二次索取。
Spire.PDF for JavaScript 基于 WebAssembly 在浏览器端直接完成 PDF 的加载、绘制与保存,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。处理附件有两种基本操作:一种是添加——用 PdfAttachment 把某个文件的名称、字节数据与说明封装成附件,再通过 doc.Attachments.Add 加入文档的附件集合;另一种是删除——访问 doc.Attachments 附件集合,用 RemoveAt(index) 按索引移除指定的附件。两者都围绕 PdfDocument.Attachments 这一集合展开。
本文介绍两个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.PDF for JavaScript。以下示例默认已安装 Spire.PDF 并完成 WebAssembly 模块初始化。
将附件添加到 PDF 文档
给 PDF 添加附件时,先把主文档和要嵌入的文件加载进虚拟文件系统,再用 PdfAttachment 封装附件(名称、数据、说明、MIME 类型),最后 Add 进 doc.Attachments。附件不会画在页面上,而是存在 PDF 的嵌入文件树中,用查看器打开后可在“附件”面板看到并另存。本示例给合同文档嵌入一张 logo.png。
function App() {
const addAttachment = async () => {
// 获取 Spire.PDF WASM 模块
const pdfModule = window.wasmModule?.spirepdf;
// 检查模块是否就绪
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// 将作为主文档的 PDF 文件载入 VFS
const inputFileName = '合同模板.pdf';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// 将待嵌入为附件的图片文件载入 VFS
const attachFileName = 'logo.png';
await window.spire.FetchFileToVFS(attachFileName, "", `${process.env.PUBLIC_URL}/data/`);
// 创建 PdfDocument 对象并加载 PDF 文档
let doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
// 创建附件对象:设置附件名称、说明与 MIME 类型
let attachment = new pdfModule.PdfAttachment({ fileName: attachFileName });
attachment.Data = window.dotnetRuntime.Module.FS.readFile(attachFileName);
attachment.Description = '随合同一并分发的公司 logo';
attachment.MimeType = 'image/png';
// 将附件添加到文档的附件集合中
doc.Attachments.Add({ attachment: attachment });
// 定义输出文件名并保存文档
const outputFileName = '带附件的合同.pdf';
doc.SaveToFile(outputFileName);
doc.Close();
// 从 VFS 读取生成的文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Add Attachment To PDF</h1>
<button onClick={addAttachment}>
Generate
</button>
</div>
);
}
export default App;
已嵌入 logo.png 附件的合同文档

删除 PDF 文档中的附件
删除某个指定的附件,用附件集合的 RemoveAt(index) 按索引移除,索引从 0 开始(删除前可用 Count 核对数量与索引范围);本示例加载一份带附件的样例文档,删除其中的第一个附件。如需删除文档中的全部附件,直接调用 attachments.Clear() 清空整个附件集合即可。
function App() {
const deleteAttachments = async () => {
// 获取 Spire.PDF WASM 模块
const pdfModule = window.wasmModule?.spirepdf;
// 检查模块是否就绪
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// 将包含附件的 PDF 文件载入 VFS
const inputFileName = '含附件样例.pdf';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// 创建 PdfDocument 对象并加载 PDF 文档
let doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
// 获取文档的附件集合
let attachments = doc.Attachments;
// 删除附件集合中指定索引处的附件(索引从 0 开始,此处删除第一个附件)
attachments.RemoveAt(0);
// 定义输出文件名并保存文档
const outputFileName = '删除附件后的文档.pdf';
doc.SaveToFile(outputFileName);
doc.Close();
// 从 VFS 读取生成的文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Delete Attachments From PDF</h1>
<button onClick={deleteAttachments}>
Generate
</button>
</div>
);
}
export default App;
删除第一个附件后的 PDF 文档

常见问题
如何判断 PDF 文档中是否包含附件以及有多少个
原因:删除或读取附件前,通常需要先确认文档里是否存在附件、数量几何,避免对空集合做无效操作。
解决:文档的所有附件都存放在 doc.Attachments 集合中,其 Count 属性即附件个数,为 0 表示没有附件;需要逐个读取某个附件时,可用 get_Item(index) 按索引访问:
// 获取文档的附件集合与附件数量
let attachments = doc.Attachments;
let count = attachments.Count;
添加附件时应设置哪些属性
原因:只把文件字节塞给附件而不设置名称与说明,查看器“附件”面板里的展示会不完整,接收方难以识别文件内容。
解决:PdfAttachment 常用的几个属性是 fileName(接收方看到的附件文件名)、Description(一行说明文字)与 MimeType(内容类型),文件字节赋给 Data 即可。设置后再 Add 进集合,附件栏即可按名称、说明正确展示:
// 创建附件并填写名称、数据、说明与 MIME 类型
let attachment = new pdfModule.PdfAttachment({ fileName: 'logo.png' });
attachment.Data = window.dotnetRuntime.Module.FS.readFile('logo.png');
attachment.Description = '随合同一并分发的公司 logo';
attachment.MimeType = 'image/png';
doc.Attachments.Add({ attachment: attachment });
是不是只能把图片作为附件,能否嵌入其他类型的文件
原因:示例多以图片演示附件,容易误以为 PDF 附件只支持图片。
解决:PDF 附件本质是携带任意字节的嵌入文件,不限类型。只要先把文件加载进虚拟文件系统,用 FS.readFile 读出字节赋给 Data,并把 MimeType 设为对应的内容类型,Word、Excel、PDF、压缩包等都能作为附件嵌入。以嵌入一份 PDF 附表为例:
// 载入要嵌入的 PDF 附表并作为附件添加
const attachName = '产品附表.pdf';
await window.spire.FetchFileToVFS(attachName, "", `${process.env.PUBLIC_URL}/data/`);
let attachment = new pdfModule.PdfAttachment({ fileName: attachName });
attachment.Data = window.dotnetRuntime.Module.FS.readFile(attachName);
attachment.MimeType = 'application/pdf';
doc.Attachments.Add({ attachment: attachment });
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。









