web-dev-qa-db-fra.com

Comment ajouter un en-tête et un pied de page à tous PDF dans jsPDF avec la méthode addHTML

Je convertis le HTML en pdf en utilisant jspdf. J'utilise la méthode addHTML pour convertir la page html en pdf

  var htmlSource = $('#body')[0];

 function crate (){
   var pdf = new jsPDF('p','px');

  pdf.addHTML(
    htmlSource,10, 10, {pagesplit: true, margin: {top: 10, right: 10,bottom: 10, left: 10, useFor: 'page'}},
    function(dispose){
       pdf.save('datapdf.pdf');
    }
  );

}

et je veux ajouter un en-tête et un pied de page sur toutes les pages, soit laisser un espace vide pour l'en-tête et le pied de page. mais en utilisant l'option, je ne peux laisser qu'un espace d'en-tête sur la première page du pdf.

8
Vijay ijardar

Une approche pourrait être de recharger le rendu de page html dans le navigateur client afin de l'afficher exactement comme vous voulez qu'il soit imprimé dans le pdf (puis utilisez simplement la fonction que vous venez de créer ci-dessus), donc dans un format composé d'une série d'éléments verticaux comme h, p1, f, h, p2, f, h, p3, f, etc. (où h = en-tête, p1 ... pn sont les pages et f = pied de page) au lieu d'une série contenant juste h, p1, p2, p3, ..., pn, f (comme c'est le cas actuellement).

Cela signifie que vous pourriez avoir accès au code source de la page html (il ne s'agit donc pas seulement d'une page provenant d'Internet), car s'il s'agit d'une ressource externe, les dimensions de l'en-tête et du pied de page sont peut-être construites de manière à remplir également les espaces en relation avec d'autres éléments de la page (et je pense ici aux technologies flex/appliquées verticalement/ou grille dans le rendu de la page web).

Un autre aspect, si vous allez faire cette méthode, est que la division du contenu n'est peut-être pas toujours possible (et je ne pense pas ici à détruire les tableaux ou autres éléments multi-pages visibles uniquement lors de l'utilisation du défilement), mais aussi le rendu pourrait prendre en compte l'affichage vertical de la page (opposé au mode paysage comme sur le bureau) afin de redessiner les éléments de la page. Cela peut parfois rendre le pied de page et l'en-tête plus volumineux, donc je ne sais pas pourquoi vous voudriez dépenser des parties de la précieuse succession de la dernière page imprimée en faisant cela. (La solution serait peut-être d'ouvrir une nouvelle fenêtre, rendant ainsi la page au nouveau format, peut-être même derrière la page existante, puis lancer la confirmation d'impression/ou télécharger le fichier/avant de fermer cette page respective.)

L'autre façon serait de changer la fonction afin de travailler avec un rendu virtuel de la page (pas de page affichée) - en effectuant les changements dans votre fonction et non dans le rendu lui-même.

Cependant, cette deuxième approche présente également quelques défis. Initialement, lors de la déclaration de la variable 'var pdf', celle-ci est créée comme un conteneur de stockage de données unique, puis vous lui affectez le constructeur (var pdf = new jsPDF ('p', 'px');). Cependant, à l'étape suivante, vous y ajoutez un contenu HTML (pdf.addHTML) qui est un élément unique, pas une entité multiple. Vous devez modifier la fonction afin de lui faire imprimer un tableau où vous calculez d'abord les éléments en fonction des dimensions des pages rendues.

Peut-être que le code deviendrait quelque chose comme:

var fullpage, onepage, headd, foott, edges, contentt, he, fo, c, pages;
fullpage = document.body.scrollHeight; // height of all html page (not just the visible content)
onepage = 1200; // height of each single page printed in pdf - in pixels
headd = document.getElementById("header");
he =  headd.offsetHeight;
foott = document.getElementById("footer"); 
fo = foott.offsetHeight;
edges = he + fo;
contentt = onepage - edges; // height of content of each page printed

pages = [0];  // start to work with first page which obviously is there
fullpage -= onepage; // remove height of first printed page (containg both header and footer)
    pdf.addHTML( // create first page of pdf file
    htmlSource, 10, 10, {pagesplit: true, margin: {top: 10, right:
      10, bottom: 10, left: 10, useFor: 'page'}},
    function(dispose){
       pdf.save('datapdf.pdf');
    });   // this is your code

var i = 0; // start the counter

 while(fullpage > 0) { // start adding header + footer to remaining pages
  fullpage += edges; // if there is still a page 2...n we add edges, etc.
  i++;
  pages[i] = content(onepage) { // here you must insert the code for harvesting the n-st page content from your source code
    return htmlSource;
  }
     function addPages(i) {
         var eachpdf = "datapdf" + i + ".pdf";
          // <= here goes again your code, with a small change
          // pagesplit: false - instead of true, in order to speed the process, and also
          // pdf.save(eachpdf); - instead of pdf.save('datapdf.pdf');              
     }
 }

Ce que vous essayez de réaliser est de créer une série he, p1, fo, he, p2, fo, he, p3, fo, etc (où he = header, p1 ... pn sont les pages/nommé datapdfi ci-dessus/et fo = pied de page) au lieu d'une série contenant uniquement h, p1, p2, p3, ..., pn, f.

Cela signifie que vous devez construire un tableau contenant des pages pdf séparées comme expliqué dans le code ci-dessus.

Je n'ai pas encore créé pour vous le code pour séparer le contenu de chaque page (qui pourrait retourner le htmlSource) mais cela est en stricte dépendance avec la façon dont vos pages sont rendues.

5
1copyright

Il existe une méthode suggérée qui utilise les éléments HTML <header> et <footer> à cet effet, par exemple:

<footer>
    <div style='text-align:center;'>Page <span class="pageCounter"></span>/<span class="totalPages"></span></div>
</footer>

Voir https://github.com/MrRio/jsPDF/pull/26

4
Sajeetharan