jsTree で作成したツリー図をPDFにする

jsTree jsTree で作成したツリー図をPDFで出力するのは、jsTreeがHTML表示としたものを
画像データにして、PDF作成のツールで出力ということをしなければなりません。
PDF作成でテンプレートによる作成というのは無理があります。=できない。

【大きな流れ】
jsTree → HTML表示
→ ツリー表示エリアを canvas データに変換、html2canvas で変換します。
canvas データを jsPDF に渡します。
jsPDF で、canvas データをイメージデータとして作成するPDFオブジェクトに
  追加します。
→ jsPDF でダウンロード出力、プレビュー表示。

という流れになります。
jsTreeはツリー図を ul,li 要素で書いているので、jsPDF で HTML変換による
PDF作成だとjsTreeが指定する CSS を読み込まなくてはならず、
jsPDF のサンプルを見るととてもつらいです。
よって、html2canvas を介在する上に書いた流れになります。

ツリー図の表示があって、プレビューのボタンを押すと右横にPDFプレビューが表示される
ものを作成します。

サンプル
f:id:posturan:20181006210522j:plain


HTML は、ツリー表示の div 要素と button があります。

<div id="tree" class="demo"></div>

<button id="preview" type="button">preview PDF</button>

jsTree でのツリー表示の処理は、今回割愛します。
jsTree の他に必要なJS
html2canvas
jsPDF

日本語タイトルを入れたいので jsPDF 日本語の文字が使用できるものをダウンロードして
使います。

https://qiita.com/JunichiWatanuki/items/07bcb842e5532068fd62

https://github.com/JunichiWatanuki/jsPDFjp


ボタンを押して、プレビュー表示させる処理を以下のとおりです。
ツリー図を画像データとして保存する処理は、
http://oboe2uran.hatenablog.com/entry/2018/10/06/162209html2canvas を使って表示HTMLを画像変換してダウンロード - Oboe吹きプログラマの黙示録
のように、PNG画像でしたが、PDF出力で今回は、JPEGです。
そうしないと、作成したPDFを開いた時に
「ページの処理中にエラーが発生しました。
 このドキュメント(110)の読み込み中に問題が発生しました。」

ということになります。

html2canvas version 0.4.1 を使用する場合、

$("#preview").click(function(){
   html2canvas($("#tree"), {
      onrendered : function(canvas){
         var pdf = new jsPDF('p', 'pt', 'a4', false);
         pdf.setFontSize(20);
         pdf.text(10, 50, utf16_to_hexcode('ツリーサンプル'));
         // Tree図 → 横幅を取得して指定
         var width = pdf.internal.pageSize.width * 0.90;
         var x = (pdf.internal.pageSize.width - width) / 2;
         pdf.addImage(canvas, 'JPEG', x, 70, width, 0);

         var iframe = document.createElement('iframe');
         iframe.setAttribute('style','position:absolute;right:0; top:0; bottom:0; height:100%; width:500px');
         document.body.appendChild(iframe);
         iframe.src = pdf.output('datauristring');
      }
   });
});

html2canvas version 1.0.0 alpha 12 を使用する場合、

$("#preview").click(function(){
   html2canvas(document.querySelector("#tree")).then(function(canvas) {
      var pdf = new jsPDF('p', 'pt', 'a4', false);
      pdf.setFontSize(20);
      pdf.text(10, 50, utf16_to_hexcode('ツリーサンプル'));
      // Tree図 → 横幅を取得して指定
      var width = pdf.internal.pageSize.width * 0.90;
      var x = (pdf.internal.pageSize.width - width) / 2;
      pdf.addImage(canvas, 'JPEG', x, 70, width, 0);

      var iframe = document.createElement('iframe');
      iframe.setAttribute('style','position:absolute;right:0; top:0; bottom:0; height:100%; width:500px');
      document.body.appendChild(iframe);
      iframe.src = pdf.output('datauristring');
   });
});

プレビュー表示の為に、iframe で差し込むのです。
最近は、Window open させるということは、初回、ブラウザのポップアップブロックが
あるので iframe の方がよいかもしれません。

プレビューではなく、ボタンクリックでダウンロードの方法は、
jsPDF の save( ダウンロードファイル名 ) です。

html2canvas version 0.4.1 を使用する場合、

$(function(){
   $("#download").click(function(){
      html2canvas($("#tree"), {
         onrendered : function(canvas){
            var pdf = new jsPDF('p', 'pt', 'a4', false);
            pdf.setFontSize(20);
            pdf.text(10, 50, utf16_to_hexcode('ツリーサンプル'));
            // Tree図 → 横幅を取得して指定
            var width = pdf.internal.pageSize.width * 0.90;
            var x = (pdf.internal.pageSize.width - width) / 2;
            pdf.addImage(canvas, 'JPEG', x, 70, width, 0);
            pdf.save('テスト.pdf');
         }
      });
   });
});

html2canvas version 1.0.0 alpha 12 を使用する場合、

$(function(){
   $("#download").click(function(){
      html2canvas(document.querySelector("#tree")).then(function(canvas){
         var pdf = new jsPDF('p', 'pt', 'a4', false);
         pdf.setFontSize(20);
         pdf.text(10, 50, utf16_to_hexcode('ツリーサンプル'));
         // Tree図 → 横幅を取得して指定
         var width = pdf.internal.pageSize.width * 0.90;
         var x = (pdf.internal.pageSize.width - width) / 2;
         pdf.addImage(canvas, 'JPEG', x, 70, width, 0);
         pdf.save('テスト.pdf');
      });
   });
});