WebアプリケーションからPDFを作成する方法
公開: 2022-03-10多くのWebアプリケーションには、ユーザーがPDF形式で何かをダウンロードできるようにする必要があります。 アプリケーション(eコマースストアなど)の場合、これらのPDFは動的データを使用して作成し、ユーザーがすぐに利用できるようにする必要があります。
この記事では、Webアプリケーションからその場で直接PDFを生成する方法を探ります。 これはツールの包括的なリストではありませんが、代わりにさまざまなアプローチを示すことを目指しています。 お気に入りのツールや独自の経験を共有したい場合は、以下のコメントに追加してください。
HTMLとCSSから始める
私たちのWebアプリケーションは、PDFに追加される情報を使用してHTMLドキュメントをすでに作成している可能性があります。 請求書の場合、ユーザーは情報をオンラインで表示し、クリックして記録用のPDFをダウンロードできる場合があります。 パッキングスリップを作成している可能性があります。 繰り返しになりますが、情報はすでにシステム内に保持されています。 ダウンロードと印刷のために、それを適切な方法でフォーマットする必要があります。 したがって、開始するのに適した場所は、そのHTMLとCSSを使用してPDFバージョンを生成できるかどうかを検討することです。
CSSには、印刷用のCSSを扱う仕様があり、これはPagedMediaモジュールです。 この仕様の概要は、私の記事「CSSを使用した印刷用の設計」にあります。CSSは、多くの書籍出版社がすべての印刷出力に使用しています。 ですから、CSS自体に印刷物の仕様があるので、きっと使えるはずでしょうか?
ユーザーがPDFを生成する最も簡単な方法は、ブラウザーを使用することです。 プリンターではなくPDFに印刷することを選択すると、PDFが生成されます。 悲しいことに、このPDFは通常完全に満足のいくものではありません! まず、Webページから何かを印刷するときに自動的に追加されるヘッダーとフッターがあります。 また、印刷スタイルシートに従ってフォーマットされます—あると仮定します。
ここで遭遇する問題は、ブラウザーでの断片化仕様のサポートが不十分なことです。 これは、ページのコンテンツが異常な方法で壊れていることを意味する場合があります。 「CSSフラグメンテーションでボックスを壊す」という記事を調べたときに発見したように、フラグメンテーションのサポートにはパッチがあります。 これは、ページの最後のアイテムとしてヘッダーが残されているなど、コンテンツの最適ではない破損を防ぐことができない可能性があることを意味します。
さらに、ページの余白ボックスのコンテンツを制御することはできません。たとえば、各ページに選択したヘッダーを追加したり、複雑な請求書のページ数を示すページ番号を付けたりすることはできません。 これらはPagedMedia仕様の一部ですが、どのブラウザにも実装されていません。
私の記事「2018年の印刷スタイルシートの状態に関するガイド」は、印刷スタイルシートを使用してブラウザーから直接印刷するためのブラウザーのサポートの種類に関しては、依然として正確です。
ブラウザレンダリングエンジンを使用した印刷
ブラウザの印刷メニューを経由せずに、ブラウザのレンダリングエンジンを使用してPDFに印刷する方法があり、ドキュメントを印刷したかのようにヘッダーとフッターが表示されます。 私のツイートに応えて最も人気のあるオプションは、wkhtmltopdfと、ヘッドレスChromeとPuppeteerを使用した印刷でした。
wkhtmltopdf
Twitterで何度も言及された解決策は、wkhtmltopdfと呼ばれるコマンドラインツールです。 このツールは、HTMLファイルまたは複数のファイルをスタイルシートとともに取得してPDFに変換します。 これは、WebKitレンダリングエンジンを使用して行われます。
wkhtmltopdfを使用します。 これはおそらくユーザーエラーでしたが、完全ではありませんが、実稼働アプリケーションには簡単に十分です。
— Paul Cardno(@pcardno)2019年2月15日
したがって、基本的に、このツールはブラウザからの印刷と同じことを行いますが、自動的に追加されたヘッダーとフッターは取得されません。 この良い面として、コンテンツの印刷スタイルシートが機能している場合は、このツールを使用してPDFに適切に出力する必要があるため、単純なレイアウトで非常に適切に印刷できます。
ただし、残念ながら、ブラウザレンダリングエンジンを使用して印刷しているため、ページメディア仕様とフラグメンテーションプロパティがサポートされていないという点で、Webブラウザから直接印刷する場合と同じ問題が発生します。 Paged Media仕様を使用してデフォルトで持っている不足している機能のいくつかを追加するために、wkhtmltopdfに渡すことができるいくつかのフラグがあります。 ただし、これには、優れたHTMLとCSSの作成に加えて追加の作業が必要です。
ヘッドレスクローム
もう1つの興味深い可能性は、ヘッドレスChromeとPuppeteerを使用してPDFに印刷することです。
パペッティア。 これはすごいです。
—アレックス・ラッセル(@slightlylate)2019年2月15日
ただし、ここでも、ページメディアとフラグメンテーションのブラウザサポートによって制限されています。 page.pdf()
関数に渡すことができるいくつかのオプションがあります。 wkhtmltopdfと同様に、これらは、ブラウザーのサポートがあればCSSから可能な機能の一部を追加します。
これらのソリューションの1つで必要なすべてが実行される可能性がありますが、何らかの戦いをしていることに気付いた場合は、現在のブラウザレンダリングエンジンで可能なことの限界に達している可能性があります。より良い解決策を探す必要があります。
ページメディア用のJavaScriptポリフィル
JavaScriptを使用してブラウザでページドメディア仕様を本質的に再現する試みがいくつかあります—本質的にページドメディアポリフィルを作成します。 これにより、Puppeteerを使用するときにPagedMediaがサポートされる可能性があります。 paged.jsとVivliostyleを見てください。
はい。 コース証明書などの単純なドキュメントの場合、@ページのサポートが最小限のChromeを使用できます。 それ以外の場合は、PrinceXMLまたはChromeのpaged.jsポリフィルを使用します。 これは、本にpaged.jsを使用したWIPの概念実証です:https://t.co/AZ9fO94PT2
— Electric Book Works(@electricbook)2019年2月15日
印刷ユーザーエージェントの使用
HTMLとCSSのソリューションを使い続けたい場合は、HTMLとCSSから印刷するために設計されたユーザーエージェント(UA)を探す必要があります。これには、ファイルからPDFを生成するためのAPIがあります。 これらのユーザーエージェントはPagedMedia仕様を実装し、CSSFragmentationプロパティをはるかによくサポートしています。 これにより、出力をより細かく制御できます。 主要な選択肢は次のとおりです。
- 王子
- アンテナハウス
- PDFReactor
印刷UAは、Webブラウザーと同じように、CSSを使用してドキュメントをフォーマットします。 CSSのブラウザサポートと同様に、これらのUAのドキュメントをチェックして、それらが何をサポートしているかを確認する必要があります。 たとえば、Prince(私が最もよく知っている)はFlexboxをサポートしていますが、執筆時点ではCSSグリッドレイアウトをサポートしていません。 使用しているツールにページを送信する場合、通常、これは印刷用の特定のスタイルシートを使用します。 通常の印刷スタイルシートと同様に、サイトで使用するCSSがすべてPDFバージョンに適しているとは限りません。
これらのツールのスタイルシートを作成することは、通常の印刷スタイルシートを作成することと非常によく似ており、おそらく異なるフォントサイズや色を使用して、何を表示または非表示にするかについて決定を下します。 その後、脚注やページ番号などを追加して、PagedMedia仕様の機能を利用できるようになります。
Webアプリケーションからこれらのツールを使用するという点では、サーバーにツールをインストールする必要があります(もちろん、そのためのライセンスを購入している必要があります)。 これらのツールの主な問題は、それらが高価であるということです。 とは言うものの、印刷されたドキュメントを簡単に作成できることを考えると、開発者の時間の節約になります。
DocRaptorと呼ばれるサービスを介して、APIを介して、ドキュメントごとの支払いに基づいてPrinceを使用することができます。 これは確かに、多くのアプリケーションを開始するのに適した場所であり、自分のアプリケーションをホストする方が費用対効果が高くなるように見え、切り替えの開発コストは最小限に抑えられます。
上記のツールほど包括的ではありませんが、必要な結果を十分に達成できる無料の代替手段は、WeasyPrintです。 Paged Mediaのすべてを完全に実装しているわけではありませんが、ブラウザエンジンよりも多くを実装しています。 間違いなく、試してみてください!
HTMLおよびCSSからの変換をサポートすると主張する他のツールには、HTML5、CSS3、およびJavaScriptをサポートすると大胆に主張するPDFCrowdが含まれます。 ただし、サポートされている内容の詳細と、ページングされたメディアの仕様のいずれかがサポートされているかどうかについては、詳細を見つけることができませんでした。 また、私のツイートへの回答で言及を受けたのはmPDFでした。
HTMLとCSSから離れる
HTMLやCSSの使用から離れ、ツールの特定の出力を作成する必要があるソリューションは他にもたくさんあります。 JavaScriptの候補は次のとおりです。
- jsPDF
- pdfmake
ヘッドレスブラウザ+ PDFへの保存は、かつては私の最初の選択肢でしたが、単一ページのドキュメント以外では常に標準以下の結果が得られました。 複数ページのレポートをhttps://t.co/3o8Ce23F1tに切り替えました。これにはかなりの労力がかかりましたが、最終的にはそれだけの価値があります。
— JimmyJoy(@jimle_uk)2019年2月15日
推奨事項
印刷用にコンテンツの完全に異なる表現を作成する必要があるJavaScriptベースのアプローチを除いて、これらのソリューションの多くの利点は、互換性があることです。 ソリューションがコマンドラインツールの呼び出しに基づいており、そのツールにHTML、CSS、場合によってはJavaScriptを渡すことに基づいている場合、ツールを切り替えるのはかなり簡単です。
この記事を書いている過程で、さまざまなツールを実行できるPythonラッパーも発見しました。 (ツール自体は既にインストールされている必要がありますが、これはサンプルドキュメントでさまざまなツールをテストするための良い方法である可能性があることに注意してください。)
Paged Mediaとフラグメンテーションのサポートのために、Prince、Antenna House、およびPDFReactorがトップになります。 市販品として、サポートも付いています。 予算があり、PDFに印刷するための複雑なページがあり、開発者の時間に制限がある場合は、PDF作成を適切に機能させるための最短ルートはこれらである可能性があります。
ただし、多くの場合、無料のツールが適しています。 要件が非常に単純な場合は、wkhtmltopdf、または基本的なヘッドレスChromeおよびPuppeteerソリューションでうまくいく可能性があります。 私の元のツイートに返信した多くの人にとっては確かにうまくいったようです。
ただし、必要な出力を取得するのに苦労している場合は、ブラウザの印刷の制限である可能性があり、間違っていることではないことに注意してください。 Paged Mediaのサポートを増やしたいが、商用製品を購入する立場にない場合は、WeasyPrintをご覧ください。
これが、WebアプリケーションからPDFを作成するために利用できるツールの便利なまとめであることを願っています。 他に何もないとしても、最初の選択がうまく機能していない場合は、さまざまな選択肢があることを示しています。
コメントにあなた自身の経験や提案を追加してください。これは私たちの多くが最終的に対処するものの1つであり、共有された個人的な経験は非常に役立ちます。
参考文献
この記事で説明したさまざまなリソースとツールのまとめ、およびWebアプリケーションからのPDFファイルを操作するためのその他の便利なリソース。
仕様
- ページングされたメディアモジュール
- 断片化
記事とリソース
- CSSを使用した印刷用のデザイン
- CSSフラグメンテーションでボックスを壊す
- 2018年の印刷スタイルシートの状態に関するガイド
- ヘッドレスChromeとPuppeteerの使用を開始する
- print-css.rocks
ツール
- wkhtmltopdf
- paged.js
- Vivliostyle
- 王子
- アンテナハウス
- PDFReactor
- DocRaptor
- WeasyPrint
- PDFCrowd
- mPDF
- jsPDF
- pdfmake
- サーバーの作成と公開