TCPDF*フォームを使ってPHPでPDFを生成
@odysseyさんのおすすめPHP参考書。
PHP 逆引きレシピ (PROGRAMMER’S RECiPE)
の125項目「PDFファイルを生成したい」を参考に、請求書用フォーマットを作成中。
フォームから入力された値を拾って、表組みされるようにPDFで出力する。
最初に、TDPDFをインストールしてtcpdfをC:\xamppのhtdocs内に置き、form.phpを作成。
form.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>請求書作成フォーム</title> <link href="css/style.css" rel="stylesheet" type="text/css" /> </head> <body> <h1>必要項目を入力後に必ずボタンをクリックしてPDFを作成してください。 <!-- name属性から値を拾いますYO --> </h1> <p>必要事項入力後、合計金額を自動計算しPDF化します。</p> <form action="./ex.php" method="post"> <div id="Form"> <dl class="title"> 各項目の情報 </dl> <dl> <dt>請求書No. : </dt> <dd> 自動入力 </dd> </dl> <dl> <dt>請求日 : </dt> <dd> <input type="text" name="date" /> </dd> </dl> <dl> <dt>担当者名 : </dt> <dd> <input type="text" name="name" /> <input type="text" name="name2" /> 例 山田 花子</dd> </dl> <dl> <dt>希望支払い方法 : </dt> <dd> <select name="charge"> <option selected="selected">ご希望の支払い方法を選択してください</option> <option>銀行振込</option> <option>手渡し</option> <option>寄付</option> </select> </dd> </dl> <dl class="title"> 案件 1 </dl> <dl> <dt>クライアント様名 : </dt> <dd> <input type="text" name="client1" /> 様</dd> </dl> <dl> <dt>納品日 :</dt> <dd> <input name="overdate1" type="text" value="" /> 例 2011/08/22</dd> </dl> <dl> <dt class="details">内容 : </dt> <dd class="details"> <textarea name="detail1"></textarea> </dd> </dl> <dl> <dt>請求金額計算 : </dt> <dd> 単価 : <input name="unitprice1" type="text" class="form1" value="" /> ×数量 : <input name="count1" type="text" class="form1" value="" /> <select name="unit1"> <option selected="selected">単位</option> <option>ページ</option> <option>セット</option> <option>個</option> <option>つ</option> <option>本</option> <option>サイト</option> <option>点</option> <option>式</option> <option>枚</option> <option>時間</option> <option>日</option> <option>ヶ月</option> <option>年</option> <option>日</option> <option>人</option> <option>回</option> <option>箇所</option> </select> </dd> </dl> <dl> <dt>担当箇所 : </dt> <dd> <select name="deploy1"> <option selected="selected">担当分野を選択してください</option> <option>WEBデザイン</option> <option>バナー製作</option> <option>デザイン各パーツ製作</option> <option>PHP開発</option> <option>WordPressテーマ製作</option> <option>WordPressページ製作</option> <option>WordPressプラグイン製作</option> <option>WordPressテーマ事務的作業(商品登録など)</option> <option>SEO対策</option> <option>HTML</option> <option>コーディング全般</option> </select> </dd> </dl> <input type="submit" class="submit" value="請求書PDFを作成してみる" /> </div> </form> </body> </html>
こんな感じ。
これは、C:\xampp\htdocs\tcpdf\examplesの階層に置く。
サンプルPHPファイル群が入っているexamplesの中からexample_001.phpを開き、コピーしてex.phpにリネーム。
ex.php
// Set some content to print $html = <<<EOD <h1>Welcome to <a href="http://www.tcpdf.org" style="text-decoration:none;background-color:#CC0000;color:black;"> <span style="color:black;">TC</span><span style="color:white;">PDF</span> </a>!</h1> <i>This is the first example of TCPDF library.</i> <p>This text is printed using the <i>writeHTMLCell()</i> method but you can also use: <i>Multicell(), writeHTML(), Write(), Cell() and Text()</i>.</p> <p>Please check the source code documentation and other examples for further information.</p> <p style="color:#CC0000;">TO IMPROVE AND EXPAND TCPDF I NEED YOUR SUPPORT, PLEASE <a href="http://sourceforge.net/donate/index.php?group_id=128076">MAKE A DONATION!</a></p> EOD; // Print text using writeHTMLCell() $pdf->writeHTMLCell($w=0, $h=0, $x='', $y='', $html, $border=0, $ln=1, $fill=0, $reseth=true, $align='', $autopadding=true);
上記をごっそりコメントアウトして、
$pdf->MultiCell(50, 8, '請求日' , 1, 'L', 0, 0 ); $pdf->MultiCell(130, 8, $_POST['date'], 1, 'L', 0, 1 ); $pdf->MultiCell(50, 8, '担当者名' , 1, 'L', 0, 0 ); $pdf->MultiCell(65, 8, $_POST['name'], 1, 'L', 0, 0 ); $pdf->MultiCell(65, 8, $_POST['name2'], 1, 'L', 0, 1 ); $pdf->MultiCell(50, 8, '希望支払い方法' , 1, 'L', 0, 0 ); $pdf->MultiCell(130, 8, $_POST['charge'], 1, 'L', 0, 1 ); $pdf->Write(8, '' . "\n" ); $pdf->MultiCell(50, 8, 'クライアント様名' , 1, 'L', 0, 0 ); $pdf->MultiCell(65, 8, $_POST['client1'], 1, 'L', 0, 0 ); $pdf->MultiCell(20, 8, '納品日' , 1, 'L', 0, 0 ); $pdf->MultiCell(45, 8, $_POST['overdate1'], 1, 'L', 0, 1 ); $pdf->MultiCell(50, 8, '内容' , 1, 'L', 0, 0 ); $pdf->MultiCell(130, 8, $_POST['detail1' ], 1, 'L', 0, 1 ); $pdf->MultiCell(50, 8, '担当箇所' , 1, 'L', 0, 0 ); $pdf->MultiCell(130, 8, $_POST['deploy1' ], 1, 'L', 0, 1 ); $pdf->MultiCell(50, 8, '単価' , 1, 'L', 0, 0 ); $pdf->MultiCell(45, 8, $_POST['unitprice1' ], 1, 'L', 0, 0 ); $pdf->MultiCell(20, 8, '数量' , 1, 'L', 0, 0 ); $pdf->MultiCell(20, 8, $_POST['count1' ], 1, 'L', 0, 0 ); $pdf->MultiCell(20, 8, '単位' , 1, 'L', 0, 0 ); $pdf->MultiCell(25, 8, $_POST['unit1' ], 1, 'L', 0, 1 ); $pdf->MultiCell(50, 8, '請求金額' , 1, 'L', 0, 0 ); $pdf->MultiCell(130, 8, $_POST['unitprice1' ]*$_POST['count1' ] , 1, 'R', 0, 1 ); $pdf->Write(8, '' . "\n\n" );
を追加。
セットフォントは、小塚さんFONT(小塚ゴシックPro M)にしたいので、
ex.php
// Set font
// dejavusans is a UTF-8 Unicode font, if you only need to
// print standard ASCII chars, you can use core fonts like
// helvetica or times to reduce file size.
$pdf->SetFont('kozgopromedium', '', 14, '', true);
こうした。
tcpdfには予めいくつかの日本語FONTが入っているんだけど、
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
としても、文字化けしたので、30行目あたりの、
require_once('../config/lang/eng.php');
require_once('../tcpdf.php');
の下に、
mb_internal_encoding('UTF-8');
を追加して、文字化け解消。ちなみに、PHPは全部UTF-8で書いてました。
デフォルトでセットアップされているFONTは下記参照。
公式サイトの説明 TCPDF
- ・ Arial Uni CID0 (arialunicid0)
- ・ 小塚ゴシックPro M (kozgopromedium)
- ・ 小塚明朝Pro M (kozminproregular)
- ・ HYSMyeongJoStd-Medium (hysmyeongjostdmedium)
- ・ MSungStd-Light (msungstdlight)
- ・ STSongStd-Light (stsongstdlight)
請求金額を出すために、さっきのごっそりコメントアウトしてから追加したコードの中のこれ
$pdf->MultiCell(50, 8, '請求金額' , 1, 'L', 0, 0 ); $pdf->MultiCell(130, 8, $_POST['unitprice1' ]*$_POST['count1' ] , 1, 'R', 0, 1 );
['unitprice1' ](単価)で出た値と、$_POST['count1' ](数量)で出た値を*で掛けて請求合計金額を出す。
1PDFで1案件の請求書を生成するなら、これでOKだけど、1PDFで複数案件の小計金額&請求合計金額を出したいので、最終的に、下記のようにしました。
最大3案件の請求項目を追加。
form.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>請求書作成フォーム</title> <link href="css/style.css" rel="stylesheet" type="text/css" /> </head> <body> <h1>必要項目を入力後に必ずボタンをクリックしてPDFを作成してください。 <!-- name属性から値を拾いますYO --> </h1> <p>必要事項入力後、合計金額を自動計算しPDF化します。</p> <form action="./ex.php" method="post"> <div id="Form"> <dl class="title"> 各項目の情報 </dl> <dl> <dt>請求書No. : </dt> <dd> 自動入力 </dd> </dl> <dl> <dt>請求日 : </dt> <dd> <input type="text" name="date" /> </dd> </dl> <dl> <dt>担当者名 : </dt> <dd> <input type="text" name="name" /> <input type="text" name="name2" /> 例 山田 花子</dd> </dl> <dl> <dt>希望支払い方法 : </dt> <dd> <select name="charge"> <option selected="selected">ご希望の支払い方法を選択してください</option> <option>銀行振込</option> <option>手渡し</option> <option>寄付</option> </select> </dd> </dl> <dl class="title"> 案件 1 </dl> <dl> <dt>クライアント様名 : </dt> <dd> <input type="text" name="client1" /> 様</dd> </dl> <dl> <dt>納品日 :</dt> <dd> <input name="overdate1" type="text" value="" /> 例 2011/08/22</dd> </dl> <dl> <dt class="details">内容 : </dt> <dd class="details"> <textarea name="detail1"></textarea> </dd> </dl> <dl> <dt>請求金額計算 : </dt> <dd> 単価 : <input name="unitprice1" type="text" class="form1" value="" /> ×数量 : <input name="count1" type="text" class="form1" value="" /> <select name="unit1"> <option selected="selected">単位</option> <option>ページ</option> <option>セット</option> <option>個</option> <option>つ</option> <option>本</option> <option>サイト</option> <option>点</option> <option>式</option> <option>枚</option> <option>時間</option> <option>日</option> <option>ヶ月</option> <option>年</option> <option>日</option> <option>人</option> <option>回</option> <option>箇所</option> </select> </dd> </dl> <dl> <dt>担当箇所 : </dt> <dd> <select name="deploy1"> <option selected="selected">担当分野を選択してください</option> <option>WEBデザイン</option> <option>バナー製作</option> <option>デザイン各パーツ製作</option> <option>PHP開発</option> <option>WordPressテーマ製作</option> <option>WordPressページ製作</option> <option>WordPressプラグイン製作</option> <option>WordPressテーマ事務的作業(商品登録など)</option> <option>SEO対策</option> <option>HTML</option> <option>コーディング全般</option> </select> </dd> </dl> <dl class="title"> 案件 2 </dl> <dl> <dt>クライアント様名 : </dt> <dd> <input type="text" name="client2" /> 様</dd> </dl> <dl> <dt>納品日 :</dt> <dd> <input name="overdate2" type="text" value="" /> 例 2011/08/22</dd> </dl> <dl> <dt class="details">内容 : </dt> <dd class="details"> <textarea name="detail2"></textarea> </dd> </dl> <dl> <dt>請求金額計算 : </dt> <dd> 単価 : <input name="unitprice2" type="text" class="form1" value="" /> ×数量 : <input name="count2" type="text" class="form1" value="" /> <select name="unit2"> <option selected="selected">単位</option> <option>ページ</option> <option>セット</option> <option>個</option> <option>つ</option> <option>本</option> <option>サイト</option> <option>点</option> <option>式</option> <option>枚</option> <option>時間</option> <option>日</option> <option>ヶ月</option> <option>年</option> <option>日</option> <option>人</option> <option>回</option> <option>箇所</option> </select> </dd> </dl> <dl> <dt>担当箇所 : </dt> <dd> <select name="deploy2"> <option selected="selected">担当分野を選択してください</option> <option>WEBデザイン</option> <option>バナー製作</option> <option>デザイン各パーツ製作</option> <option>PHP開発</option> <option>WordPressテーマ製作</option> <option>WordPressページ製作</option> <option>WordPressプラグイン製作</option> <option>WordPressテーマ事務的作業(商品登録など)</option> <option>SEO対策</option> <option>HTML</option> <option>コーディング全般</option> </select> </dd> </dl> <dl class="title"> 案件 3 </dl> <dl> <dt>クライアント様名 : </dt> <dd> <input type="text" name="client3" /> 様</dd> </dl> <dl> <dt>納品日 :</dt> <dd> <input name="overdate3" type="text" value="" /> 例 2011/08/22</dd> </dl> <dl> <dt class="details">内容 : </dt> <dd class="details"> <textarea name="detail3"></textarea> </dd> </dl> <dl> <dt>請求金額計算 : </dt> <dd> 単価 : <input name="unitprice3" type="text" class="form1" value="" /> ×数量 : <input name="count3" type="text" class="form1" value="" /> <select name="unit3"> <option selected="selected">単位</option> <option>ページ</option> <option>セット</option> <option>個</option> <option>つ</option> <option>本</option> <option>サイト</option> <option>点</option> <option>式</option> <option>枚</option> <option>時間</option> <option>日</option> <option>ヶ月</option> <option>年</option> <option>日</option> <option>人</option> <option>回</option> <option>箇所</option> </select> </dd> </dl> <dl> <dt>担当箇所 : </dt> <dd> <select name="deploy3"> <option selected="selected">担当分野を選択してください</option> <option>WEBデザイン</option> <option>バナー製作</option> <option>デザイン各パーツ製作</option> <option>PHP開発</option> <option>WordPressテーマ製作</option> <option>WordPressページ製作</option> <option>WordPressプラグイン製作</option> <option>WordPressテーマ事務的作業(商品登録など)</option> <option>SEO対策</option> <option>HTML</option> <option>コーディング全般</option> </select> </dd> </dl> <input type="submit" class="submit" value="請求書PDFを作成してみる" /> </div> </form> </body> </html>
ex.php
<?php
~省略~
require_once('../config/lang/eng.php');
require_once('../tcpdf.php');
mb_internal_encoding('UTF-8');
// create new PDF document
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
// set document information
// $pdf->SetCreator(PDF_CREATOR);
// $pdf->SetAuthor('Nicola Asuni');
// $pdf->SetTitle('TCPDF Example 001');
// $pdf->SetSubject('TCPDF Tutorial');
// $pdf->SetKeywords('TCPDF, PDF, example, test, guide');
// set default header data
//$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE.' 001', PDF_HEADER_STRING);
// set header and footer fonts
$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
//set margins
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
//set auto page breaks
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
//set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
//set some language-dependent strings
$pdf->setLanguageArray($l);
// ---------------------------------------------------------
// set default font subsetting mode
$pdf->setFontSubsetting(true);
// Set font
// dejavusans is a UTF-8 Unicode font, if you only need to
// print standard ASCII chars, you can use core fonts like
// helvetica or times to reduce file size.
$pdf->SetFont('kozgopromedium', '', 14, '', true);
// Add a page
// This method has several options, check the source code documentation for more information.
$pdf->AddPage();
$pdf->Write(20, '請求書' . "\n" );
$pdf->Write(8, '***宛て' . "\n" . '下記の通りご請求申し上げます。'. "\n");
$pdf->Ln(10);
$pdf->MultiCell(50, 8, '請求日' , 1, 'L', 0, 0 );
$pdf->MultiCell(130, 8, $_POST['date'], 1, 'L', 0, 1 );
$pdf->MultiCell(50, 8, '担当者名' , 1, 'L', 0, 0 );
$pdf->MultiCell(65, 8, $_POST['name'], 1, 'L', 0, 0 );
$pdf->MultiCell(65, 8, $_POST['name2'], 1, 'L', 0, 1 );
$pdf->MultiCell(50, 8, '希望支払い方法' , 1, 'L', 0, 0 );
$pdf->MultiCell(130, 8, $_POST['charge'], 1, 'L', 0, 1 );
$pdf->Write(8, '' . "\n" );
$pdf->MultiCell(50, 8, 'クライアント様名' , 1, 'L', 0, 0 );
$pdf->MultiCell(65, 8, $_POST['client1'], 1, 'L', 0, 0 );
$pdf->MultiCell(20, 8, '納品日' , 1, 'L', 0, 0 );
$pdf->MultiCell(45, 8, $_POST['overdate1'], 1, 'L', 0, 1 );
$pdf->MultiCell(50, 8, '内容' , 1, 'L', 0, 0 );
$pdf->MultiCell(130, 8, $_POST['detail1' ], 1, 'L', 0, 1 );
$pdf->MultiCell(50, 8, '担当箇所' , 1, 'L', 0, 0 );
$pdf->MultiCell(130, 8, $_POST['deploy1' ], 1, 'L', 0, 1 );
$pdf->MultiCell(50, 8, '単価' , 1, 'L', 0, 0 );
$pdf->MultiCell(45, 8, $_POST['unitprice1' ], 1, 'L', 0, 0 );
$pdf->MultiCell(20, 8, '数量' , 1, 'L', 0, 0 );
$pdf->MultiCell(20, 8, $_POST['count1' ], 1, 'L', 0, 0 );
$pdf->MultiCell(20, 8, '単位' , 1, 'L', 0, 0 );
$pdf->MultiCell(25, 8, $_POST['unit1' ], 1, 'L', 0, 1 );
$pdf->MultiCell(50, 8, '請求金額' , 1, 'L', 0, 0 );
$pdf->MultiCell(130, 8, $_POST['unitprice1' ]*$_POST['count1' ] , 1, 'R', 0, 1 );
$pdf->Write(8, '' . "\n" );
$pdf->MultiCell(50, 8, 'クライアント様名' , 1, 'L', 0, 0 );
$pdf->MultiCell(65, 8, $_POST['client2'], 1, 'L', 0, 0 );
$pdf->MultiCell(20, 8, '納品日' , 1, 'L', 0, 0 );
$pdf->MultiCell(45, 8, $_POST['overdate2'], 1, 'L', 0, 1 );
$pdf->MultiCell(50, 8, '内容' , 1, 'L', 0, 0 );
$pdf->MultiCell(130, 8, $_POST['detail2' ], 1, 'L', 0, 1 );
$pdf->MultiCell(50, 8, '担当箇所' , 1, 'L', 0, 0 );
$pdf->MultiCell(130, 8, $_POST['deploy2' ], 1, 'L', 0, 1 );
$pdf->MultiCell(50, 8, '単価' , 1, 'L', 0, 0 );
$pdf->MultiCell(45, 8, $_POST['unitprice2' ], 1, 'L', 0, 0 );
$pdf->MultiCell(20, 8, '数量' , 1, 'L', 0, 0 );
$pdf->MultiCell(20, 8, $_POST['count2' ], 1, 'L', 0, 0 );
$pdf->MultiCell(20, 8, '単位' , 1, 'L', 0, 0 );
$pdf->MultiCell(25, 8, $_POST['unit2' ], 1, 'L', 0, 1 );
$pdf->MultiCell(50, 8, '請求金額' , 1, 'L', 0, 0 );
$pdf->MultiCell(130, 8, $_POST['unitprice2' ]*$_POST['count1' ] , 1, 'R', 0, 1 );
$pdf->Write(8, '' . "\n" );
$pdf->MultiCell(50, 8, 'クライアント様名' , 1, 'L', 0, 0 );
$pdf->MultiCell(65, 8, $_POST['client3'], 1, 'L', 0, 0 );
$pdf->MultiCell(20, 8, '納品日' , 1, 'L', 0, 0 );
$pdf->MultiCell(45, 8, $_POST['overdate3'], 1, 'L', 0, 1 );
$pdf->MultiCell(50, 8, '内容' , 1, 'L', 0, 0 );
$pdf->MultiCell(130, 8, $_POST['detail3' ], 1, 'L', 0, 1 );
$pdf->MultiCell(50, 8, '担当箇所' , 1, 'L', 0, 0 );
$pdf->MultiCell(130, 8, $_POST['deploy3' ], 1, 'L', 0, 1 );
$pdf->MultiCell(50, 8, '単価' , 1, 'L', 0, 0 );
$pdf->MultiCell(45, 8, $_POST['unitprice3' ], 1, 'L', 0, 0 );
$pdf->MultiCell(20, 8, '数量' , 1, 'L', 0, 0 );
$pdf->MultiCell(20, 8, $_POST['count3' ], 1, 'L', 0, 0 );
$pdf->MultiCell(20, 8, '単位' , 1, 'L', 0, 0 );
$pdf->MultiCell(25, 8, $_POST['unit3' ], 1, 'L', 0, 1 );
$pdf->MultiCell(50, 8, '請求金額' , 1, 'L', 0, 0 );
$pdf->MultiCell(130, 8, $_POST['unitprice3' ]*$_POST['count1' ] , 1, 'R', 0, 1 );
$pdf->Write(8, '' . "\n\n" );
$pdf->MultiCell(50, 8, '請求合計金額' , 1, 'L', 0, 0 );
$pdf->MultiCell(130, 8, $_POST['unitprice1' ]*$_POST['count1' ]+$_POST['unitprice2' ]*$_POST['count2' ]+$_POST['unitprice3' ]*$_POST['count3' ] , 1, 'R', 0, 1 );
// Print text using writeHTMLCell()
//$pdf->writeHTMLCell($w=0, $h=0, $x='', $y='', $html, $border=0, $ln=1, $fill=0, $reseth=true, $align='', $autopadding=true);
// ---------------------------------------------------------
// Close and output PDF document
// This method has several options, check the source code documentation for more information.
$pdf->Output('example_001.pdf', 'I');
//============================================================+
// END OF FILE
//============================================================+
綺麗な書き方でないので直してください汗。一部表現のおかしいところもあるので、そこも直してくださいね。