fix: robust per-card PDF export to avoid blank pages

This commit is contained in:
2026-03-08 10:35:29 +01:00
parent a3e75c0950
commit 8b9c878132

View File

@@ -73,6 +73,8 @@ body.modal-open { overflow: hidden; }
<link rel="stylesheet" href="https://uicdn.toast.com/editor/latest/toastui-editor.min.css" /> <link rel="stylesheet" href="https://uicdn.toast.com/editor/latest/toastui-editor.min.css" />
<script src="https://uicdn.toast.com/editor/latest/toastui-editor-all.min.js"></script> <script src="https://uicdn.toast.com/editor/latest/toastui-editor-all.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
</head><body> </head><body>
<div class="topbar"> <div class="topbar">
<button id="menuToggle" class="menu-btn"></button> <button id="menuToggle" class="menu-btn"></button>
@@ -496,44 +498,61 @@ function closeAiModal(){
} }
async function downloadPdf(){ async function downloadPdf(){
if (!window.html2pdf) { if (!window.html2canvas || !window.jspdf?.jsPDF) {
alert('PDF-Export-Bibliothek nicht geladen.'); alert('PDF-Export-Bibliothek nicht geladen.');
return; return;
} }
const root = document.createElement('div'); const root = document.createElement('div');
root.style.position = 'fixed'; root.style.position = 'fixed';
root.style.left = '0'; root.style.left = '-10000px';
root.style.top = '0'; root.style.top = '0';
root.style.width = '210mm'; root.style.width = '1200px';
root.style.minHeight = '297mm';
root.style.background = '#fff'; root.style.background = '#fff';
root.style.padding = '8mm';
root.style.zIndex = '-1';
root.style.opacity = '0.01';
root.style.pointerEvents = 'none';
root.innerHTML = app.innerHTML; root.innerHTML = app.innerHTML;
root.querySelectorAll('.card-actions,.card-action-btn,button,[data-edit-all]').forEach(el => el.remove()); root.querySelectorAll('.card-actions,.card-action-btn,button,[data-edit-all]').forEach(el => el.remove());
root.querySelectorAll('.exercise-container').forEach(el => { el.style.pageBreakAfter = 'always'; });
root.querySelectorAll('.card-size').forEach(el => { root.querySelectorAll('.card-size').forEach(el => {
el.style.boxShadow = 'none'; el.style.boxShadow = 'none';
el.style.margin = '0 auto 10mm auto'; el.style.margin = '0 0 12px 0';
}); });
document.body.appendChild(root); document.body.appendChild(root);
const opt = {
margin: [5, 5, 5, 5],
filename: `coachingcards-${new Date().toISOString().slice(0,10)}.pdf`,
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2, useCORS: true, backgroundColor: '#ffffff', logging: false },
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' },
pagebreak: { mode: ['css', 'legacy'] }
};
try { try {
await window.html2pdf().set(opt).from(root).save(); const cards = [...root.querySelectorAll('.card-size')];
if (!cards.length) {
alert('Keine Karten für den Export sichtbar.');
return;
}
const { jsPDF } = window.jspdf;
const pdf = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' });
const pageW = pdf.internal.pageSize.getWidth();
const pageH = pdf.internal.pageSize.getHeight();
const margin = 8;
const usableW = pageW - margin * 2;
const usableH = pageH - margin * 2;
for (let i = 0; i < cards.length; i++) {
const canvas = await window.html2canvas(cards[i], {
scale: 2,
useCORS: true,
backgroundColor: '#ffffff',
logging: false
});
const img = canvas.toDataURL('image/jpeg', 0.98);
const imgW = canvas.width;
const imgH = canvas.height;
const ratio = Math.min(usableW / imgW, usableH / imgH);
const drawW = imgW * ratio;
const drawH = imgH * ratio;
const x = margin + (usableW - drawW) / 2;
const y = margin + (usableH - drawH) / 2;
if (i > 0) pdf.addPage();
pdf.addImage(img, 'JPEG', x, y, drawW, drawH, undefined, 'FAST');
}
pdf.save(`coachingcards-${new Date().toISOString().slice(0,10)}.pdf`);
} finally { } finally {
root.remove(); root.remove();
} }