Files
2026-07-12 10:17:17 -04:00

1.9 KiB
Raw Permalink Blame History

PDF Export as Images (pdf-to-images.ts)

Converts every page of a jsPDF document into separate PNG files that the browser downloads automatically.

Installation

npm install pdfjs-dist

Worker config in main.tsx:

import * as pdfjsLib from 'pdfjs-dist';
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
  'pdfjs-dist/build/pdf.worker.min.mjs',
  import.meta.url,
).toString();

Function Signature

import { downloadPdfAsImages } from '../lib/pdf-to-images';

// Option A: pass a jsPDF instance
const doc = new jsPDF();
// ... build PDF content ...
await downloadPdfAsImages(doc, 'Jon Smith');

// Option B: pass a Blob from generateQuotePDF()
const blob = await generateQuotePDF(quote, settings);
await downloadPdfAsImages(blob, 'Jon Smith');

How It Works

  1. Accepts jsPDF | Blob — if Blob, reads as ArrayBuffer; if jsPDF, calls doc.output('arraybuffer')
  2. Loads PDF binary into pdfjsLib
  3. Iterates each page, renders onto an off-screen <canvas> at 2× scale (144 DPI)
  4. Exports canvas as image/png Blob
  5. Triggers a browser download for each page as {CustomerName}_Page{N}.png

Naming

Spaces in customer name become underscores. Output: Jon_Smith_Page1.png, Jon_Smith_Page2.png, etc.

Scale Tuning

  • scale = 1 → 72 DPI (small files)
  • scale = 2 → 144 DPI (default, good quality)
  • scale = 3 → 216 DPI (print quality, larger files)

Dual-Input Pattern

The function accepts both jsPDF and Blob to work with generateQuotePDF() which returns a Blob. This avoids needing to expose the internal jsPDF doc from the builder. The pattern is:

export async function downloadPdfAsImages(
  pdfInput: jsPDF | Blob,
  customerName: string,
): Promise<void> {
  let arrayBuffer: ArrayBuffer;
  if (pdfInput instanceof Blob) {
    arrayBuffer = await pdfInput.arrayBuffer();
  } else {
    arrayBuffer = pdfInput.output('arraybuffer');
  }
  // ... rest uses pdfjsLib
}