みかづきブログ・カスタム

基本的にはちょちょいのほいです。

Google Chromeの印刷機能でWebサイトをA4のPDFに変換する際、1ページに表示できるDOMの大きさ何pxになるのか調査する 📄

はじめに

最近、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-beforepage-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ができることがわかりました。