ここは、技術情報、身の回りに起こった出来事を、「もしかしたらみんなの役に立つかもしれない」と思って書き留めておく場所です。

Image

【PHP】mPDFを使ってHTMLからPDFを作成する

2020年11月9日
 

最近またPHPを色々使いだしまして

その中でPDFも作ったので書き残しておこうと思いました。

 

mPDFとは

mPDFはPHP製のPDF作成ライブラリです。

といっても難しい作り方ではなく、HTMLを記述すればPDFを作成してくれるという、とんでもなく便利なライブラリなのです。

 

インストール

composerを使用します。

composer require mpdf/mpdf

インストールにはgdが必要です。

今回はインストールされた最新のバージョンv8.0.7を使用しています。

v7以上では機能的な違いがあまりないようです。

 

とりあえず使う

<?php
declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

$mpdf = new \Mpdf\Mpdf([
	'mode' => 'ja',
	'format' => 'A4',
	'orientation' =>  'P'
]);

$tbl = <<<EOD
<table>
<tr>
<th>名前</th><th>職業</th>
</tr>
<tr>
<td>田中太郎</td><td>公務員</td>
</tr>
</table>
EOD;

$mpdf->WriteHTML($tbl, \Mpdf\HTMLParserMode::HTML_BODY);

$file = __DIR__ . '/test1.pdf';

$mpdf->Output($file, \Mpdf\Output\Destination::FILE);

コンストラクタ

従来のmPDFは

コンストラクタがパラメタの列挙だったのですが、

連想配列になり、必要なオプションのみ記述出来るようになっています。

最低限、日本語と用紙サイズA4、用紙の向き'P'(縦向き。横向きは’L’)

を指定しておきます。

WriteHTML

従来のmPDFは

WriteHTMLにHTML全部を記述していましたが、2番目の引数にHTML_BODYを記述することにより、BODY内のみを書けるようになっていました。

楽になりましたね。

以前はテンプレートエンジン経由で渡していましたが、BODYだけならそんな事しなくても良いかもしれません。

Output

従来のmPDFと同様に2番目の引数なしならば、画面に表示されます。

Destination::FILE('F'と同じ)を指定するとファイルに書き出します。

結果

CSSを指定する

<?php
declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

$mpdf = new \Mpdf\Mpdf([
	'mode' => 'ja',
	'format' => 'A4',
	'orientation' =>  'P'
]);


$css = <<<EOD
table {
  border-collapse:collapse;
}
 
table th{
  border:1px solid #333333;
  background:#eeeeee;
}
 
table td{
  border:1px solid #333333;
  background:#ffffff;
}
EOD;

$tbl = <<<EOD
<table>
<tr>
<th>名前</th><th>職業</th>
</tr>
<tr>
<td>田中太郎</td><td>公務員</td>
</tr>
</table>
EOD;

$mpdf->WriteHTML($css, \Mpdf\HTMLParserMode::HEADER_CSS);
$mpdf->WriteHTML($tbl, \Mpdf\HTMLParserMode::HTML_BODY);

$file = __DIR__ . '/test2.pdf';

$mpdf->Output($file, \Mpdf\Output\Destination::FILE);

CSS

WriteHTMLにHTML全体を記述しなくても良くなったため、

CSSも分けて渡せるようになりました。

WriteHTMLにHTMLParserMode::HEADER_CSSを使って渡しています。

mPDFで有効なCSSは公式ドキュメントで調べる必要があります。

https://mpdf.github.io/css-stylesheets/supported-css.html

今回はtableの枠線と背景色です。

結果

CSSで細かい調整をする

declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

$mpdf = new \Mpdf\Mpdf([
	'mode' => 'ja',
	'format' => 'A4',
	'orientation' =>  'P'
]);


$css = <<<EOD
table {
  border-collapse:collapse;
}
 
table th{
  border:1px solid #333333;
  background:#eeeeee;
  text-align:center;
  padding:10px;
}
 
table td{
  border:1px solid #333333;
  background:#ffffff;
  text-align:center;
  padding:10px 5px 10px 5px;
}
EOD;

$tbl = <<<EOD
<table>
<tr>
<th>名前</th><th>職業</th>
</tr>
<tr>
<td>田中太郎</td><td>公務員</td>
</tr>
<tr>
<td>佐藤小次郎</td><td>古物鑑定士</td>
</tr>
</table>
EOD;

$mpdf->WriteHTML($css, \Mpdf\HTMLParserMode::HEADER_CSS);
$mpdf->WriteHTML($tbl, \Mpdf\HTMLParserMode::HTML_BODY);

$file = __DIR__ . '/test3.pdf';

$mpdf->Output($file, \Mpdf\Output\Destination::FILE);

CSSでの調整

無指定のCSSではtableが文字ギリギリに組まれてしまうため、

パディングを指定してスペースを空けます。

また、文字位置をセンタリングにしています。なぜかthは最初からセンタリングされてましたね。

結果

要素をセンタリング

<?php
declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

$mpdf = new \Mpdf\Mpdf([
	'mode' => 'ja',
	'format' => 'A4',
	'orientation' =>  'P'
]);


$css = <<<EOD
table {
  border-collapse:collapse;
  width:80%;
  margin: 0 auto;
}
 
table th{
  border:1px solid #333333;
  background:#eeeeee;
  text-align:center;
  padding:10px;
}
 
table td{
  border:1px solid #333333;
  background:#ffffff;
  padding:10px 5px 10px 5px;
}
EOD;

$tbl = <<<EOD
<table>
<tr>
<th>名前</th><th>職業</th>
</tr>
<tr>
<td>田中太郎</td><td>公務員</td>
</tr>
<tr>
<td>佐藤小次郎</td><td>古物鑑定士</td>
</tr>
</table>
EOD;

$mpdf->WriteHTML($css, \Mpdf\HTMLParserMode::HEADER_CSS);
$mpdf->WriteHTML($tbl, \Mpdf\HTMLParserMode::HTML_BODY);

$file = __DIR__ . '/test4.pdf';

$mpdf->Output($file, \Mpdf\Output\Destination::FILE);

要素のセンタリング

このまま出力して見せるとおそらく、

「なんでこんなに左に出力されてるの?」

とダメだしをされてしまうので、CSSでtableの幅を80%に指定し、mergin: 0 auto;でセンタリングしています。

結果

フォントを指定する

<?php
declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

$mpdf = new \Mpdf\Mpdf([
	'mode' => 'ja',
	'format' => 'A4',
	'orientation' =>  'P',
	'fontDir' => __DIR__ . '/ipafonts',
	'fontdata' => [
		'ipaexg' => [
			'R' => 'ipaexg.ttf'
			]
		],
	'default_font' => 'ipaexg'	
]);

$css = <<<EOD
table {
  border-collapse:collapse;
  width:80%;
  margin: 0 auto;
  font-size:20px;
}
 
table th{
  border:1px solid #333333;
  background:#eeeeee;
  text-align:center;
  padding:10px;
}
 
table td{
  border:1px solid #333333;
  background:#ffffff;
  padding:10px 5px 10px 5px;
}
EOD;

$tbl = <<<EOD
<table>
<tr>
<th>名前</th><th>職業</th>
</tr>
<tr>
<td>田中太郎</td><td>公務員</td>
</tr>
<tr>
<td>佐藤小次郎</td><td>古物鑑定士</td>
</tr>
</table>
EOD;

$mpdf->WriteHTML($css, \Mpdf\HTMLParserMode::HEADER_CSS);
$mpdf->WriteHTML($tbl, \Mpdf\HTMLParserMode::HTML_BODY);

$file = __DIR__ . '/test5.pdf';

$mpdf->Output($file, \Mpdf\Output\Destination::FILE);

フォントの用意

このまま提出するとおそらく、

「なんでゴシックじゃないの?」

とダメだしをされてしまうので、フォントを指定します。

(今までのmPDFはフォントをインストールしないと日本語が出なかった気がしますが、何もせずに日本語が出力されていますね)

今回は

IPAexゴシック(Ver.004.01)

をダウンロードしてipafontsディレクトリに置いておきます。

フォントの指定

コンストラクタでfontDir、fontdata、default_fontを指定します。

複数フォントを入れてCSSで指定する事もできるようです。

結果

まとめ

昔のバージョンしか知らなかったのですが、かなり使いやすくなっていました。

もっと詳しく知りたい場合は公式ドキュメントをどうぞ。

https://mpdf.github.io/