
KantanBiz 一括請求書:スマホでも印刷・PDF保存が安定するようにした話
スマホから一括請求書を「印刷」「PDF保存」するとき、次のような不具合が出ていました。
- PDF の自社情報(ロゴ・住所など)が PC 版より小さく見える
- 2ページ分ある請求書が 1ページで終わる
- PC なのに共有シート(AirDrop など)が開いてダウンロードにならない
- スマホで「ブロックしたポップアップ」と案内ダイアログが出る
今回、これらをまとめて直しました。
画面のプレビューはボタンを押しても変化しないという方針はそのままです。
こだわったポイント
1. プレビューはそのまま、出力だけ別処理
「印刷」「PDF保存」を押しても、画面上の請求書プレビューは動きません。
裏側で HTML を複製し、PDF 用の専用レイアウトで出力しています。
ダークモードで見ていても、印刷・PDF は白い帳票(ライト帳票)で出ます。プレビューだけダークモード対応、という使い分けです。
2. スマホ PDF で自社情報が小さくならないように
スマホは画面幅が狭いため、PDF 生成時にレイアウトが崩れやすい状態でした。
対策として、PDF キャプチャ時だけ次を行っています。
- PC プレビュー相当の幅(A4 相当)でレンダリング
- スマホ向けの余白詰め CSS が PDF に効かないよう上書き
- 自社ブロックを 2 列グリッドの右列として固定
印影の位置・見た目は従来どおりです(今回は触っていません)。
3. 2ページ目が切れない PDF 生成
2ページあるのに 1ページで終わる原因は、主に次の 2 点でした。
- キャプチャ用の隠し枠が 1px + overflow:hidden になっており、Safari / スマホで html2canvas が 1 ページ分しか取れないことがある
- ページ分割の計算が、実際に取れた画像の高さとズレていた
修正内容は次のとおりです。
- スマホ・Safari では画面外(left: -12000px)にフル幅で配置してキャプチャ
- 明細・フッター下端まで高さを計測
- ページ分割は DOM の高さではなく、実際にキャプチャした canvas の高さを基準にする
これで 2 ページ目以降も PDF に含まれるようになりました。
4. PC は普通にダウンロード、スマホは共有シート or ダウンロード
ファイル名は {顧客名}-{締日}-請求書.pdf 形式です。
| 環境 | 保存の動き |
|---|---|
| PC(Chrome など) | <a download> でそのままダウンロード |
| iPhone / iPad | 共有シート(Web Share API)を優先。正しいファイル名で「ファイルに保存」しやすい |
| iOS で共有できない場合 | <a download> にフォールバック |
以前は macOS 版 Chrome でも navigator.share が使われ、AirDrop などの共有シートが開いていました。PC では共有ではなく通常のダウンロードに限定しました。
5. 「ブロックしたポップアップ」を出さない
スマホで PDF 保存後に「ブロックしたポップアップ: 1」と出ていたのは、共有シートが使えないときに window.open() で PDF を開いていたためです。
PDF 生成は html2canvas + jsPDF で数秒かかる非同期処理のため、ボタンクリックから時間が経ったあとの window.open はポップアップブロックの対象になります。
対策:
window.openと案内アラートを廃止- 共有失敗時は
<a download>のクリックで保存
ダウンロード・保存はできるまま、ポップアップブロックの表示だけ抑えています。
ブラウザ別の整理
| ブラウザ | 印刷 | PDF保存 |
|---|---|---|
| Chrome(PC) | PDF 経由で印刷ダイアログ | ダウンロード |
| Safari(Mac / iOS) | PDF 経由で印刷 | iOS は共有シート優先 |
| Firefox | PDF と同じページ画像を印刷(iframe 直印刷は不可のため) | ダウンロード |
| スマホ全般 | 上記と同様 | 共有 or ダウンロード(ポップアップなし) |
技術メモ(開発者向け)
主な変更ファイル:
resources/js/bulk-invoice-print.js… PDF キャプチャ・ページ分割・レイアウト補正resources/js/kp-print-iframe.js…downloadPdfBlob()の端末別保存処理resources/views/clients/bulk-invoice.blade.php… PDF 用ミラースタイル・ダークモード時のライト帳票
PDF キャプチャの流れ(概要):
- プレビュー HTML を複製
- 画面外シェルにマウント(スマホは 1px クリップを使わない)
- html2canvas で画像化 → jsPDF で A4 分割
- 端末に応じてダウンロード or 共有シート
ブラウザ印刷の共通ルール(kp-print-iframe パターン)も踏襲しています。
- 空白ページ・白紙印刷を出さない
- Safari では iframe 内の
window.print()を使う - 画面ごとに JS を分離し、全体一括読み込みはしない
スマホで PDF を「ファイル」に保存する手順(iOS)
- 「PDF保存」をタップ
- 共有シートが開いたら、上にスクロール
- 「ファイルに保存」を選ぶ
- 保存先とファイル名(例:
○○株式会社-2026-05-31-請求書.pdf)を確認して保存
まとめ
今回の対応で、スマホからでも次が期待どおり動くようになりました。
- プレビューを崩さず PDF 保存・印刷できる
- 自社情報のサイズが PC 版と揃いやすい
- 2 ページ以上の請求書も PDF に収まる
- PC は普通のダウンロード、スマホは共有 or ダウンロード
- 「ポップアップをブロックしました」が出にくい
帳票まわりは端末・ブラウザ差が出やすいので、引き続き実機での確認をお願いしています。不具合があれば端末名とブラウザ名を添えてご連絡ください。




コメント