Saving and exporting

WebPDF saves PDFs to the user's device, gives you their bytes for uploads, and exports pages as images. This article walks through the methods of <pdf-file> for the document, and of page.image for a page's picture.

Saving to the device

save() saves the PDF with its form edits. Where the browser has the File System Access API, it writes back to the file the user opened with open(), and asks where to save otherwise; elsewhere, it downloads the file.

MethodDoes
save()Saves to the opened file, or asks where to save.
saveAs()Always asks, and then saves to the new file from then on.
saveCopy()Always asks, and keeps working on the original.
download()Always downloads.
close()Forgets the opened file, so the next save asks again.
js
const file = document.querySelector("pdf-file");
save.addEventListener("click", () => file.saveAs({ name: "filled.pdf" }));

Note: File pickers only open in response to a user action, such as a click. On a page with controls, the menu has Save and Open…, and Ctrl S and Ctrl O work in any page.

Getting the bytes

To upload a PDF or keep it yourself, saveData() returns its bytes, and export() a File or a Blob. Both include the form edits, unless you pass { noEdit: true }:

js
const file = document.querySelector("pdf-file");
await fetch("/upload", { method: "POST", body: await file.saveData() });
const blob = await file.export({ type: Blob, noEdit: true }); // as it loaded

Form data

file.XFDF saves and exports the form values alone, as XFDF, with the same methods. See Forms and XFDF.

Exporting page images

page.image.export() returns the image a page has drawn: as a Blob, a data: URL or a ClipboardItem, in PNG, WebP, JPEG, AVIF or, for an SVG page, SVG. Here a button exports the page as WebP and shows the result:

A page as an image

html
<pdf-file id=f src=//pdf.ist/web.pdf></pdf-file>
<pdf-page id=page of=f scale=0.3></pdf-page>
<button id=go>Export as WebP</button>
<img id=img alt>
css
pdf-page, img {
  width: 40%;
  vertical-align: top;
}
js
document.querySelector("#go").addEventListener("click", async () => {
  const blob = await document.querySelector("#page").image.export({ format: "webp", quality: 0.8 });
  document.querySelector("#img").src = URL.createObjectURL(blob);
});

The image is the page alone: transparent, without its paper color, its text and annotation layers, its signature cards, its controls or the evaluation watermark. JPEG has no transparency, so a JPEG gets white paper. page.image.metrics gives its size in pixels.

On a page with controls, Ctrl C copies the image and Ctrl D copies a data: URL as text. The clipboard takes images only as PNG (Chromium also takes SVG), so export(ClipboardItem) copies other formats as PNG.

Handling errors

The save and open promises reject when the user cancels a picker; a failed write is retried as a copy. Loading rejects with a PDFLoadError once the proxy retry has failed too, and exporting an image with a PDFExportError, for an unknown format or for SVG from a page drawn on a canvas. Both error classes are exported by the WebPDF module.

See also