PHP はしばしば PDF を出力する要望をかなえる必要があります。この PDF を快適に構築する方法の一つが HTML と CSS でデザインを構築して PDF として出力する方法です。これを実現するライブラリにはブラウザを介さないが使える CSS が少ない dompdf や周辺環境(PHP外のバイナリファイルなど)の整備が少々手間ですがブラウザを介してほぼ完璧な CSS を使える snappy といったものがあります。
dompdf/dompdf: HTML to PDF converter for PHP
KnpLabs/snappy: PHP library allowing thumbnail, snapshot or PDF generation from a url or a html page. Wrapper for wkhtmltopdf/wkhtmltoimage
この記事では合いの子的に Google Chrome を PHP で動かして開いたページの印刷結果を PDF としてクライアントにダウンロードさせる方法を紹介します。
使うライブラリは headless-chromium-php です。これは画面を非表示にした chromium を PHP で動作させるためのライブラリです。
chrome-php/headless-chromium-php: Control Chrome from PHP
これを使うためには headless-chromium-php をcomposer require chrome-php/chrome(GitHubのリポジトリ名と違いますが、これで正しくダウンロードできます)でインストールするほか、chromium のブラウザを PHP を動かすマシンにインストールする必要があります。これは各ディストリごとに多様ですので都度調べることになります。例えば debian ならば
apt update apt upgrade wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb apt install ./google-chrome-stable_current_amd64.deb
でダウンロードとインストールができます。
ここまで来たらあとは動かすだけです。例えば次の様に動かせます。
<?php
require __DIR__ . '/../vendor/autoload.php';
// chrome を動かします
$browser = (new \HeadlessChromium\BrowserFactory('/usr/bin/google-chrome'))
->createBrowser(['noSandbox' => true]);
try {
// 新しいページ(新しいタブ的なもの)を用意して
$page = $browser->createPage();
// 指定したURLにジャンプします。このURLで開けるページに PDF にしたいものを仕込んでおきます。
// 安全を期すならば外部公開していないポートで web ページを開けるようにしておき、都度そこからPDF用の情報を見れる様にするのが良いでしょう
$page->navigate('http://localhost/hogehoge.pdf')
->waitForNavigation();
// pdfをダウンロード
$fileName = 'sample.pdf';
// フレームワークを使えばこの header + アウトプットストリームアクセスよりスマートにダウンロードを書けるかと思います
header("Content-Disposition: attachment; filename={$fileName}");
$page->pdf([
// ここに PDF に関するオプションを記述
// @see https://github.com/chrome-php/headless-chromium-php#print-as-pdf
])->saveToFile('php://output');
} finally {
// ブラウザプロセスが生き残るのを防ぐために finally でプロセスを閉じます
$browser->close();
}
このようにすると CSS が使えなくてやきもきすることが減ります。