
BB Sport GmbH & Co KG
Söderbergstr. 14, 84513 Töging am Inn
Tel: +49 (0) 8631 988 2029 | E-Mail: service@unterkunft-fluechtlinge.de
Komplettset: teilbares Etagenbett 90x200 cm inklusive 2 Matratzen, 2 Betten-Sets, 2 Spannbettlaken und 2 Bettwäschegarnituren teilbar in zwei Einzelbetten



Komplettset: teilbares Etagenbett, Stockbett 90x200 inklusive 2 Matratzen, 2 Betten-Sets, 2 Spannbettlaken und 2 Bettwäschegarnituren
➽ Wichtig: Bitte übermitteln Sie uns nach der Bestellung Ihre Telefonnummer per E-Mail, da die Betten per Spedition versendet werden. Danke!
Bestehend aus:
- 1 Metall Etagenbett, Stockbett
- 2 Komfortschaummatratzen 90 x 200 x 10 cm
- 2 Spannbettlaken 90 x 200 cm
- 2 Mikrofaser Bettensets Bettdecke 135 x 200 cm und Kissen 80 x 80 cm
- 2 Bettwäschegarnituren 2 teilig 135 x 200 cm mit Hotelverschluss
Metall Etagenbett, Stockbett - teilbar in zwei Einzelbetten
Stabile Metallrahmenkonstruktion für eine platzsparende Lösung in Jugendheimen, Wohnheimen, Notunterkünften, Kasernen etc.
Unsere Etagenbetten stehen für geprüfte Qualität. Sie erfüllen sowohl die Anforderungen der bisherigen Norm DIN EN 747-1:2012+A1:2015 und DIN EN 747-2:2012+A1:2015 als auch der aktuellen Norm DIN EN 747-1:2024 und DIN EN 747-2:2024.
Das Bett ist bei Bedarf teilbar in zwei Einzelbetten, verfügt über eine fest anschraubbare Leiter, Metall-Gitterroste sowie extra hohe Fallschutzgitter. Die Metallbetten sind leicht zu reinigen, sehr stabil und dabei trotzdem einfach und schnell montiert. Sie bieten den Standard-Matratzen in einer Größe von 90 x 200 cm Platz. Jedes Bett kann bis zu 180 kg belastet werden.
Details:
- Einsatzbereiche: Kasernen, Wachen, Notunterkünfte, Jugendheime, Wohnheime etc.
- Geprüft nach DIN EN 747: DIN EN 747-1:2012+A1:2015 | DIN EN 747-2:2012+A1:2015
- Teilbar in zwei Einzelbetten
- Robuste Metallrahmenkonstruktion
- Inkl. Metall-Gitterroste
- Belastbarkeit je Bett 180 kg
- Liegefläche je Bett 90 x 200 cm
- Hohe Fallschutzgitter mit 27 cm Höhe
- Nicht für Kinder unter 6 Jahren geeignet
Technische Daten:
| Außenmaße Bett komplett: | 97 x 209 cm, Höhe 162 cm |
| Bodenfreiheit: | 31,5 cm |
| Leiter: | 123,5 x 34,5 cm, 4 Sprossen |
| Höhe Fallschutz: | 36,8 cm |
| Kopffreiheit (ohne Matratze): | 85 cm |
| Material: | Metall, pulverbeschichtet; Standrohre Ø 50 mm, Außenrahmen Matratzen-Auflage 40,5 x 20,3 mm |
| Gewicht: | 46 kg |
| Packmaß: | 204,5 x 99,5 x 15,5 cm |
Komfortschaummatratze Rollmatratze Matratze 90 x 200 x 10 cm
Die Rollmatratze ist eine Komfortschaummatratze mit einem beidseitig mit Klimafaser versteppten Bezug.
Details
| Bezugsmaterial: | 100 % Polyester |
| RG: | 25 |
| Packmaß: | Durchmesser von 28 cm, Länge von 96 cm |
| Gewicht: | 5,25 kg |
Spannbettlaken 90 x 200 cm
Durch die Polyester-/ Baumwollmischung ist der Stoff pflegeleicht und neigt weniger zum Einlaufen und Knittern. Die Materialien sind nach STANDARD 100 by OEKO-TEX® (Zertifikat Nr. 02.0.5999, Institut Hohenstein) zertifiziert und damit frei von gesundheitsschädlichen Substanzen.
Details:
- aus 52 % Polyester (100 % recycelt), 48 % Baumwolle
- Eckenhöhe: bis ca. 16 cm
- waschbar bis 60 °C
- trocknergeeignet
- Maße (BxL): ca. 90/ 100 x 190/ 200 cm
- Gewicht: 380 g
- Farbe: Cremeweiß
ⓘ Hinweis: Die Lieferung erfolgt in einer verfügbaren Farbvariante. Abweichungen von der Abbildung sind möglich.
Mikrofaser Bettenset, Bettdecke 135 x 200 cm und Kissen 80 x 80 cm
Ausgeruht und erholt - so gelingt der Start in einen erfolgreichen Tag. Viele Faktoren beeinflussen unseren Schlaf, besonders wichtig ist das richtige Betten-Set, welches für die jeweiligen Schlaf-Bedürfnisse passen sollte.
Die Mikrofaser-Bettdecke ist robust und pflegeleicht. Die ausgleichenden Eigenschaften der Polyester-Mikrofasern bieten eine angenehme Wärmeleistung und eine optimale Atmosphäre für Ihren Schlaf. Im weiteren speichert die Mikrofaser z. B. keine Feuchtigkeit, sondern lagert sie zwischen den Faserzwischenräumen an. Dadurch kann diese sehr rasch verdunsten und das Material bietet stehts die richtige Balance zwischen angenehmer Wärme und regulierender Kühle. Die Steppung sorgt rundum für die passende Isolation.
Hautsympathisch und mittestark befüllt ist das Kopfkissen. Es passt sich durch den hohen Bausch hervorragend an wechselnde Schlafpositionen an und beschert durch die Elastitizät einen erholsamen Schlaf. Die Materialien sind nach STANDARD 100 by OEKO-TEX® (Zertifikat Nr. 02.0.5999, Institut Hohenstein) zertifiziert und damit frei von gesundheitsschädlichen Substanzen.
Details zum Betten-Set:
- Verwöhnende Qualität - leicht, weich und geschmeidig - trotzdem strapazierfähig, pflegeleicht und griffig
- Gute Alternative zu oftmals sehr kostspieliger Seide oder Daune
- Bestes Schlafklima - Mikrofaser speichert im Vergleich zu Baumwolle nicht die Feuchtigkeit, sondern lagert sie zwischen den Faserzwischenräumen an - dadurch kann diese rasch verdunsten
- Gute Wärmeeigenschaften
- Formbeständig und Faltenfrei
- Atmungsaktiv und schnell trocknend
- Bettdecke aus recyceltem Polyester
- Kopfkissen mit mittelstarker Füllung und gutem Bausch
- Hinweis: Um die Atmungsaktivität Ihres Produktes zu erhalten, sollte beim Waschen auf Weichspüler verzichtet werden, da dieser die Fasern verklebt.
Technische Daten:
| Material: | Bettdecke: 100 % Polyester (100 % recycelt) / Kissen: 100 % Polyester [Mikrofaser] |
| Maße Bettdecke: | 135 x 200 cm |
| Maße Kopfkissen: | 80 x 80 cm |
| Gewicht Bettdecke: | 1060 g |
| Gewicht Kopfkissen: | 860 g |
| Maschinenwaschbar bei: | 60 °C (Bettdecke) / 40 °C (Kissen) |
| Nutzung: | Flüchtlingsunterkünfte, Monteurwohnungen, privater Gebrauch |
| Wärmeklasse: | 3 / 10,5 tog |
| Pflegehinweise: | Keine chemische Reinigung, nicht bleichen, nicht bügeln, trocknergeeignet bei niedriger Temperatur (Bettdecke max. 60 °C / Kissen Schontrockengang) |
Bettwäsche Bettgarnitur 2-teilig 135x200 / 80x80 cm
Schaffen Sie sich eine angenehme Atmosphäre in Ihrem Schlafzimmer und damit die Grundlage für einen entspannten und erholsamen Schlaf.
Durch die Polyester-/ Baumwollmischung ist der Stoff pflegeleicht und neigt weniger zum Einlaufen und Knittern. Die glatte Oberfläche ist äußerst weich, leicht und wärmt angenehm. Die Bettgarnitur hat einen praktischen Hotelverschluss. Einfach einschlagen und fertig, ganz ohne Knöpfe oder Reißverschluss. Diese Alltagstauglichkeit wissen vor allem Familien mit Kindern, aber auch alle anderen Haushalte, die häufig waschen müssen, sehr zu schätzen. Die Materialien sind nach STANDARD 100 by OEKO-TEX® (Zertifikat Nr. 02.0.5999, Institut Hohenstein) zertifiziert und damit frei von gesundheitsschädlichen Substanzen.
Details zum Bettwäsche-Set:
- Hautfreundlich, strapazierfähig und pflegeleicht
- Für Allergiker geeignet
- Hotelverschluss für leichtes Wechseln
- 2-teiliges Set bestehend aus: 1 x Kissenbezug 80 x 80 cm + 1 x Bettbezug 135 x 200 cm
Technische Daten:
| Material: | 52 % Polyester (100 % recycelt), 48 % Baumwolle |
| Prüfnorm-Nr. Oeko-Tex® Standard 100: | 11.HCN.89512 Hohenstein HTTI |
| Jahreszeiten: | 4-Jahreszeiten-Bettwäsche |
| Verschluss: | Hotelverschluss / Druckknöpfe |
| Pflegehinweise: | Maschinenwaschbar bei 40 °C Buntwäsche, max. 60 °C. Nicht mit Chlor bleichen Trocknergeeignet bei Normaltemperatur (max. 80 °C) Bügeln bei max. 150 °C Nicht chem. reinigen |
| Gewicht: | 720 g |
ⓘ Hinweis: Die Lieferung erfolgt in einer verfügbaren Designvariante. Abweichungen von der Abbildung sind möglich.
Drucken nicht möglich
Sie können das PDF herunterladen und manuell drucken.
'; previewDiv.appendChild(link); } // Funktion zur PDF-Generierung function generatePDF() { // Melde dem Benutzer, dass die PDF-Generierung beginnt console.log('PDF-Generierung wird gestartet...'); // Hole die jsPDF-Instanz const { jsPDF } = window.jspdf; // Erstelle ein neues PDF-Dokument im A4-Format const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4', compress: true }); // Setze eine eindeutige Funktion, die für alle Seitenoperationen aufgerufen wird // Diese zentralisierte Verarbeitung stellt sicher, dass alle Seiten konsistent formatiert werden doc.setPageCallback = function(pageInfo) { console.log("Seite verarbeitet:", pageInfo.pageNumber); addHeader(); addFooter(pageInfo.pageNumber); }; // Überschreibe die interne addPage-Methode, um unsere Callback-Funktion aufzurufen const originalAddPage = doc.addPage; doc.addPage = function() { originalAddPage.apply(this, arguments); const pageInfo = doc.getCurrentPageInfo(); if (doc.setPageCallback) { doc.setPageCallback(pageInfo); } }; // Füge Metadaten zum PDF hinzu doc.setProperties({ title: 'Datenblatt', subject: 'Datenblatt', author: 'BB Sport GmbH & Co KG', keywords: 'Produkte', creator: 'BB Sport GmbH & Co KG' }); // Definiere Standardschriftart und -größe doc.setFont('helvetica'); doc.setFontSize(10); // Standardabstände const margin = 20; let currentY = margin; // Funktion zum Zeichnen des Headers auf jeder Seite function addHeader() { // Position zurücksetzen currentY = margin; // Prüfe, ob wir das Logo bereits vorgeladen haben if (logoDataURL) { // Verwende das vorgeladene Logo mit korrektem Seitenverhältnis console.log('Verwende vorgeladenes Logo im Header mit Dimensionen:', logoWidth, 'x', logoHeight, 'mm'); // Setze das Logo etwas höher, damit es besser zentriert ist doc.addImage(logoDataURL, 'PNG', margin, currentY, logoWidth, logoHeight); } else { const logoSrc = 'https://cdn02.plentymarkets.com/5rubvkuloybx/frontend/Template/UF-logo.png'; // Logo direkt im Dokument suchen als Fallback const logoImg = document.getElementById('logoImage'); if (logoImg && logoImg.complete && logoImg.naturalWidth > 0) { try { console.log('Logo aus DOM laden'); // Seitenverhältnis des DOM-Images berechnen const imgAspectRatio = logoImg.naturalWidth / logoImg.naturalHeight; const adjustedHeight = logoWidth / imgAspectRatio; const canvas = document.createElement('canvas'); canvas.width = logoImg.naturalWidth; canvas.height = logoImg.naturalHeight; const ctx = canvas.getContext('2d'); ctx.drawImage(logoImg, 0, 0); const logoDataURLFromDOM = canvas.toDataURL('image/png'); doc.addImage(logoDataURLFromDOM, 'PNG', margin, currentY, logoWidth, adjustedHeight); console.log('Logo erfolgreich aus DOM geladen und hinzugefügt'); } catch (e) { console.warn('Logo konnte nicht aus DOM geladen werden:', e); // LOGO-Text wird NICHT mehr angezeigt - wir versuchen jetzt, ein Bild zu laden loadImageDirectlyIntoPDF(logoSrc, margin, currentY, logoWidth); } } else { // Versuche das Logo direkt zu laden loadImageDirectlyIntoPDF(logoSrc, margin, currentY, logoWidth); } } // Firmenname und Kontaktdaten doc.setFont('helvetica', 'bold'); doc.setFontSize(14); doc.text('BB Sport GmbH & Co KG', 190, currentY + 5, { align: 'right' }); doc.setFont('helvetica', 'normal'); doc.setFontSize(8); doc.text('Söderbergstr. 14, 84513 Töging am Inn', 190, currentY + 10, { align: 'right' }); doc.text('Tel: +49 (0) 8631 988 2029 | E-Mail: service@unterkunft-fluechtlinge.de', 190, currentY + 15, { align: 'right' }); // Linie unter dem Header currentY += 20; doc.setDrawColor(200, 200, 200); doc.line(margin, currentY, 190, currentY); currentY += 10; return currentY; } // Direktes Laden eines Bildes in das PDF function loadImageDirectlyIntoPDF(src, x, y, width) { fetch('https://corsproxy.io/?url=' + encodeURIComponent(src)) .then(response => response.blob()) .then(blob => { const reader = new FileReader(); reader.onload = function() { const imgData = reader.result; // Temporäres Image zum Ermitteln der Dimensionen erstellen const tempImg = new Image(); tempImg.onload = function() { // Berechne Höhe basierend auf dem Seitenverhältnis const imgAspectRatio = tempImg.width / tempImg.height; const height = width / imgAspectRatio; // Logo in allen Seiten einfügen const pageCount = doc.internal.getNumberOfPages(); for (let i = 1; i <= pageCount; i++) { doc.setPage(i); doc.addImage(imgData, 'PNG', x, y, width, height); } }; tempImg.src = imgData; }; reader.readAsDataURL(blob); }) .catch(error => { console.error('Fehler beim direkten Laden des Logos:', error); }); } // Funktion zum Zeichnen des Footers auf jeder Seite function addFooter(pageNumber) { // Position des Footers definieren (weiter unten auf der Seite) const pageHeight = doc.internal.pageSize.height; const footerPosition = pageHeight - 10; // 10mm vom unteren Rand // Linie über dem Footer doc.setDrawColor(200, 200, 200); doc.line(margin, footerPosition - 15, 190, footerPosition - 15); // Footer-Text doc.setFont('helvetica', 'normal'); doc.setFontSize(8); doc.text('BB Sport GmbH & Co KG | E-mail: service@unterkunft-fluechtlinge.de', 105, footerPosition - 10, { align: 'center' }); doc.text('Bürozeiten: Montag bis Donnerstag von 7.30 - 17.00 Uhr | Freitag von 7:30 - 13.30 Uhr', 105, footerPosition - 5, { align: 'center' }); // Seitenzahl - nun prominent im Footer positioniert doc.setFont('helvetica', 'bold'); // Fett für Seitenzahlen doc.setFontSize(9); // Etwas größer für bessere Lesbarkeit doc.text('Seite ' + pageNumber, 190, footerPosition - 5, { align: 'right' }); } // Erstelle das PDF async function createPDF() { try { // Wir zeichnen den Header für die erste Seite currentY = addHeader(); addFooter(1); // Kundendaten doc.setFont('helvetica', 'bold'); doc.setFontSize(12); doc.text('Produktinformationen', margin, currentY); currentY += 10; // Extrahiere den echten Content const productContent = document.querySelector('.printrow'); if (productContent) { // Produkttitel const title = productContent.querySelector('.printname')?.textContent || 'Produkttitel'; const articleNumber = productContent.querySelector('.printnumber')?.textContent || 'ArtikelNr.: ---'; // Titel einfügen doc.setFont('helvetica', 'bold'); doc.setFontSize(14); // Splitten des Textes, falls er zu lang für eine Zeile ist const titleLines = doc.splitTextToSize(title, 190 - 2 * margin); doc.text(titleLines, margin, currentY); currentY += titleLines.length * 7 + 3; // Artikelnummer doc.setFontSize(10); doc.setFont('helvetica', 'normal'); doc.text(articleNumber, margin, currentY); currentY += 8; // Produktbilder await processImages(productContent); // Produktbeschreibung processDescription(productContent); // Footer für die erste Seite hinzufügen addFooter(1); // Das PDF speichern oder öffnen // Die Output-Methode auf 'blob' setzen const pdfOutput = doc.output('blob'); // Speichern des PDF-Blobs für späteren Zugriff pdfBlob = pdfOutput; // Falls bereits eine URL für ein vorheriges PDF existiert, diese freigeben if (pdfObjectURL) { URL.revokeObjectURL(pdfObjectURL); } // Erstellen einer URL für den PDF-Blob pdfObjectURL = URL.createObjectURL(pdfBlob); // Dateiname festlegen (für evtl. späteren Download) lastPDFFilename = 'Produktdokument.pdf'; console.log('PDF wurde erfolgreich generiert!'); // Direkt zum Drucken übergehen, ohne Download try { printPDF(); } catch (printError) { console.error('Fehler beim Druckversuch:', printError); alert('Das PDF wurde erstellt, aber der Druckdialog konnte nicht automatisch geöffnet werden.\n\nBitte klicken Sie auf "PDF drucken".'); } } else { doc.text("Keine Produktinformationen gefunden.", margin, currentY); const pdfOutput = doc.output('blob'); pdfBlob = pdfOutput; if (pdfObjectURL) { URL.revokeObjectURL(pdfObjectURL); } pdfObjectURL = URL.createObjectURL(pdfBlob); lastPDFFilename = 'Dokument.pdf'; console.log('Leeres PDF wurde generiert'); // Auch hier direkt drucken try { printPDF(); } catch (printError) { console.error('Fehler beim Druckversuch:', printError); alert('Das PDF wurde erstellt, aber der Druckdialog konnte nicht automatisch geöffnet werden.\n\nBitte klicken Sie auf "PDF drucken".'); } } } catch (error) { console.error("Fehler bei der PDF-Erstellung:", error); alert("Fehler bei der PDF-Erstellung: " + error.message); } } // Bildverarbeitung async function processImages(productContent) { const images = productContent.querySelectorAll('.printimg img'); if (!images || images.length === 0) return; for (let i = 0; i < images.length; i++) { const imgSrc = images[i].getAttribute('src'); if (!imgSrc || imgSrc.trim() === '') continue; try { // Direkt über fetch laden (umgeht Canvas-CORS) const imageData = await loadImage(imgSrc); // Dimensionen über temporäres Image ermitteln const dims = await new Promise((resolve) => { const tempImg = new Image(); tempImg.onload = () => resolve({ w: tempImg.width, h: tempImg.height }); tempImg.onerror = () => resolve({ w: 1000, h: 800 }); tempImg.src = imageData; }); const imgWidth = 80; const imgHeight = imgWidth * dims.h / dims.w; if (currentY + imgHeight > 250) { doc.addPage(); currentY = margin + 30; addHeader(); } doc.addImage(imageData, 'JPEG', margin, currentY, imgWidth, imgHeight); currentY += imgHeight + 10; console.log('Bild ' + (i+1) + ' erfolgreich eingefügt'); break; // Nur erstes Bild } catch (e) { console.warn('Bild ' + (i+1) + ' fehlgeschlagen:', e.message); } } } // Verarbeite die Produktbeschreibung function processDescription(productContent) { const descSection = productContent.querySelector('.printdesc'); if (descSection) { // Alle direkten Kindelemente in der originalen Reihenfolge durchlaufen const childNodes = descSection.children; console.log('Verarbeite Beschreibung mit ' + childNodes.length + ' Elementen'); for (let i = 0; i < childNodes.length; i++) { const element = childNodes[i]; const tagName = element.tagName.toLowerCase(); // Überschriften (h1, h2, h3, etc.) if (tagName.startsWith('h') && tagName.length === 2) { const headingText = element.textContent || ''; const headingLevel = parseInt(tagName[1]); doc.setFont('helvetica', 'bold'); doc.setFontSize(headingLevel === 2 ? 12 : (headingLevel === 3 ? 11 : 10)); // Splitten des Textes, falls er zu lang für eine Zeile ist const headingLines = doc.splitTextToSize(headingText, 190 - 2 * margin); // Prüfen, ob genug Platz auf der Seite ist if (currentY + headingLines.length * 7 > 250) { doc.addPage(); // Header auf der neuen Seite hinzufügen currentY = margin + 30; // Zurücksetzen der Y-Position addHeader(); // Header hinzufügen } doc.text(headingLines, margin, currentY); currentY += headingLines.length * 7 + 3; } // Absätze else if (tagName === 'p') { const paragraphText = element.textContent || ''; doc.setFont('helvetica', 'normal'); doc.setFontSize(10); // Splitten des Textes, falls er zu lang für eine Zeile ist const paragraphLines = doc.splitTextToSize(paragraphText, 190 - 2 * margin); // Prüfen, ob genug Platz auf der Seite ist if (currentY + paragraphLines.length * 5 > 250) { doc.addPage(); // Header auf der neuen Seite hinzufügen currentY = margin + 30; // Zurücksetzen der Y-Position addHeader(); // Header hinzufügen } doc.text(paragraphLines, margin, currentY); currentY += paragraphLines.length * 5 + 5; } // Listen else if (tagName === 'ul') { const listItems = element.querySelectorAll('li'); listItems.forEach(item => { const itemText = '• ' + (item.textContent || ''); doc.setFont('helvetica', 'normal'); doc.setFontSize(10); // Splitten des Textes, falls er zu lang für eine Zeile ist const itemLines = doc.splitTextToSize(itemText, 185 - 2 * margin); // Prüfen, ob genug Platz auf der Seite ist if (currentY + itemLines.length * 5 > 250) { doc.addPage(); // Header auf der neuen Seite hinzufügen currentY = margin + 30; // Zurücksetzen der Y-Position addHeader(); // Header hinzufügen } doc.text(itemLines, margin, currentY); currentY += itemLines.length * 5 + 2; }); currentY += 3; // Zusätzlicher Abstand nach der Liste } // Tabellen else if (tagName === 'table') { const tableElement = element; // Reduziere den Abstand vor der Tabelle currentY += 2; // Früher: 5 // Lasse die Überschrift "Technische Daten" weg, da sie bereits als h3 enthalten ist //doc.setFont('helvetica', 'bold'); //doc.setFontSize(11); //doc.text('Technische Daten', margin, currentY); currentY += 2; // Früher: 7 - Reduziere den Leerraum const rows = tableElement.querySelectorAll('tr'); const tableData = []; rows.forEach(row => { const cells = row.querySelectorAll('td'); if (cells.length >= 2) { const rowData = [ cells[0].textContent || '', cells[1].textContent.replace(/\t{2,}/g, "\n").replace(/\t/g, " ") || '' ]; tableData.push(rowData); } }); // Technische Daten als Tabelle rendern if (tableData.length > 0) { doc.autoTable({ startY: currentY, body: tableData, theme: 'plain', // Zurück zu 'plain' und manueller Linien-Steuerung styles: { fontSize: 9, cellPadding: 3, lineWidth: 0.5, // Einheitliche Linienstärke lineColor: [80, 80, 80] // Dunkelgrau }, columnStyles: { 0: { fontStyle: 'bold', cellWidth: 40 }, 1: { cellWidth: 'auto' } }, margin: { left: margin, right: margin, top: 40, // Abstand von oben für den Header bottom: 40 // Mehr Abstand unten für den Footer }, // Klare Tabelleneigenschaften tableLineWidth: 0.5, // Moderate Linienstärke tableLineColor: [80, 80, 80], // Dunkelgrau drawCell: function(cell, data) { // Klar definierte Zellenrahmen für alle Zellen const doc = data.doc; const cellPos = cell.getTextPos(); // Zeichne standardmäßig alle Außenlinien doc.setDrawColor(80, 80, 80); // Einheitliche Linienfarbe doc.setLineWidth(0.5); // Einheitliche Linienstärke // Zeichne Zellenrahmen (oben, rechts, unten, links) doc.rect(cell.x, cell.y, cell.width, cell.height, 'S'); }, // Entferne den didParseCell-Handler, der dickere Linien hinzugefügt hat didDrawPage: function(data) { // Header und Footer werden nicht explizit hier gezeichnet, // da die modifizierte addPage-Methode dies automatisch macht } }); // Position nach der Tabelle aktualisieren currentY = doc.autoTable.previous.finalY + 5; // Reduziere auch den Abstand nach der Tabelle } } } } } // Hilfsfunktion zum Laden eines Bildes function loadImage(src) { return new Promise(async (resolve, reject) => { try { const proxyUrl = 'https://apps.spotlight-dev.de/image-proxy?url=' + encodeURIComponent(src); const response = await fetch(proxyUrl); if (!response.ok) throw new Error('Status: ' + response.status); const blob = await response.blob(); if (blob.size === 0) throw new Error('Leere Antwort'); const reader = new FileReader(); reader.onloadend = () => resolve(reader.result); reader.onerror = () => reject(new Error('FileReader-Fehler')); reader.readAsDataURL(blob); } catch (e) { console.error('Bildladung fehlgeschlagen:', src, e.message); reject(e); } }); } // Hilfsfunktion: Blob → DataURL function blobToDataURL(blob) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result); reader.onerror = reject; reader.readAsDataURL(blob); }); } // Starte die PDF-Erstellung createPDF(); } setTimeout(function(){ generatePDF(); },1000) });