initial commit
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
# Exporting PDF Pages as PNG Images
|
||||
|
||||
When you need to export every page of a jsPDF document as individual PNG images (e.g., for sharing in chat, embedding in emails, or image-only workflows):
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install pdfjs-dist
|
||||
```
|
||||
|
||||
## Worker Setup (main.tsx or entry point)
|
||||
|
||||
```typescript
|
||||
import * as pdfjsLib from 'pdfjs-dist';
|
||||
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = new URL(
|
||||
'pdfjs-dist/build/pdf.worker.min.mjs',
|
||||
import.meta.url,
|
||||
).toString();
|
||||
```
|
||||
|
||||
## Implementation Pattern
|
||||
|
||||
The function accepts EITHER a jsPDF instance OR a Blob (from a function that returns `doc.output('blob')`):
|
||||
|
||||
```typescript
|
||||
export async function downloadPdfAsImages(
|
||||
pdfInput: jsPDF | Blob,
|
||||
customerName: string,
|
||||
): Promise<void> {
|
||||
// 1. Get raw PDF bytes
|
||||
let arrayBuffer: ArrayBuffer;
|
||||
if (pdfInput instanceof Blob) {
|
||||
arrayBuffer = await pdfInput.arrayBuffer();
|
||||
} else {
|
||||
arrayBuffer = pdfInput.output('arraybuffer');
|
||||
}
|
||||
|
||||
// 2. Load into pdfjs
|
||||
const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;
|
||||
|
||||
// 3. Render each page to canvas, then trigger download
|
||||
for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
|
||||
const page = await pdf.getPage(pageNum);
|
||||
const viewport = page.getViewport({ scale: 2 }); // 2x = Retina
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = viewport.width;
|
||||
canvas.height = viewport.height;
|
||||
const ctx = canvas.getContext('2d')!;
|
||||
|
||||
await page.render({ canvasContext: ctx, viewport }).promise;
|
||||
|
||||
const blob = await new Promise<Blob>((resolve) => {
|
||||
canvas.toBlob((b) => resolve(b!), 'image/png');
|
||||
});
|
||||
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `${customerName.replace(/\s+/g, '_')}_Page${pageNum}.png`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
page.cleanup();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Key Details
|
||||
|
||||
- **Scale**: `getViewport({ scale: 2 })` = 144 DPI. Use 1 for smaller files, 3-4 for print quality.
|
||||
- **Blob path**: If you have a function that already builds the PDF and returns `doc.output('blob')`, pass the blob directly — you don't need access to the jsPDF instance.
|
||||
- **Browser download**: Each page triggers its own download. Browsers batch them into the download bar.
|
||||
- **Memory**: `URL.revokeObjectURL()` and `page.cleanup()` prevent leaks with many pages.
|
||||
- **Dependency**: `pdfjs-dist` adds ~2MB to the bundle (worker + core).
|
||||
Reference in New Issue
Block a user