POUR CEUX QUI VEULENT GENERER UN DOCUMENT JE VAIS VOUS MONTRER COMMENT GENERER UN, TEXTE, UN TABLEAU ET UNE IMAGE MAIS JE NE VAIS QUE ME LIMITER AUX TROIS ENTITES.
//BACKEND COMMENT DECLENCHER UN TELECHARGEMENT AUTOMATIQUE ?
//FilmeName = AUTODownloading.jsw
import { mediaManager } from "wix-media-backend";
import wixData from 'wix-data';
export function savePDF(base64, fileName) {
return new Promise((resolve, reject) => {
uploadPDF(base64, fileName)
.then((file) => {
getDownloadUrl(file.fileUrl)
.then((downloadUrl) => {
resolve(downloadUrl);
})
.catch((error) => {
reject(error);
});
})
.catch((error) => {
reject(error);
});
});
}
export function uploadPDF(base64, fileName) {
// create Buffer from Base64
const buffer = Buffer.from(base64, 'base64');
return mediaManager.upload(
"/UserUploads",
buffer,
fileName + ".pdf", {
"mediaOptions": {
"mimeType": "application/pdf",
"mediaType": "document"
},
"metadataOptions": {
"isPrivate": false,
"isVisitorUpload": false,
"context": {
"someKey1": "someValue1",
"someKey2": "someValue2"
}
}
}
);
}
export async function getDownloadUrl(fileUrl) {
const myFileDownloadUrl = await mediaManager.getDownloadUrl(fileUrl, 10);
return myFileDownloadUrl;
}
2- TELECHARGER PDF-LIB VIA NPM
A-- CREER LE DOCUMENT DANS UN SEUL BOUTON nommé BOUTON4 DANS LE FRONTEND
import { savePDF } from "backend/AUTODownloading.jsw";
import wixData from 'wix-data';
import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';
$w('#button4').onClick(async()=>{
const pdfDoc = await PDFDocument.create();
const fileName = "MY DOCUMENT " + $w('#myTexte').text;
const PoliceFont = await pdfDoc.embedFont(StandardFonts.Helvetica);//Ma police préférée Helvetica
const page = pdfDoc.addPage([600, 800]);
const { width, height } = page.getSize();
Je tiens à préciser que je n’est pas fermé le bouton, le code n’est pas finit. TOUJOUR A L’INTERIEUR DU BOUTON, Voici le code de génération d’un Texte.
// A- Creer Texte
const fontSize9 = 15;
page.drawText($w('#myText2').text;, {
x: 400,
y: height - 21 * fontSize,
size: fontSize9,
font: PoliceFont, //HELVETICA MA POLICE PREFERE
color: rgb(0, 0, 0), //NOIR
});
B- TOUJOURS A L’INTERIEUR DU MEME BOUTON, CODE POUR GENERER UN TABLEAU
const header = ['Prestations', 'Détails', "Achat (FCFA)", "Vente (FCFA)"]//CREER ENTETE DE TABLEAU (personnaliser le votre)
// Récupération des données
const results = await wixData
.query("collectionName")
.eq("fields1", $w('#text80').text)
.eq('field2', "réponse devis")
.find();
const tableDatas = results.items.map(item => ({
prestation: item.Prestation || "N/A",
detail: item.Détails || "N/A",
achat: item.Achat || "N/A",
vente: item.Vente || "N/A",
}));
//LES VALEURS N/A SONT LES VALEURS PAR DEFAUT (PAR DEFAUT EST LA MEILLEUR OPTION POUR RENDRE LA COLONNE RESPONSIVE)
const tableData = [header, ...tableDatas.map(data => [data.prestation, data.detail, data.achat, data.vente])] // FORMATER LES RESULTATS EN TABLEAU FORMAT WIX VALIDE
// Paramètres pour dessiner le tableau
const startX = 30;
let startY = 590; // Position de départ dynamique
const columnWidths = [120, 220, 100, 100]; // Largeur des colonnes
const defaultRowHeight = 40; // Hauteur minimale d'une ligne
// Fonction pour découper les textes trop longs en plusieurs lignes pour adapter les lignes en fonction du tableau
function splitTextToLines(text, columnWidth, fontSize, font) {
const words = text.split(' ');
let lines = [];
let currentLine = '';
words.forEach(word => {
const testLine = currentLine ? `${currentLine} ${word}` : word;
const testWidth = font.widthOfTextAtSize(testLine, fontSize);
if (testWidth <= columnWidth) {
currentLine = testLine;
} else {
lines.push(currentLine);
currentLine = word;
}
});
if (currentLine) lines.push(currentLine); // Ajouter la dernière ligne
return lines;
}
// Dessiner le tableau avec bordures et texte inclus
tableData.forEach((row, rowIndex) => {
let maxCellHeight = defaultRowHeight;
// Calculer la hauteur dynamique de la ligne en fonction du texte le plus long
const cellHeights = row.map((cell, colIndex) => {
const lines = splitTextToLines(cell, columnWidths[colIndex], 15, timesRomanFont);
return lines.length * 18; // 14 est la hauteur approximative d'une ligne (taille + espacement)
});
maxCellHeight = Math.max(...cellHeights);
// Dessiner les cellules et le texte
row.forEach((cell, colIndex) => {
const x = startX + columnWidths.slice(0, colIndex).reduce((a, b) => a + b, 0);
const y = startY;
// Dessiner la bordure de la cellule
page.drawRectangle({
x: x,
y: y - maxCellHeight, // Ajustement pour inclure toute la hauteur de la cellule
width: columnWidths[colIndex],
height: maxCellHeight,
borderWidth: 1,
borderColor: rgb(0, 0, 0), // Couleur noire pour les bordures
});
// Diviser le texte en lignes
const fontSize = rowIndex === 0 ? 16 : 15; // Taille pour l'en-tête ou les lignes
const lines = splitTextToLines(cell, columnWidths[colIndex], fontSize, timesRomanFont);
// Dessiner chaque ligne de texte
lines.forEach((line, lineIndex) => {
const textX = x + 5; // Marge à gauche pour le texte
const textY = y - 14 - lineIndex * (fontSize + 2); // Ajustement vertical pour chaque ligne
page.drawText(line, {
x: textX,
y: textY,
size: fontSize,
font: timesRomanFont,
color: rowIndex === 0 ? rgb(0, 0.53, 0.71) : rgb(0, 0, 0), // Couleur en-tête et lignes
});
});
});
// Réduire la position Y pour la prochaine ligne
startY -= maxCellHeight;
});
C- GENERER DEUX (2) IMAGES (Image et Image1).
let baseUrl;
let cleanedUrl
let cleanedUrl1
let baseUrl1;
let image;
let image1;
let imageBytes;
let imageBytes1;
let extension;
let extension1;
const results1 = await wixData
.query("CollectionName")
.eq("_id", MyId)
.find();
//console.log(results1.items[0].logo)
const wixImageUrl = results1.items[0].logo; // Votre URL Wix
const wixImageUrl1 = results1.items[0].image//URL de la seconde Image
if (wixImageUrl && wixImageUrl.startsWith("wix:image://v1/")) {
baseUrl = wixImageUrl.replace('wix:image://v1/', 'https://static.wixstatic.com/media/');
cleanedUrl = baseUrl.replace(/(\.(jpg|jpeg|png|webp|avif|gif))[^\/]*.*/, '$1');
console.log(cleanedUrl)
}
else
{
cleanedUrl = wixImageUrl
}
if (wixImageUrl1 && wixImageUrl1.startsWith("wix:image://v1/")) {
baseUrl1 = wixImageUrl1.replace('wix:image://v1/', 'https://static.wixstatic.com/media/');
cleanedUrl1 = baseUrl1.replace(/(\.(jpg|jpeg|png|webp|avif|gif))[^\/]*.*/, '$1');
console.log(cleanedUrl1)
}
else
{
cleanedUrl1 = wixImageUrl1
}
extension = cleanedUrl.split('.').pop().toLowerCase();
extension1 = cleanedUrl1.split('.').pop().toLowerCase();
//IL SE PEUT QUE l'URL NE SOIT PAS COMPATIBLE DONC FORMATER L'URL EN UNE EXTENSION WIX COMPATIBLE
imageBytes = await fetch(cleanedUrl).then((res) => res.arrayBuffer());
if (['png'].includes(extension)) {
image = await pdfDoc.embedPng(imageBytes);
} else if (['jpg', 'jpeg'].includes(extension)) {
image = await pdfDoc.embedJpg(imageBytes);
} else {
$w('#box67').show()
}
imageBytes1 = await fetch(cleanedUrl1).then((res) => res.arrayBuffer());
if (['png'].includes(extension1)) {
image1 = await pdfDoc.embedPng(imageBytes1);
} else if (['jpg', 'jpeg'].includes(extension1)) {
image1 = await pdfDoc.embedJpg(imageBytes1);
} else {
console.error("une erreur s'est produite soit parce que votre URL d'image est undefined (recherche query à échoué), soit à cause de l'extension de votre image verifiez s'il est jpg, jpeg ou png")
}
// Taille et position de l'image
const imageWidth = 200; // Largeur de l'image
const imageHeight = 100; // Hauteur de l'image
const imageX = 33; // Position X de l'image
const imageY = 750; // Position Y de l'image
// Dessiner l'image
page.drawImage(image, {
x: imageX,
y: imageY,
width: imageWidth,
height: imageHeight,
});
const imageWidth1 = 200; // Largeur de l'image
const imageHeight1 = 100; // Hauteur de l'image
const imageX1 = 300; // Position X de l'image
const imageY1 = 200; // Position Y de l'image
// Dessiner la 2e l'image
page.drawImage(image1, {
x: imageX1,
y: imageY1,
width: imageWidth1,
height: imageHeight1,
});
ETAPE FINALE TOUJOURS DANS LE MEME BOUTON DECLENCHER LE TELECHARGEMENT ET GENERER L’URL.
// Generer le PDF
// Sauvegarder et télécharger le PDF
const pdfDataUri = await pdfDoc.saveAsBase64({ dataUri: true });
const dataUriPrefix = 'data:application/pdf;base64,';
const base64 = pdfDataUri.slice(dataUriPrefix.length);
savePDF(base64, fileName)
.then(downloadUrl => {
console.log(downloadUrl);
wixLocation.to(downloadUrl); // Fonctionne uniquement en ligne
})
.catch((error) => {
console.error("Error while saving the PDF: ", error);
});
})//IL FAUT FERMER LE BOUTON
NORMALEMENT LE CODE EST TERMINE ET CELA FONCTIONNE CHEZ MOI
IMPORTANT : cet URL Généré n’est disponible que 1 heure, si vous voulez enregistrer le pdf definitivement dans votre collection alors vous suivez le tuto :