出力

mPDF vol.4

mPDFでHTMLファイルからPDFファイルを作成する

  • このエントリーをはてなブックマークに追加

PHPでPDFファイルを作成するときに、HTMLの表示をそのまま出力したいことがあります。今回はHTMLとCSSファイル(スタイルシート)を使ってPDFを作成する方法を解説します。

この記事のポイント

  • HTMLからPDFファイルを作成する
  • 作成するPDFファイルによってスタイルシートを切り替える

目次

HTMLの見た目をそのままにPDFファイルを作成する

今回は、mPDFライブラリを使ってHTMLファイルとCSSファイルからPDFファイルを作成します。

mPDFライブラリはすでにインストールされていることを前提に進めます。
インストールや基本的な使い方については、「mPDFライブラリでPDFファイルを作成する」を参照ください。

こちらで解説している内容は公式リファレンスを元にしています。
リファレンスを参照したい方はこちら。
mPDF functions (英語)

出力するHTMLとCSSを確認

PDFを作成する前に、まずは出力したいHTMLファイルとCSSファイル(スタイルシート)の内容を確認します。
今回はサンプル用に、次の2つのファイルを用意しました。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="description" content="テストページです。">
<meta name="og:title" content="テストページ">
<meta name="og:type" content="article">
<meta name="og:description" content="こちらはテスト用のHTMLページです。特に意味はありません。">
<title>テストページ</title>
<link type="text/css" rel="stylesheet" href="style.css">
</head>
<body>
	<h1>PDF出力のテスト</h1>
	<p>こちらはテスト用のHTMLページです。特に意味はありません。</p>
	<figure><img src="pic.jpg"></figure>
	<table>
		<tr>
			<th>ID</th>
			<th>名前</th>
			<th>性別</th>
			<th>メールアドレス</th>
		</tr>
		<tr>
			<td>1</td>
			<td>石川 太郎</td>
			<td>男</td>
			<td>taro@gray-code.com</td>
		</tr>
		<tr>
			<td>6</td>
			<td>川辺 咲</td>
			<td>女</td>
			<td>saki@gray-code.com</td>
		</tr>
		<tr>
			<td>7</td>
			<td>細川 亜美</td>
			<td>女</td>
			<td>ami@gray-code.com</td>
		</tr>
		<tr>
			<td>11</td>
			<td>田中 啓介</td>
			<td>男</td>
			<td>keisuke@gray-code.com</td>
		</tr>
	</table>
</body>
</html>

style.css

@charset "UTF-8";

@media all {
	
	/* Reset Style
	----------------------------------------*/
	
	html, body, div, span, object, iframe,
	h1, h2, h3, h4, h5, h6, p, blockquote, pre,
	abbr, address, cite, code,
	del, dfn, em, img, ins, kbd, q, samp,
	small, strong, sub, sup, var,
	b, i,
	dl, dt, dd, ol, ul, li,
	fieldset, form, label, legend,
	table, caption, tbody, tfoot, thead, tr, th, td,
	article, aside, canvas, details, figcaption, figure, 
	footer, header, hgroup, menu, nav, section, summary,
	time, mark, audio, video {
	    margin:0;
	    padding:0;
	    border:0;
	    outline:0;
	    font-size:100%;
	    vertical-align:baseline;
	    background:transparent;
	}
	
	body {
	    line-height:1;
	}
	
	article,aside,details,figcaption,figure,
	footer,header,hgroup,menu,nav,section { 
	    display:block;
	}
	
	nav ul {
	    list-style:none;
	}
	
	blockquote, q {
	    quotes:none;
	}
	
	blockquote:before, blockquote:after,
	q:before, q:after {
	    content:'';
	    content:none;
	}
	
	a {
	    margin:0;
	    padding:0;
	    font-size:100%;
	    vertical-align:baseline;
	    background:transparent;
	}
	
	/* change colours to suit your needs */
	ins {
	    background-color:#ff9;
	    color:#000;
	    text-decoration:none;
	}
	
	/* change colours to suit your needs */
	mark {
	    background-color:#ff9;
	    color:#000; 
	    font-style:italic;
	    font-weight:bold;
	}
	
	del {
	    text-decoration: line-through;
	}
	
	abbr[title], dfn[title] {
	    border-bottom:1px dotted;
	    cursor:help;
	}
	
	table {
	    border-collapse:collapse;
	    border-spacing:0;
	}
	
	hr {
	    display:block;
	    height:1px;
	    border:0;   
	    border-top:1px solid #cccccc;
	    margin:1em 0;
	    padding:0;
	}
	
	input, select {
	    vertical-align:middle;
	}


	/* Original Style
	----------------------------------------*/

	body {
		padding: 20px;
		color: #333;
		background: #f7f7f7;
	}

	h1 {
		margin-bottom: 40px;
		padding: 10px 0;
		font-size: 129%;
		color: #fff;
		text-align: center;
		background: #555;
	}
	
	p {
		margin-bottom: 20px;
	}
	
	figure {
		margin-bottom: 40px;
		width: 100%;
	}
		figure img {
			max-width: 100%;
			height: auto;
			line-height: 1.0em;
			vertical-align: top;
		}

	table {
		overflow: hidden;
		margin-bottom: 20px;
		border: 1px solid #62a7c4;
	}

	table th {
		padding: 10px;
		font-size: 86%;
		line-height: 1.6em;
		vertical-align: middle;
		border-right: 1px solid #62a7c4;
		border-bottom: 1px solid #62a7c4;
		background: #89c9e3;
	}
	
	table td {
		padding: 10px;
		font-size: 86%;
		line-height: 1.6em;
		border-right: 1px solid #ddd;
		border-bottom: 1px solid #ddd;
		background: #fff;
	}
}

ブラウザ表示結果

ブラウザの表示結果サンプル

この表示をそのままPDFに出力していきます。

PDFファイルを作成する

PDFファイルを作成していきます。
PDFを作成するコードは「mpdf.php」に書いていきます。

mpdf.php

<?php

// ライブラリの読み込み
require_once 'mpdf60/mpdf.php';

// HTMLとCSSを読み込み
$html_doc = new DOMDocument();
$html_doc->loadHTMLFile('index.html');
$css = file_get_contents('style.css');

// mPDFクラス作成
$mpdf = new mPDF( "ja");

// ファイル名を指定
$mpdf->setTitle( "MyPDF.pdf");

// HTMLとCSSをPDFへ書き込む
$mpdf->WriteHTML( $css, 1);
$mpdf->WriteHTML( $html_doc->saveHTML(), 2);

// 出力
$mpdf->Output();
return;

実行結果

次のようなPDFファイルが作成されます。

出力したPDFファイル

解説

コードを上から順に解説していきます。

mPDFライブラリを読み込んだ後、「// HTMLとCSSを読み込み」ではHTMLファイルとCSSファイルを読み込んでいます。

mpdf.php

// HTMLとCSSを読み込み
$html_doc = new DOMDocument();
$html_doc->loadHTMLFile('index.html');
$css = file_get_contents('style.css');

HTMLファイルでもheadタグ内のlinkタグでスタイルシート「style.css」を読み込んでいますが、必要なHTMLファイルとCSSファイルは個別に読み込む必要があるので注意してください

また、PDFは「印刷」扱いとなるため、適用されるスタイルシートは@mediaが「all」、もしくは「print」になります。

$html_docにはloadHTMLFileメソッドで読み込んだHTMLコードが入り、$cssにはfile_get_contents関数で読み込んだスタイルシートが入ります。
ここで読み込んだコードを、次の箇所でPDFファイルへ反映していきます。

その後はmPDFクラスを作成しファイル名を設定し、「// HTMLとCSSをPDFへ書き込む」の箇所でPDFファイルの内容を設定します。

mpdf.php

// HTMLとCSSをPDFへ書き込む
$mpdf->WriteHTML( $css, 1);
$mpdf->WriteHTML( $html_doc->saveHTML(), 2);

WriteHTMLメソッドの第1パラメータは書き込む内容を、第2パラメータはモードを指定します。
モードとは、「1」はスタイルシート、「2」はHTMLタグといったように決められており、上記のコードでもそれぞれ該当する値を指定しています。

パラメータの詳細は公式マニュアル「WriteHTML() – mPDF Manual」をご覧ください。

以上を実行し、最後にOutputメソッドを実行すると、いよいよPDFファイルが作成されます。

しかし、出力されたPDFファイルをよく見ると一番上にtitleタグが出力されてしまっています。
続いて、この部分が出力されないようにしましょう。

不要な出力を取り除く

$html_doc->saveHTML()で出力される内容をvar_dump関数で確認してみると、次のように1つの文字列になっていることが分かります。

mpdf.php

string '<!DOCTYPE html>
<html lang="ja"><head><meta charset="utf-8"><meta name="description" content="テストページです。"><meta name="og:title" content="テストページ"><meta name="og:type" content="article"><meta name="og:description" content="こちらはテスト用のHTMLページです。特に意味はありません。"><title>テストページ</title><link type="text/css" rel="stylesheet" href="style.css"></head><body>
	<h1>PDF出力のテスト</h1>
	<p>こちらはテスト用のHTMLページです。特に意味はありません。</p>
	<figure><img src="pic.jpg"></figure><table><tr><th>ID</th>
			<th>名前</th>
			<th>性別</th>
			<th>メールアドレス</th>
		</tr><tr><td>1</td>
			<td>石川 太郎</td>
			<td>男</td>
			<td>taro@gray-code.com</td>
		</tr><tr><td>6</td>
			<td>川辺 咲</td>
			<td>女</td>
			<td>saki@gray-code.com</td>
		</tr><tr><td>7</td>
			<td>細川 亜美</td>
			<td>女</td>
			<td>ami@gray-code.com</td>
		</tr><tr><td>11</td>
			<td>田中 啓介</td>
			<td>男</td>
			<td>keisuke@gray-code.com</td>
		</tr></table></body></html>
' (length=1647)

そこで、不要なタグを正規表現で検索し、取り除くコードを追加していきます。
先ほどのコードに、下記の赤いコードを追記してください。

mpdf.php

<?php

// ライブラリの読み込み
require_once 'mpdf60/mpdf.php';

// HTMLとCSSを読み込み
$html_doc = new DOMDocument();
$html_doc->loadHTMLFile('index.html');
$css = file_get_contents('style.css');

// 変数の初期化
$html_array = array();
$html_array2 = array();

// 不要なタグで分割
$html_array = preg_split( '/<title>/', $html_doc->saveHTML());
$html_array2 = preg_split( '/<\/title>/', $html_array[1]);

// mPDFクラス作成
$mpdf = new mPDF( "ja");

// ファイル名を指定
$mpdf->setTitle( "MyPDF.pdf");

// HTMLとCSSをPDFへ書き込む
$mpdf->WriteHTML( $css, 1);
$mpdf->WriteHTML( $html_doc->saveHTML(), 2);
$mpdf->WriteHTML( $html_array[0] . $html_array2[1], 2);

// 出力
$mpdf->Output();
return;

実行結果

修正後のコードを実行すると、ページ上部に出力されていたtitleタグが消えたPDFが作成されます。

修正後のPDF出力結果

解説

コード自体はシンプルで、preg_split関数を使って文字列を分割しているだけです。
その結果、$html_array[0]にはtitleタグより前のコードが入り、$html_array2[1]にはtitleタグの後ろのコードが入ります。

この2つを、WriteHTMLメソッドでPDFへ内容を書き込むときに文字列結合することで、titleタグが取り除かれたHTMLからPDFを作成することができる仕組みです。

preg_split関数を使った理由は、titleタグ内のテキストをPDFのファイル名にしたいことがあるためです。
$html_array2[0]にはタイトルの文字列が入っているため、この値をsetTitleメソッドに渡すことでファイル名に設定することができます。

  • このエントリーをはてなブックマークに追加
前のページへ 一覧ページへ一覧 次のページへ