/
ncit
/
c4panelmodel
Обзор
Документация
Войти
/
ncit
/
c4panelmodel
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
src/lib/utils/exportPdf.ts
92 строки
2 KB
ncit
feat: implement full IcePanel feature clone (Phases 1-8)
09 июн 2026, 11:13
09 июн 2026, 11:13
858c15a
Код
Авторство
О чём код?
/** * Export diagram as PDF using jsPDF (browser-side). * Wraps PNG export into a PDF page. */ import { exportPng } from './exportImage'; export interface PdfOptions { theme?: 'light' | 'dark'; pageSize?: 'a4' | 'letter' | 'fit'; orientation?: 'portrait' | 'landscape'; scale?: number; } export async function exportPdf(element: HTMLElement, opts: PdfOptions = {}): Promise<Blob> { const { jsPDF } = await import('jspdf'); // Determine page dimensions in mm. const pageSizes: Record<string, [number, number]> = { a4: [210, 297], letter: [215.9, 279.4], fit: [0, 0] // will be computed from image aspect ratio }; const [pw, ph] = pageSizes[opts.pageSize ?? 'a4'] ?? pageSizes.a4; const orientation = opts.orientation ?? 'landscape'; const width = orientation === 'landscape' ? Math.max(pw, ph) : Math.min(pw, ph); const height = orientation === 'landscape' ? Math.min(pw, ph) : Math.max(pw, ph); // Render element to PNG. const pngBlob = await exportPng(element, { theme: opts.theme, scale: opts.scale }); const pngUrl = URL.createObjectURL(pngBlob); try { const doc = new jsPDF({ orientation, unit: 'mm', format: opts.pageSize === 'fit' ? undefined : [width, height] }); // For 'fit' mode, compute dimensions from image aspect ratio. const img = await loadImage(pngUrl); let imgW: number; let imgH: number; if (opts.pageSize === 'fit') { const aspect = img.width / img.height; // Use A4 width as base, compute height from aspect. imgW = width; imgH = width / aspect; // Recreate doc with computed size. const fitDoc = new jsPDF({ orientation, unit: 'mm', format: [imgW, imgH] }); fitDoc.addImage(pngUrl, 'PNG', 0, 0, imgW, imgH); return fitDoc.output('blob'); } else { // Fit image within page with margins. const margin = 10; const maxW = width - margin * 2; const maxH = height - margin * 2; const aspect = img.width / img.height; if (maxW / aspect <= maxH) { imgW = maxW; imgH = maxW / aspect; } else { imgH = maxH; imgW = maxH * aspect; } const x = (width - imgW) / 2; const y = (height - imgH) / 2; doc.addImage(pngUrl, 'PNG', x, y, imgW, imgH); return doc.output('blob'); } } finally { URL.revokeObjectURL(pngUrl); } } function loadImage(src: string): Promise<HTMLImageElement> { return new Promise((resolve, reject) => { const img = new Image(); img.onload = () => resolve(img); img.onerror = reject; img.src = src; }); }