TCPDFでPDF帳票の作成 †PHPライブラリ TCPDF でPDF帳票を作成する手順を記載する。 インストール †たぶん Composer でやる方が良いが。。 適当なフォルダを作る †mkdir test-tcpdf cd test-tcpdf TCPDFインストール †https://github.com/tecnickcom/tcpdf から git clone git clone https://github.com/tecnickcom/TCPDF.git FPDIインストール †PDFをテンプレートにして値を埋め込む場合は必須 mkdir FPDI && cd FPDI wget https://www.setasign.com/downloads/2102915/FPDI-2.1.0.zip unzip FPDI-2.1.0.zip rm -rf FPDI-2.1.0.zip cd ../ インストール後のフォルダ構成 †だいたいこんな感じ。 test-tcpdf ├── FPDI │ ├── LICENSE.txt │ ├── README.md │ ├── composer.json │ └── src │ ├── FpdfTpl.php │ ├── FpdfTplTrait.php │ ├── Fpdi.php │ ├── FpdiException.php │ ├── FpdiTrait.php │ ├── PdfParser │ ├── PdfReader │ ├── Tcpdf │ ├── TcpdfFpdi.php │ ├── Tfpdf │ └── autoload.php ├── TCPDF │ ├── CHANGELOG.TXT │ ├── LICENSE.TXT │ ├── README.md │ ├── composer.json │ ├── config │ ├── examples │ ├── fonts │ ├── include │ ├── tcpdf.php │ ├── tcpdf_autoconfig.php │ ├── tcpdf_barcodes_1d.php │ ├── tcpdf_barcodes_2d.php │ ├── tcpdf_import.php │ ├── tcpdf_parser.php │ └── tools HTMLからPDFを出力する †スタイルシートも効くが、padding が効かない等、いくつかの制限がある模様。 html2pdf.php <?php include("./TCPDF/tcpdf.php"); define("MY_PDF_PAGE_ORIENTATION" , "P"); // P:Portrait, L:Landscape define("MY_PDF_FONT_NAME" , "kozgopromedium"); // kozminproregular define("MY_PDF_FONT_SIZE" , 10); define("MY_PDF_UNIT" , "mm"); define("MY_PDF_PAGE_FORMAT" , "A4"); define("MY_PDF_IMAGE_SCALE_RATIO" , 1); define("MY_PDF_MARGIN_HEADER" , 0); define("MY_PDF_MARGIN_FOOTER" , 0); define("MY_PDF_MARGIN_TOP" , 10); define("MY_PDF_MARGIN_LEFT" , 15); define("MY_PDF_MARGIN_RIGHT" , 15); define("MY_PDF_MARGIN_BOTTOM" , 20); class MYPDF extends TCPDF { // フッタのカスタマイズ(ページ番号を出力する) public function Footer() { $this->SetY(-15); // Position at 15 mm from bottom $this->SetFont('helvetica', 'I', 8); $this->Cell(0, 10, 'Page '.$this->getAliasNumPage().'/'.$this->getAliasNbPages(), 0, false, 'C', 0, '', 0, false, 'T', 'M'); } } $pdf = new MYPDF(MY_PDF_PAGE_ORIENTATION, MY_PDF_UNIT, MY_PDF_PAGE_FORMAT, true, 'UTF-8', false); $pdf->SetTitle('PDF出力テスト'); //$pdf->SetSubject('TCPDF Tutorial'); //$pdf->SetHeaderData(null, null, null, null); //$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE.' 006', PDF_HEADER_STRING); //$pdf->setHeaderFont(Array(MY_PDF_FONT_NAME, '', MY_PDF_FONT_SIZE)); //$pdf->setFooterFont(Array(MY_PDF_FONT_NAME, '', MY_PDF_FONT_SIZE)); //$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED); $pdf->SetMargins(MY_PDF_MARGIN_LEFT, MY_PDF_MARGIN_TOP, MY_PDF_MARGIN_RIGHT); //$pdf->SetHeaderMargin(MY_PDF_MARGIN_HEADER); //$pdf->SetFooterMargin(MY_PDF_MARGIN_FOOTER); $pdf->SetAutoPageBreak(TRUE, MY_PDF_MARGIN_BOTTOM); $pdf->setPrintHeader(false); $pdf->setPrintFooter(true); $pdf->setImageScale(MY_PDF_IMAGE_SCALE_RATIO); $pdf->SetFont(MY_PDF_FONT_NAME, "", 10); // ページを追加 $pdf->AddPage(); // PDFに変換するHTML $html =<<<_EO_HTML_ <style> table { border-collapse: collapse; } table tr th { background-color: #efe; border: 1px solid #333; padding: 10px; /* 効かない */ } table tr td { border: 1px solid #333; padding: 10px; /* 効かない */ } .center { text-align: center; } </style> <h1>TCPDFテスト</h1> <table cellpadding="5"> <thead> <tr> <th>列1</th><th>列2</th><th>列3</th> </tr> </thead> <tbody> <tr> <td>2018-01-01</td><td>テスト1</td><td class="center">100</td> </tr> <tr> <td>2018-01-02</td><td>テスト2</td><td class="center">200</td> </tr> </tbody> </table> _EO_HTML_; $pdf->writeHTML($html, true, false, true, false, ''); // 2ページ目追加 //$pdf->lastPage(); //$pdf->AddPage(); //$pdf->writeHTML($html, true, false, true, false, ''); /* * Output の第2引数にI,D,FI,FD を指定すればHTTPレスポンスヘッダ(Content-TypeやContent-Disposition)を自動的に出力してくれる。 * 自分でヘッダを調整したい場合は、S でデータだけ取得して自分でヘッダを吐く。 * (ファイル名に日本語を含めたい場合など.) */ $data = null; $fileName = "テスト.pdf"; //$pdf->Output($fileName, 'I'); // ブラウザに表示 //$pdf->Output($fileName, 'D'); // ダウンロードダイアログを表示 //$pdf->Output($fileName, 'F'); // サーバにファイルを保存 $data = $pdf->Output(null,'S'); // PDFドキュメントを文字列として返却 //$pdf->Output($fileName, 'FI'); // ファイルに保存して、ブラウザにも表示 //$pdf->Output($fileName, 'FD'); // ファイルに保存して、ダウンロードダイアログを表示 //$data = $pdf->Output(null, 'E'); // Base64エンコード済みのPDFドキュメントを返却(メールに添付するmultipartコンテンツ用なのでContent-Typeなどのヘッダーが付く) if ($data != null) { // ブラウザにそのまま表示 header('Content-Type: application/pdf'); header('Content-Disposition: inline; filename="'.basename($fileName).'"'); // ダウンロード //header('Content-Type: application/octet-stream', false); //header('Content-Disposition: attachment; filename="'.basename($fileName).'"'); echo $data; } ?> 既存のPDFテンプレートに値を埋め込んで出力する †テンプレートとなるPDFの作成 †別にTCPDFで作らなくても良いが。 print_template.php <?php include("./TCPDF/tcpdf.php"); define("MY_PDF_PAGE_ORIENTATION" , "P"); // P:Portrait, L:Landscape define("MY_PDF_FONT_NAME" , "kozgopromedium"); // kozminproregular define("MY_PDF_FONT_SIZE" , 10); define("MY_PDF_UNIT" , "mm"); define("MY_PDF_PAGE_FORMAT" , "A4"); define("MY_PDF_IMAGE_SCALE_RATIO" , 1); define("MY_PDF_MARGIN_HEADER" , 0); define("MY_PDF_MARGIN_FOOTER" , 0); define("MY_PDF_MARGIN_TOP" , 10); define("MY_PDF_MARGIN_LEFT" , 15); define("MY_PDF_MARGIN_RIGHT" , 15); define("MY_PDF_MARGIN_BOTTOM" , 20); $pdf = new TCPDF(MY_PDF_PAGE_ORIENTATION, MY_PDF_UNIT, MY_PDF_PAGE_FORMAT, true, 'UTF-8', false); $pdf->SetTitle('PDF 出力テスト'); $pdf->SetMargins(MY_PDF_MARGIN_LEFT, MY_PDF_MARGIN_TOP, MY_PDF_MARGIN_RIGHT); $pdf->SetAutoPageBreak(TRUE, MY_PDF_MARGIN_BOTTOM); $pdf->setPrintHeader(false); $pdf->setPrintFooter(true); $pdf->setImageScale(MY_PDF_IMAGE_SCALE_RATIO); $pdf->SetFont(MY_PDF_FONT_NAME, "", 10); $pdf->AddPage(); $html =<<<_EO_HTML_ <style> table.tbl { border-collapse: collapse; } table.tbl tr th { background-color: #efe; border: 1px solid #333; padding: 10px; /* 効かない */ } table.tbl tr td { border: 1px solid #333; padding: 10px; /* 効かない */ } .center { text-align: center; } </style> <h1>PDF出力テスト</h1> <table class="tbl" cellpadding="5"> <tr><th>列1</th><th>列2</th><th>列3</th></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> <tr><td></td><td></td><td></td></tr> </table> _EO_HTML_; $pdf->writeHTML($html, true, false, true, false, ''); // ファイルに保存 $fileName = "/tmp/template.pdf"; $pdf->Output($fileName, 'F'); ?> # 実行 php print_template.php # 作成したテンプレートをカレントディレクトリにコピー cp /tmp/template.pdf ./ 作成したテンプレートに値を埋め込む †ここから、実際にPDFテンプレートに値を埋め込むプログラム。 use_template.php <?php use setasign\Fpdi; include("./TCPDF/tcpdf.php"); include("./FPDI/src/autoload.php"); define("MY_PDF_PAGE_ORIENTATION" , "P"); // P:Portrait, L:Landscape define("MY_PDF_FONT_NAME" , "kozgopromedium"); // kozminproregular define("MY_PDF_FONT_SIZE" , 10); define("MY_PDF_UNIT" , "mm"); define("MY_PDF_PAGE_FORMAT" , "A4"); define("MY_PDF_IMAGE_SCALE_RATIO" , 1); define("MY_PDF_MARGIN_HEADER" , 0); define("MY_PDF_MARGIN_FOOTER" , 0); define("MY_PDF_MARGIN_TOP" , 10); define("MY_PDF_MARGIN_LEFT" , 15); define("MY_PDF_MARGIN_RIGHT" , 15); define("MY_PDF_MARGIN_BOTTOM" , 20); //class MYPDF extends TCPDF { class MYPDF extends Fpdi\TcpdfFpdi { // フッタのカスタマイズ(ページ番号を出力する) public function Footer() { $this->SetY(-15); // Position at 15 mm from bottom $this->SetFont('helvetica', 'I', 8); $this->Cell(0, 10, 'Page '.$this->getAliasNumPage().'/'.$this->getAliasNbPages(), 0, false, 'C', 0, '', 0, false, 'T', 'M'); } } $pdf = new MYPDF(MY_PDF_PAGE_ORIENTATION, MY_PDF_UNIT, MY_PDF_PAGE_FORMAT, true, 'UTF-8', false); $pdf->SetTitle('PDFテンプレートに値を埋め込むテスト'); $pdf->SetMargins(MY_PDF_MARGIN_LEFT, MY_PDF_MARGIN_TOP, MY_PDF_MARGIN_RIGHT); $pdf->SetAutoPageBreak(TRUE, MY_PDF_MARGIN_BOTTOM); $pdf->setPrintHeader(false); $pdf->setPrintFooter(true); $pdf->setImageScale(MY_PDF_IMAGE_SCALE_RATIO); $pdf->SetFont(MY_PDF_FONT_NAME, "", 10); $pdf->AddPage(); // テンプレート読み込んでページに適用 $pdf->setSourceFile('./template.pdf'); $pdf->useTemplate($pdf->importPage(1)); // 出力位置の調整が少し面倒 function printRow($pdf, $index, $cols){ $y = 31 + $index * 8; $posX = array(15, 75, 135); foreach ($cols as $i => $col) { $x = $posX[$i]; $pdf->SetXY($posX[$i], $y); $pdf->Write(0, $col); } } for ($i = 0; $i < 10; $i++) { $no = $i + 1; printRow($pdf, $i, array("test${no}-1", "test${no}-2", "test${no}-3")); } // 作成したPDFをブラウザに表示 $fileName = "use_template.pdf"; $pdf->Output($fileName, 'I'); //$data = $pdf->Output(null,'S'); // PDFデータだけ取得する場合 ?> |