Save Documents
This guide explains how to save PDF documents and the available save options.
Basic Save
Section titled “Basic Save”// Save existing documentusing document = await pdfium.openDocument(data);const bytes = document.save();await fs.writeFile('output.pdf', bytes);
// Save new documentusing builder = pdfium.createDocument();// ... add content ...const bytes = builder.save();await fs.writeFile('output.pdf', bytes);Save Options
Section titled “Save Options”Both PDFiumDocument.save() and PDFiumDocumentBuilder.save() accept options:
interface SaveOptions { flags?: SaveFlags; version?: number;}SaveFlags
Section titled “SaveFlags”import { SaveFlags } from '@scaryterry/pdfium';| Flag | Value | Description |
|---|---|---|
None | 0 | Default full save |
Incremental | 1 | Append changes (preserves signatures) |
NoIncremental | 2 | Force full rewrite |
RemoveSecurity | 3 | Remove encryption |
PDF Version
Section titled “PDF Version”Specify the PDF version as a number:
| Version | Value | Released |
|---|---|---|
| PDF 1.4 | 14 | 2001 |
| PDF 1.5 | 15 | 2003 |
| PDF 1.6 | 16 | 2004 |
| PDF 1.7 | 17 | 2006 |
| PDF 2.0 | 20 | 2017 |
Save Modes Explained
Section titled “Save Modes Explained”Default Save (None)
Section titled “Default Save (None)”Rewrites the entire PDF:
const bytes = document.save();// orconst bytes = document.save({ flags: SaveFlags.None });Characteristics:
- Creates optimised file
- May invalidate digital signatures
- Removes document history
- Usually smaller file size
Incremental Save
Section titled “Incremental Save”Appends changes to the end of the file:
const bytes = document.save({ flags: SaveFlags.Incremental });Characteristics:
- Preserves digital signatures
- Maintains document history
- Faster for large documents with small changes
- File size grows with each save
Use when:
- Document has digital signatures
- Audit trail is required
- Making small modifications
Force Non-Incremental
Section titled “Force Non-Incremental”Forces full rewrite even if incremental would be possible:
const bytes = document.save({ flags: SaveFlags.NoIncremental });Remove Security
Section titled “Remove Security”Removes encryption (requires correct password to open first):
// Open with passwordusing document = await pdfium.openDocument(data, { password: 'secret' });
// Save without encryptionconst bytes = document.save({ flags: SaveFlags.RemoveSecurity });Specifying PDF Version
Section titled “Specifying PDF Version”// Save as PDF 1.7const bytes = document.save({ version: 17 });
// Save as PDF 2.0const bytes = document.save({ version: 20 });Version Compatibility
Section titled “Version Compatibility”| Feature | Minimum Version |
|---|---|
| Basic PDF | 1.4 |
| Compressed objects | 1.5 |
| AES encryption | 1.6 |
| PDF/A-2 | 1.7 |
| New annotation types | 2.0 |
Error Handling
Section titled “Error Handling”import { DocumentError, PDFiumErrorCode } from '@scaryterry/pdfium';
try { const bytes = document.save(); await fs.writeFile('output.pdf', bytes);} catch (error) { if (error instanceof DocumentError) { if (error.code === PDFiumErrorCode.DOC_SAVE_FAILED) { console.error('Failed to save document:', error.message); } } throw error;}Save to Different Formats
Section titled “Save to Different Formats”Save to Buffer
Section titled “Save to Buffer”const bytes = document.save();// bytes is Uint8ArraySave to File
Section titled “Save to File”import { promises as fs } from 'fs';
const bytes = document.save();await fs.writeFile('output.pdf', bytes);Save to Stream
Section titled “Save to Stream”import { createWriteStream } from 'fs';
const bytes = document.save();const stream = createWriteStream('output.pdf');stream.write(bytes);stream.end();Send as HTTP Response (Node.js)
Section titled “Send as HTTP Response (Node.js)”// Express.js exampleapp.get('/download', async (req, res) => { const data = await fs.readFile('document.pdf');
using pdfium = await PDFium.init(); using document = await pdfium.openDocument(data);
// Modify document...
const bytes = document.save();
res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', 'attachment; filename="output.pdf"'); res.send(Buffer.from(bytes));});Browser Download
Section titled “Browser Download”function downloadPDF(bytes: Uint8Array, filename: string) { const blob = new Blob([bytes], { type: 'application/pdf' }); const url = URL.createObjectURL(blob);
const link = document.createElement('a'); link.href = url; link.download = filename; link.click();
URL.revokeObjectURL(url);}
// Usageconst bytes = document.save();downloadPDF(bytes, 'output.pdf');Complete Examples
Section titled “Complete Examples”Copy with Version Update
Section titled “Copy with Version Update”import { PDFium } from '@scaryterry/pdfium';import { promises as fs } from 'fs';
async function upgradePDFVersion(inputPath: string, outputPath: string) { const data = await fs.readFile(inputPath);
using pdfium = await PDFium.init(); using document = await pdfium.openDocument(data);
// Save as PDF 1.7 const bytes = document.save({ version: 17 }); await fs.writeFile(outputPath, bytes);
console.log(`Upgraded ${inputPath} to PDF 1.7`);}Remove Password Protection
Section titled “Remove Password Protection”async function removePassword( inputPath: string, outputPath: string, password: string) { const data = await fs.readFile(inputPath);
using pdfium = await PDFium.init(); using document = await pdfium.openDocument(data, { password });
const bytes = document.save({ flags: SaveFlags.RemoveSecurity }); await fs.writeFile(outputPath, bytes);
console.log('Password protection removed');}Incremental Save Workflow
Section titled “Incremental Save Workflow”async function signaturePreservingSave( inputPath: string, outputPath: string) { const data = await fs.readFile(inputPath);
using pdfium = await PDFium.init(); using document = await pdfium.openDocument(data);
// Make modifications here...
// Save incrementally to preserve signatures const bytes = document.save({ flags: SaveFlags.Incremental }); await fs.writeFile(outputPath, bytes);
console.log('Saved with signatures preserved');}Batch Processing
Section titled “Batch Processing”import { promises as fs } from 'fs';import path from 'path';
async function convertPDFVersions( inputDir: string, outputDir: string, targetVersion: number) { using pdfium = await PDFium.init();
const files = await fs.readdir(inputDir); const pdfFiles = files.filter(f => f.toLowerCase().endsWith('.pdf'));
await fs.mkdir(outputDir, { recursive: true });
for (const file of pdfFiles) { const inputPath = path.join(inputDir, file); const outputPath = path.join(outputDir, file);
try { const data = await fs.readFile(inputPath); using document = await pdfium.openDocument(data);
const bytes = document.save({ version: targetVersion }); await fs.writeFile(outputPath, bytes);
console.log(`Converted: ${file}`); } catch (error) { console.error(`Failed: ${file}`, error); } }}
// Convert all PDFs to version 1.7convertPDFVersions('./input', './output', 17);See Also
Section titled “See Also”- PDFiumDocument — Document API reference
- PDFiumDocumentBuilder — Creating documents
- SaveFlags Enum — Save flags reference
- Open Document Guide — Loading documents