Skip to content

保存文档

福昕 PDF SDK(Web)中,“保存文档”通常是指将当前 PDFDoc 导出为新的 PDF 文件流,然后由应用自行决定下载到本地、上传到服务器,或重新打开到 Viewer 中。

常用接口是 PDFDoc.getFile()。该接口会将当前 PDF 文档对象导出为 File 对象,包含文档中的修改内容,例如注释、表单、页面编辑等已经写入到 PDFDoc 的数据。

备注:

Web SDK 运行在浏览器环境中,不能直接写入用户本地磁盘的任意路径。保存到本地通常需要通过浏览器下载能力完成;保存到业务系统通常需要将导出的文件上传到服务器。

获取当前文档对象

使用 UIExtension 时,可以先通过 pdfui.getPDFViewer() 获取 PDFViewer,再通过 getCurrentPDFDoc() 获取当前文档对象。

javascript
const pdfViewer = await pdfui.getPDFViewer();
const pdfDoc = pdfViewer.getCurrentPDFDoc();

if (!pdfDoc) {
    throw new Error('当前没有打开文档');
}

如果您直接使用 PDFViewer

javascript
const pdfDoc = pdfViewer.getCurrentPDFDoc();

if (!pdfDoc) {
    throw new Error('当前没有打开文档');
}

导出为 PDF 文件

PDFDoc.getFile() 会返回一个 Promise<File>

javascript
const file = await pdfDoc.getFile({
    fileName: 'saved.pdf'
});

常用参数如下:

参数类型说明
fileNamestring导出的 PDF 文件名。未传入时,默认使用当前文档文件名。
flagsnumber文档保存标记。默认值为 0,表示普通保存。
progressHandlerFunction导出进度回调。回调参数包含 currenttotalstatus

下载到本地

浏览器中可以使用 URL.createObjectURL()<a> 标签触发下载。

javascript
async function downloadCurrentPDF(pdfui) {
    const pdfViewer = await pdfui.getPDFViewer();
    const pdfDoc = pdfViewer.getCurrentPDFDoc();

    if (!pdfDoc) {
        throw new Error('当前没有打开文档');
    }

    const file = await pdfDoc.getFile({
        fileName: 'saved.pdf'
    });

    const url = URL.createObjectURL(file);
    const a = document.createElement('a');
    a.href = url;
    a.download = file.name || 'saved.pdf';
    a.click();
    URL.revokeObjectURL(url);
}

保存到服务器

如果需要保存到业务系统,可以将 getFile() 返回的文件作为 FormData 上传。

javascript
async function uploadCurrentPDF(pdfui) {
    const pdfViewer = await pdfui.getPDFViewer();
    const pdfDoc = pdfViewer.getCurrentPDFDoc();

    if (!pdfDoc) {
        throw new Error('当前没有打开文档');
    }

    const file = await pdfDoc.getFile({
        fileName: 'saved.pdf'
    });

    const formData = new FormData();
    formData.append('file', file, file.name);

    await fetch('/api/pdf/save', {
        method: 'POST',
        body: formData
    });
}

获取导出进度

getFile() 支持通过 progressHandler 获取导出进度。进度回调适合用于展示保存进度条或禁用保存按钮。

javascript
const file = await pdfDoc.getFile({
    fileName: 'saved.pdf',
    progressHandler: function({ current, total, status }) {
        console.log('保存进度:', current, total, status);
    }
});

关于进度条,参阅 进度条组件

使用保存标记

getFile()flags 参数用于指定文档保存方式。默认值为 0,表示普通保存。

常见保存标记包括:

标记说明
normal0普通保存。该标记应单独使用。
incremental0x0001增量保存。
noOriginal0x0002保存时不包含原始数据或未变化对象。
XRefStream0x0008使用 XRef stream 保存。
linearized0x1000保存为线性化 PDF。该标记应单独使用。
removeRedundantObjects0x0010保存时移除冗余 PDF 对象。

示例:使用普通保存。

javascript
const file = await pdfDoc.getFile({
    flags: 0,
    fileName: 'saved.pdf'
});

如果没有明确的 PDF 保存策略要求,建议使用默认值。

分片导出文档流

对于希望自行处理分片流的场景,可以使用 PDFDoc.getStream()。该接口会通过回调返回分片数据,并在完成后返回总大小。

javascript
const buffers = [];

const size = await pdfDoc.getStream(function({ arrayBuffer, offset, size }) {
    buffers.push(arrayBuffer);
});

console.log('导出文件大小:', size);

const blob = new Blob(buffers, {
    type: 'application/pdf'
});

getStream() 适合需要自行拼接、上传或处理文件流的高级场景。一般保存和下载文档时,优先使用 getFile()

重新打开保存后的文档

如果您希望在保存后将导出的文件重新加载到 Viewer,可以将 getFile() 返回的文件传给 openPDFByFile()

javascript
const file = await pdfDoc.getFile({
    fileName: 'saved.pdf'
});

await pdfViewer.openPDFByFile(file, {
    fileName: file.name
});

权限限制

导出文档时,SDK 会检查相关下载权限。如果当前文档或应用权限不允许下载,getFile()getStream() 会抛出权限错误。

javascript
try {
    const file = await pdfDoc.getFile({
        fileName: 'saved.pdf'
    });
} catch (error) {
    console.error('保存文档失败', error);
}

注意事项

  • getFile() 返回的是新的文件对象,不会自动触发浏览器下载,也不会自动上传到服务器。
  • 浏览器环境不能直接覆盖用户本地原文件,下载或上传逻辑需要由应用实现。
  • 保存前如果存在异步的业务数据同步逻辑,请先确保这些数据已经写入当前 PDFDoc
  • 大文档导出可能需要较长时间,建议使用 progressHandler 提示用户保存进度。
  • 如果只是导出注释或表单数据,请使用对应的注释导出或表单数据导出接口,而不是导出整个 PDF 文档。