web-dev-qa-db-fra.com

jsPDF fromHTML images cause le pdf pour être vide

J'essaie de générer un pdf à partir du contenu Tinymce, auquel j'accède avec AngularJS. Pour cela, j'utilise le plugin from_html dans jspdf.

Commencez par les parties de code pertinentes.

La fonction et l'index pertinents.ejs jspdf inclut

//relevant function
var specialElementHandlers = {
  '#bypassme': function(element, renderer) {
    return true;
   }
};

var margin = {
  top: 0,
  left: 0,
  right: 0,
  bottom: 0
};

var tinymceToJSPDFHTML = document.createElement("body");
tinymceToJSPDFHTML.innerHTML = $scope.selectedItem.content;
      
var doc = new jsPDF();
doc.fromHTML(tinymceToJSPDFHTML, 0, 0, {
  'width': 100, // max width of content on PDF
  'elementHandlers': specialElementHandlers
}, function(a) { console.log(a); }, margin);

doc.save('project.pdf');
<script src="/libs/jsPDF-1.2.61/dist/jspdf.debug.js"></script>
<script src="/libs/jsPDF-1.2.61/plugins/from_html.js"></script>

Le code que je veux analyser de html en pdf ressemble un peu à ceci, ce n'est qu'un exemple.

<strong>
        <img data-mce-src="file/3605842ba1b6e8ac5417622bf1c43b5b" src="file/3605842ba1b6e8ac5417622bf1c43b5b"></img>

        aaaaa

    </strong>

</p>
<p data-mce-style="text-align: center;" style="text-align: center;">

    <strong>

        sasasa

    </strong>

</p>
<p data-mce-style="text-align: right;" style="text-align: right;">

    <em>
        <strong>

            asasas

        </strong>
    </em>

</p>
<p data-mce-style="text-align: left;" style="text-align: left;">

    <span data-mce-style="text-decoration: underline;" style="text-decoration: underline;">
        <em>
            <strong>

                asasasa

            </strong>
        </em>
    </span>

</p>
<ul>

    <li data-mce-style="text-align: left;" style="text-align: left;">
        <span data-mce-style="text-decoration: underline;" style="text-decoration: underline;">
            <em>
                <strong>

                    bas

                </strong>
            </em>
        </span>
    </li>

</ul>

Si j'analyse ce code sans l'image, cela fonctionne au moins pour une partie, certaines manipulations de texte comme l'italique ne sont pas vraiment reconnues et les listes ne sont pas reconnues par l'analyseur.

Cependant, si j'analyse une image (toutes les images que j'ai essayées sont des images .jpg standard à partir par exemple du dossier d'images Windows et je les ai redimensionnées au cas où elles ne rentreraient pas sur le site pdf et c'est ce qui cause le site vide.

J'ai débogué le code jspdf jusqu'à présent, un peu pouvait voir qu'il passait par les méthodes de chargement de l'image. Des requêtes get sont également envoyées à partir de ce code, comme indiqué dans le débogueur de navigateur (cette routine est également écrite par moi). Mais le site reste toujours vide. le même img src est parfaitement affiché dans l'éditeur.

Comment puis-je résoudre ce problème, afin que l'image soit affichée du tout et que le pdf ne soit pas vide.

12
FroZenViper

J'ai trouvé la solution à mon problème. Lorsque vous utilisez le plugin fromHTML, il est important d'enregistrer le pdf dans le rappel, sinon le rendu ne sera pas effectué au moment où il enregistre le document.

doc.fromHTML(tinymceToJSPDFHTML, 0, 0, {
    'width': 100, // max width of content on PDF
    'elementHandlers': specialElementHandlers
},
function(bla){doc.save('saveInCallback.pdf');},
margin);
53
FroZenViper

Merci @FroZenViper de m'avoir indiqué la solution de rappel alors je peux la résoudre en utilisant setTimeout :) - jsPDF Version 1.5.3

doc.fromHTML(yourTargetHTML, 0, 0, {
    // options
},

setTimeout(function () {
    doc.save(`fileName`);
}, 0);  
0
Anh Hoang

Pour Angular 8

Si vous utilisez des images dans fromHTML, vous devez les charger de manière asynchrone. Vous devez donc utiliser le paramètre de rappel. La fonction de rappel est appelée lorsque fromHTML dans jsPDF a chargé toutes les images et généré le document.

https://github.com/MrRio/jsPDF/issues/788

public Download() {
    const doc = new jsPDF();

    const specialElementHandlers = {
      '#editor': function (element, renderer) {
        return true;
      }
    };

    const content = this.downloadPanelContent.nativeElement;

    doc.fromHTML(content.innerHTML, 0, 0, {
      'width': 100, // max width of content on PDF
      'elementHandlers': specialElementHandlers
    },
      function (bla) { doc.save('saveInCallback.pdf'); },
      0);
  }

[~ # ~] html [~ # ~]

<div id="downloadPanel" #downloadPanelContent>
    <div class="row" style="display: none;">
        <img src="../../../../assets/img/image.png" />
        <div class="container">
            <label class="text-black-54">Backup codes</label><br>
            <ng-container *ngTemplateOutlet="backupCodes"></ng-container>

        </div>
    </div>
</div>
0
San Jaisy