CakePdf ドキュメント
CakePdf は、PDF エンジンを使って HTML を PDF に変換します。PdfView でコントローラーのアクションを PDF として出力したり、メールの添付ファイルやファイルの保存などのための PDF ファイルを作成したりできます。
対応しているエンジン:
- Dompdf
- mPDF
- TCPDF
- wkhtmltopdf (
wkhtmltopdfバイナリが必要です)
各エンジンへのリンク、ライセンス、注意点は エンジンとライセンス をご覧ください。
インストール
Composer でプラグインをインストールします。
composer require pieceofcake2/cakepdfこのプラグインのタイプは cakephp-plugin なので、composer/installers によってプラグインディレクトリに (CakePdf として) インストールされます。正しい場所にインストールされるように、アプリケーションの composer.json で installer-paths を設定してください。
| レイアウト | installer-paths |
|---|---|
モダン (config/、src/、templates/、plugins/) | "plugins/{$name}/": ["type:cakephp-plugin"] |
レガシー (app/Config/、app/Plugin/) | "app/Plugin/{$name}/": ["type:cakephp-plugin"] |
使うエンジンのライブラリをインストールします。
| エンジン | 必要なもの |
|---|---|
CakePdf.DomPdf | composer require dompdf/dompdf |
CakePdf.Mpdf | composer require mpdf/mpdf |
CakePdf.Tcpdf | composer require tecnickcom/tcpdf |
CakePdf.WkHtmlToPdf | wkhtmltopdf のバイナリ |
暗号化には、さらに pdftk のバイナリが必要です。
プラグインの有効化
config/bootstrap.php (レガシーレイアウトでは app/Config/bootstrap.php) で、プラグインを ブートストラップとルートと一緒に読み込みます。
CakePlugin::load('CakePdf', ['bootstrap' => true, 'routes' => true]);このルートによって .pdf 拡張子が有効になります。
エンジンとライセンス
CakePdf 自体は MIT ライセンスで公開されています。各エンジンは別のプロジェクトで、それぞれのライセンスは 次の表のとおりです。インストールするエンジンのライセンスを確認してください。
| エンジン | ライブラリ | Composer パッケージ | ライセンス | 種類 | 注意点 |
|---|---|---|---|---|---|
CakePdf.DomPdf | Dompdf (GitHub) | dompdf/dompdf ^3.1 | LGPL-2.1 | PHP ライブラリ | PHP ^7.1 || ^8.0。主に CSS 2.1 と一部の CSS3 プロパティに対応します。flexbox や grid には対応せず、表の 1 行は 1 ページに収まる必要があります。DejaVu フォントを同梱しています。 |
CakePdf.Mpdf | mPDF (GitHub) | mpdf/mpdf ^8.0 | GPL-2.0-only | PHP ライブラリ | PHP 5.6 から 8.5 (8.5 は mPDF 8.2.6 から)。Unicode と CJK のフォントを同梱しています。 |
CakePdf.Tcpdf | TCPDF (GitHub) | tecnickcom/tcpdf ^6.10 | LGPL-3.0-or-later | PHP ライブラリ | TCPDF 6.x には PHP 7.1 以上が必要です。アップストリームは TCPDF を非推奨でメンテナンスのみとしており、開発は tc-lib-pdf に移っています。TCPDF 7.x (PHP 8.2 以上) は tc-lib-pdf の上の互換レイヤーで、CakePdf ではテストしていません。writeHTML() が対応する HTML タグは限られており、整形式の HTML が必要です。 |
CakePdf.WkHtmlToPdf | wkhtmltopdf (GitHub) | なし (システムのバイナリ) | LGPL-3.0-or-later | 外部バイナリ | メンテナンスされていません。GitHub リポジトリはアーカイブされており、最後のリリースは 0.12.6 (2020 年 6 月) です。古い Qt WebKit でレンダリングします。プロジェクトの状況 をご覧ください。アップストリームは、信頼できない HTML に使わないよう警告しています。ホストにインストールされたフォントを使います。 |
バージョンは、CakePdf が開発用にインストールするもの (composer.json の require-dev) です。 CakePdf は、インストールするエンジンのバージョンを制限しません。
暗号化 に使う、省略可能な pdftk のバイナリも外部プログラムです。PDFtk Server は GPL バージョン 2 または商用の再頒布ライセンスで提供されており、移植版の pdftk-java は GPL バージョン 2 以降でライセンスされています。
日本語のテキスト (CJK)
標準の PDF フォントには日本語の文字が含まれていないので、どのエンジンでも CJK のグリフを持つフォントが 必要です。
- Dompdf: 同梱の DejaVu フォントは日本語に対応していません。日本語の TrueType フォント (たとえば Noto Sans JP) を CSS の
@font-faceルールで指定し、font-familyで使ってください。 About Fonts and Character Encoding をご覧ください。 - mPDF: CJK に対応した
Sun-ExtAとSun-ExtBフォントを同梱しています。CSS でfont-family: sun-exta;として使ってください。埋め込まれないフォント (Adobe の CJK フォントなど) は、 閲覧ソフトに アジア言語フォントパック が必要です。 - TCPDF: TCPDF 6.x には
cid0jp、kozminproregular、kozgopromediumフォントが含まれています。 これらは PDF に埋め込まれないので、閲覧ソフトにアジア言語フォントパックが必要です。フォントを埋め込むには、TCPDF_FONTS::addTTFfont()で TrueType フォントを変換してください。 - wkhtmltopdf: ホストにインストールされたフォントで (fontconfig を通して) レンダリングするので、 サーバーに日本語フォント、たとえば Noto CJK のフォントパッケージをインストールしてください。
設定
Configure::write('CakePdf', $config); を使うか、コントローラーの $pdfConfig プロパティを設定します (PdfView と一緒に使う場合のみ)。少なくとも $config['engine'] を定義する必要があります。CakePdf を 直接使う場合は、設定の配列をコンストラクターに渡すこともできます。engine の値は、Engine サフィックスを 除いた Plugin.ClassName の形式です。
設定のオプション:
engine: 使うエンジン (必須)options: エンジンのオプション。エンジンによって異なりますpageSize: ページサイズ。デフォルトはA4orientation: ページの向き。デフォルトはportraitmargin:bottom、left、right、topをキーとする余白の配列title: ドキュメントのタイトルencoding: エンコーディング。デフォルトはUTF-8binary: バイナリのパス (WkHtmlToPdfエンジンのみ)。デフォルトは/usr/bin/wkhtmltopdfcache: 生成した PDF をキャッシュするキャッシュ設定の名前 (trueの場合はcake_pdfを使います)。 デフォルトでは無効ですdownload:trueにするとダウンロードを強制します。PdfViewを使う場合のみfilename: ダウンロードを強制するときのドキュメントのファイル名
例:
Configure::write('CakePdf', [
'engine' => 'CakePdf.WkHtmlToPdf',
'options' => [
'print-media-type' => false,
'outline' => true,
'dpi' => 96,
],
'margin' => [
'bottom' => 15,
'left' => 50,
'right' => 30,
'top' => 45,
],
'orientation' => 'landscape',
'download' => true,
]);コントローラーでは、設定を追加したり、グローバルな設定を上書きしたりできます。
class InvoicesController extends AppController
{
public function view($id = null)
{
$this->Invoice->id = $id;
if (!$this->Invoice->exists()) {
throw new NotFoundException(__('Invalid invoice'));
}
$this->pdfConfig = [
'orientation' => 'portrait',
'filename' => 'Invoice_' . $id,
];
$this->set('invoice', $this->Invoice->read(null, $id));
}
}使い方
CakePdf には 2 つの使い方があります。実際に必要なのはどちらか、よく読んでください。両方を混ぜると、 期待どおりの結果になりません。
PdfView でブラウザーに PDF として出力する
コントローラーのアクション用に PDF のビューとレイアウトのファイルを作り、強制ダウンロードも含めて 自動的に出力させることができます。
ビューテンプレートは pdf サブディレクトリに置きます。たとえば templates/Invoices/pdf/view.ctp (レガシーレイアウトでは app/View/Invoices/pdf/view.ctp) です。レイアウトは templates/Layouts/pdf/default.ctp (レガシーレイアウトでは app/View/Layouts/pdf/default.ctp) に置きます。
InvoicesController の $components 配列に RequestHandler コンポーネントがあることを確認し、 http://localhost/invoices/view/1.pdf を開きます。
さらに、ルートファイルに Router::mapResources(['Invoices']); を追加してリソースをマッピングすると、 同じドキュメントに http://localhost/invoices/1.pdf でアクセスできます。
メールの添付ファイルやファイルの保存などのための PDF を作成する
CakePdf クラスを使うと、ビューテンプレートから PDF の生データを作成できます。ビューテンプレートは templates/Pdf/newsletter.ctp (レガシーレイアウトでは app/View/Pdf/newsletter.ctp) に、レイアウトは templates/Layouts/pdf/default.ctp (レガシーレイアウトでは app/View/Layouts/pdf/default.ctp) に置きます。どちらの使い方でもレイアウトは同じディレクトリにありますが、ビューテンプレートのパスは 異なります。必要に応じて、生データをファイルに書き出すこともできます。
App::uses('CakeEmail', 'Network/Email');
App::uses('CakePdf', 'CakePdf.Pdf');
$cakePdf = new CakePdf();
$cakePdf->template('newsletter', 'default');
// Get the PDF as a string, e.g. for an email attachment
$Email = new CakeEmail();
$Email->attachments([
'newsletter.pdf' => ['data' => $cakePdf->output(), 'mimetype' => 'application/pdf'],
]);
// Or write it to a file directly
$cakePdf->write(APP . 'files' . DS . 'newsletter.pdf');暗号化
必要に応じて、PDF を権限付きで暗号化できます。暗号化を使うには、まず暗号化エンジンを選ぶ必要が あります。対応している暗号化エンジンは次のとおりです。
- Pdftk
暗号化の有効化
ブートストラップに次のように追加します。
Configure::write('CakePdf.crypto', 'CakePdf.Pdftk');pdfConfig のオプション:
protect:trueにすると暗号化が有効になりますuserPassword(省略可): PDF ファイルを開くためのパスワードownerPassword(省略可): ロックされた権限を解除するためのパスワードpermissions(省略可): 権限
userPassword と ownerPassword のどちらかを設定する必要があります。
権限
デフォルトでは、すべての権限が拒否されます。すべての権限を許可するには、permissions を true に します。特定の権限を許可するには、permissions に次の権限を組み合わせた配列を設定します。
printdegraded_printmodifyassemblycopy_contentsscreen_readersannotatefill_in
静的アセット
PDF 用のビューテンプレートでは、静的アセットに絶対 URL を使ってください。HtmlHelper::image()、 HtmlHelper::script()、HtmlHelper::css() を使う場合は、必ず $options['fullBase'] = true を 設定してください。
別の方法として、PDF のリクエストでは $options['fullBase'] = true を強制する AppHelper を使えます。
class AppHelper extends Helper
{
/**
* Generate full asset URLs when rendering a PDF.
*
* @param array|string $path Path string or URL array
* @param array $options Options array
* @return string
*/
public function assetUrl($path, $options = [])
{
if (!empty($this->request->params['ext']) && $this->request->params['ext'] === 'pdf') {
$options['fullBase'] = true;
}
return parent::assetUrl($path, $options);
}
}謝辞
Kim Biesbjerg と Jelle Henkens の貢献に深く感謝します。 ここに名前を載せたい方は、改善やほかの PDF エンジンのためのプルリクエストを作成してください。
由来
このパッケージは FriendsOfCake/CakePdf (Packagist では friendsofcake/cakepdf、アップストリームの最終バージョンは 1.0.3) のメンテナンスされたフォークで、元は Ceeram によって作られました。 pieceofcake2 が、モダンな PHP 上の CakePHP 2 向けにメンテナンスしています。 オリジナルからの変更点は フォーク以降のコミット履歴 にあります。
