Softex CelwareTech Blog
Google Apps Script2026-07-09

GAS Webアプリで1レコード1ページの印刷PDFを作る

GAS Webアプリから改ページ付き帳票を印刷するために、iframe、ポップアップブロック、Chromeの余白設定を回避する実装パターンをまとめます。

GASWebアプリ印刷PDFCSSgoogle.script.run

はじめに

Google Apps ScriptWebアプリで、一覧データを「1件1ページ」の帳票として印刷したい場面があります。 たとえば担当者別、顧客別、案件別の明細を、ページごとに分けてPDF保存したいケースです。

通常のHTMLならbreak-after: pageで済みそうですが、GAS Webアプリではそのままでは効かないことがあります。

GAS Webアプリでは改ページが効きにくい理由

GAS Webアプリは、Google側のラッパーページの中にサンドボックスiframeとして描画されます。 そのため、Ctrl + Pで印刷すると外側ページが対象になり、iframe内の改ページ指定が期待どおりに反映されないことがあります。

対策は、印刷用HTMLを別ウィンドウへ展開し、iframeではないトップレベルの文書として印刷することです。

印刷HTMLはサーバー側で作る

画面表示用HTMLと印刷用HTMLは分けておくと保守しやすくなります。 印刷用はGAS側でテンプレート評価し、HTML文字列として返します。

function getPrintHtml(token) {
  const list = getPrintableRecords_(token);
  const template = HtmlService.createTemplateFromFile("Print");
  template.data = {
    list: list.map((record) => ({
      record,
      pages: buildPrintPages_(record, 29),
    })),
  };
  return template.evaluate().getContent();
}

google.script.runから呼ぶ関数名は、末尾アンダースコアにしない点も重要です。 getPrintHtml_のような非公開関数名にすると、クライアント側から呼べません。

ポップアップブロックを避ける

次のように、サーバー応答のコールバック内でwindow.openするとブロックされやすくなります。

function doPrintBad() {
  google.script.run.withSuccessHandler((html) => {
    const win = window.open("", "_blank");
    win.document.write(html);
  }).getPrintHtml(TOKEN);
}

コールバックが走る頃には「ユーザーがクリックした直後」という文脈が切れているためです。 実務では、印刷用HTMLを先読みしておき、クリック時には同期的にウィンドウを開きます。

let printHtml = null;

document.addEventListener("DOMContentLoaded", () => {
  const button = document.getElementById("btnPrint");
  button.disabled = true;
  button.textContent = "印刷準備中";

  google.script.run
    .withSuccessHandler((html) => {
      printHtml = html;
      button.disabled = false;
      button.textContent = "印刷 / PDF保存";
    })
    .withFailureHandler(() => {
      button.textContent = "印刷を利用できません";
    })
    .getPrintHtml(TOKEN);
});

function doPrint() {
  if (!printHtml) return;

  const win = window.open("", "_blank");
  if (!win || !win.document) {
    printInPage();
    return;
  }

  win.document.open();
  win.document.write(printHtml);
  win.document.close();
  win.focus();
  setTimeout(() => win.print(), 400);
}

フォールバックとしてページ内印刷も用意する

ブラウザや設定によっては、別ウィンドウが開けないことがあります。 その場合は、印刷用HTMLを現在ページのprintAreaへ差し込み、@media printで画面表示と印刷表示を切り替えます。

function printInPage() {
  const doc = new DOMParser().parseFromString(printHtml, "text/html");
  document.getElementById("printArea").innerHTML = doc.body.innerHTML;
  window.print();
}

この方式では、印刷用HTMLのCSSが本体画面へ影響しないよう、画面用CSSと印刷用CSSの責務を分けます。

Chromeの余白最小対策

Chromeの印刷ダイアログで余白を「最小」にすると、@page { margin }が期待どおりに効かないことがあります。 左右余白は@pageだけに頼らず、用紙内のブロック余白として確保します。

@page {
  size: A4 portrait;
  margin: 10mm 0;
}

.sheet-page {
  margin: 0 10mm 8px;
  padding: 4px;
  border: 2px solid #000;
  break-after: page;
  page-break-after: always;
}

.sheet-page:last-child {
  break-after: auto;
  page-break-after: auto;
}

帳票の品質を上げるCSS

表の見出しや合計欄がページ境界で分断されると読みづらくなります。

thead {
  display: table-header-group;
}

tr,
.summary {
  break-inside: avoid;
  page-break-inside: avoid;
}

1ページに収まらない場合は、事前に配列をページ単位へ分割しておくと安定します。

関連記事

まとめ

GAS Webアプリで改ページ付き印刷を行う場合は、iframe、ポップアップブロック、ブラウザの余白設定をそれぞれ分けて対策します。 印刷HTMLの先読み、クリック時の同期的な別窓展開、ページ内印刷フォールバックを組み合わせると、Web画面からPDF保存まで安定しやすくなります。

この技術で業務改善しませんか?

Excel VBA・GAS・Webアプリで業務の自動化ツールを開発しています。 「こんなことできる?」というご相談だけでもお気軽にどうぞ。

無料相談はこちら →