はじめに
最近、HTMLをPDFに変換したいと思うことが増えてきまして、いろいろ調査していたのですが、そんな中、Google Chromeの印刷機能に目をつけました。
html2pdf.jsなどのライブラリを使わずとも、Goolge Chromeで「ファイル」 > 「印刷」を選び、送信先を「PDFに保存」にして保存すれば、HTMLを簡単にPDF化することができるからです。
HTMLと出力したいPDFで見た目が異なる場合は、ライブラリを使って変換しようと思いますが、HTMLの見た目をそのままにPDF化したい場合は、これで良いような気がします。
ただ、デフォルトに任せると、コンテンツをぶった斬って改ページを挟んでくるので、ページを分けて綺麗に印刷したい場合は自前で改ページを挟む必要があります。
そこで今回は、Google Chromeの印刷機能を使ってHTMLファイルをA4のPDFとして保存する場合、何px毎に改ページを入れれば綺麗にページが分かれるのかを調査しようと思います。
結論
先に結論を記載すると、デフォルトの設定で、
- px指定: 718px × 1046px
- mm指定: 190mm × 277mm
の大きさのDOMが、A4のPDF1ページあたりの表示領域になりました。
なので、1046px毎か、277mm毎に改ページを挟むと、PDF化した際に綺麗に分割できます。
ただし、印刷設定の余白や倍率に依存すると思われます。
px指定
.page { box-sizing: border-box; position: relative; margin: 0; padding: 0; width: 718px; height: 1046px; background: red; overflow: hidden; page-break-after: always; }
mm指定
.page { box-sizing: border-box; position: relative; margin: 0; padding: 0; width: 190mm; height: 277mm; background: red; overflow: hidden; page-break-after: always; }
調査 ❶ グリッドを表示して計測
まずは、10px × 10pxのグリッドが表示されているHTMLを用意し、Google Chromeで印刷プレビューを表示した際、1ページにどこまでが表示されるか数えてみました。
ソースコード
<html> <head> <meta charset="UTF-8" /> <title>print</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } ul { display: flex; flex-wrap: wrap; } li { display: flex; align-items: center; justify-content: center; border: solid .1px; width: 10px; height: 10px; font-size: 10px; list-style: none; } </style> </head> <body> <script> const ul = document.createElement('ul'); for (let i = 0; i < 9999; ++i) { const li = document.createElement('li'); const arr = [...String(i)]; li.innerText = arr[arr.length - 1]; ul.appendChild(li); } document.body.appendChild(ul); </script> </body> </html>
結果
ページの余白を除くと、720px × 1040px 表示されていました。
なので、試しに720px × 1040pxを赤く塗りつぶしてみたのですが、
微妙にはみ出ました。
実はCSSには改ページを指定する、 page-break-before 、page-break-after というプロパティがあるので、これを使って解決することもできます。
developer.mozilla.org
developer.mozilla.org
.page { position: relative; width: 720px; height: 1040px; overflow: hidden; page-break-after: always; // 改ページ }
という具合に、A4のエリアの直後に改ページを挟めば微妙なはみ出しをキャンセルできます。
一瞬、これでいいかとおもったのですが、CSSがmm指定できつことを思い出し、そもそもmmで指定するという手法を思いつきました。
調査 ❷ DOMの大きさをmmで指定して計測
CSSはmmで指定できることを思い出し、余白を1cmと定義してA4のサイズをmmで指定してみました。
ソースコード
<html> <head> <meta charset="UTF-8" /> <title>print</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } .page { position: relative; border: solid .1px; width: 190mm; height: 277mm; background: red; overflow: hidden; } </style> </head> <body> <div class="page"></div> <div class="page"></div> <div class="page"></div> </body> </html>
結果
するとなんということでしょう。ぴったり改ページされました。
このときのDOMの大きさは718.11px × 1046.92pxです(ディベロッパーツールで計測)。
なので、px指定の際は、小数点を切り捨てて、718px × 1046pxで改ページしていくと良いでしょう。
10px四方のグリッドを使って、導き出した 720px × 1040px という値は割と正確だったことがわかります。
結論
前述の通り、
- px指定: 718px × 1046px
- mm指定: 190mm × 277mm
の大きさのDOMがA4のPDFに変換した際の1ページに表示できる量とわかったので、
.page { position: relative; width: 720px; /* or 190mm; */ height: 1040px; /* or 277mm; */ overflow: hidden; page-break-after: always; }
で、区切りながらデザインを再現していけば、PDF変換時に綺麗に改ページできるHTMLができることがわかりました。