Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Génération de PDF en full client side #45

Open
ldubost opened this issue Nov 18, 2022 · 2 comments
Open

Génération de PDF en full client side #45

ldubost opened this issue Nov 18, 2022 · 2 comments

Comments

@ldubost
Copy link

ldubost commented Nov 18, 2022

Actuellement signaturepdf envoie les informations de signature au serveur et stocke le pdf sur le serveur pour ensuite génerer le PDF final avec du code serveur.

Dans le cadre d'une intégration de l'UI de signaturepdf dans CryptPad (une solution de drive chiffré de bout en bout permettant entre autre le stockage de PDF et le partage collaboratif), il est nécessaire de faire la génération de PDF client side.

L'objectif est d'ouvrir le PDF, d'y intégrer les signatures et annotations et de resauver le PDF

@ldubost
Copy link
Author

ldubost commented Nov 18, 2022

Ceci est réalisé avec pdf-lib.js. Le code est dans l'intégration CryptPad mais pourrait être reversé à signaturepdf:
https://github.com/xwiki-labs/cryptpad/tree/signpdf/www/sign

Le code est au début de prepareDoc ici:

https://github.com/xwiki-labs/cryptpad/blob/signpdf/www/sign/inner.js#L928
(La suite de la fonction concerne de la signature digitale qui est une autre modification).
Cela utilise pdf-lib pour insérer les élements (il est possible que tout les types d'insertions ne soit pas supportés actuellement)

   async function prepareDoc(pdfData, items) {
       var buffer = await pdfData.arrayBuffer();
       var pdfDoc = await pdflib.PDFDocument.load(buffer);
   var pageHeight = 1000;
       pdfDoc.setTitle(pdfTitle);
       items.forEach(async (item) => {
         var img = await pdfDoc.embedPng(item.data);
         var page = pdfDoc.getPages()[item.index]
         page.drawImage(img, { x: 0, y: 0, width: page.getWidth(), height: page.getHeight()})
         pageHeight = page.getHeight();
       });
       const modifiedPdfBytes = await pdfDoc.save({ useObjectStreams: false });

@ldubost
Copy link
Author

ldubost commented Nov 18, 2022

Il est à noter que comme cela fait le rendu des annotations avec l'API canvas, cela pose un problème de qualité des images insérées.. Ce problème a été résolu en faisant un resize du canvas uniquement pour la génération (afin de moins modifier le code):

// temporarey resize of canvas to improve rendering quality
resizeCanvas(4);
canvasEditions.forEach(function(canvasEdition, index) {
items.push({
data: canvasEdition.toDataURL(), index: index,
name: index + '.png', type: 'image/png'
});
})
// restore previous canvas size
resizeCanvas(0.25);
prepareDoc(pdfData, items).then(pdfBytes => {
var blob = new Blob([pdfBytes.buffer], { type: "application/pdf" })
blob.name = pdfTitle.replace(".pdf", "-signed.pdf");
APP.FM.handleFile(blob);
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant