1. ホーム
  2. ジャバスクリプト

[解決済み】Javascriptでdiv内のHTMLからpdfを生成する。

2022-03-28 11:04:07

質問

以下のようなhtmlコードを持っています。

<!DOCTYPE html>
<html>
    <body>
        <p>don't print this to pdf</p>
        <div id="pdf">
            <p><font size="3" color="red">print this to pdf</font></p>
        </div>
    </body>
</html>

私がしたいことは、idが "pdf"のdivの中にあるものをpdfに印刷することだけです。 これは、JavaScriptを使って行わなければなりません。 そして、"pdf"の文書は、"foobar.pdf"のファイル名で自動的にダウンロードされる必要があります。

私はこれを行うためにjspdfを使っていますが、jspdfが持つ唯一の関数は"text"で、これは文字列値しか受け付けないのです。 テキストではなく、HTMLをjspdfに送信したいのですが。

どのように解決するのですか?

jsPDFはプラグインを使用することができます。 HTMLを印刷できるようにするためには、特定のプラグインを入れる必要があるため、以下のようにする必要があります。

  1. 次のページへ https://github.com/MrRio/jsPDF をクリックし、最新版をダウンロードしてください。
  2. 以下のスクリプトをプロジェクトに組み込んでください。
    • jspdf.js
    • jspdf.plugin.from_html.js
    • jspdf.plugin.split_text_to_size.js。
    • jspdf.plugin.standard_fonts_metrics.js。

特定の要素を無視したい場合は、その要素にIDを付ける必要があり、それをjsPDFの特別な要素ハンドラで無視することができます。したがって、あなたのHTMLはこのようになるはずです。

<!DOCTYPE html>
<html>
  <body>
    <p id="ignorePDF">don't print this to pdf</p>
    <div>
      <p><font size="3" color="red">print this to pdf</font></p>
    </div>
  </body>
</html>

そして、以下のJavaScriptのコードを使って、作成されたPDFをPopUpで開くのです。

var doc = new jsPDF();          
var elementHandler = {
  '#ignorePDF': function (element, renderer) {
    return true;
  }
};
var source = window.document.getElementsByTagName("body")[0];
doc.fromHTML(
    source,
    15,
    15,
    {
      'width': 180,'elementHandlers': elementHandler
    });

doc.output("dataurlnewwindow");

私の場合は、「print this to pdf」という行だけを含む、きれいに整頓されたPDFが作成されました。

なお、特殊な要素ハンドラは、現在のバージョンではIDしか扱わないので、その旨も GitHubイシュー . と記載されています。

ノードツリー内のすべての要素に対してマッチングが行われるため、できるだけ高速に動作させたいというのが私の願いでした。その場合、"要素IDのみマッチングされる"要素IDはjQueryスタイルの"#id"で行われますが、すべてのjQueryセレクタをサポートするということではありませんということでした。

したがって、「#ignorePDF」を「.ignorePDF」のようなクラスセレクタで置き換えても、私にはうまくいきませんでした。代わりに、無視したい各要素に同じハンドラを追加する必要があります。

var elementHandler = {
  '#ignoreElement': function (element, renderer) {
    return true;
  },
  '#anotherIdToBeIgnored': function (element, renderer) {
    return true;
  }
};

から また、'a'や'li'などのタグを選択することが可能であると記載されています。しかし、これはほとんどの使用例に対して、少し無制限すぎるかもしれません。

特殊な要素ハンドラをサポートしています。それらをjQueryスタイルで登録します。 IDセレクタで、IDまたはノード名を指定します。("#iAmID", "div", "span" など)。 他のタイプのセレクタ(クラス、オブ)はサポートされていません。 を含む)。

一つとても重要なことを付け加えると、スタイル情報(CSS)が全て失われてしまうことです。幸いにもjsPDFはh1, h2, h3などをきれいにフォーマットすることができ、私の目的には十分でした。さらに、それはテキストノード内のテキストのみを印刷します。つまり、textareasの値などは印刷されません。例

<body>
  <ul>
    <!-- This is printed as the element contains a textnode -->        
    <li>Print me!</li>
  </ul>
  <div>
    <!-- This is not printed because jsPDF doesn't deal with the value attribute -->
    <input type="textarea" value="Please print me, too!">
  </div>
</body>