SQLの窓 イラストAC フリー素材

2014年09月28日

TCPDF + FPDI : PHP で既存 PDF を読み込んで加工してブラウザに送る

8年の月日が流れましたが、FPDFTCPDF に変えても、FPDI が自動的に全て処理するので、TCPDF のプラグインのような形で動作します。

▼ main ではこんなかんじ
require_once("../common/tcpdf_include.php");
require_once("../../fpdi/fpdi.php");
require_once("../common/common.php");
require_once("model.php");
<?php
// ***********************************************
//
//  部   品   名 : モデル
//  プログラム名 : 社員一覧印刷
//  作   成   者 : lightbox
//  作   成   日 : 2014/06/06
//
//  概要 : 
//  印刷処理の為のテンプレート
//  ここでは、プログラム固有の処理を定義します
//
// ***********************************************

// ***********************************************
// データベース読み出し
// ***********************************************
function query() {

	global $connect,$row,$SEARCH_DATA;

	$pdf = new FPDI(
		"L",
		PDF_UNIT,
		"A4",
		true,
		"UTF-8",
		false,
		false		// PDF/A モード
	);

	# PDF を読み込んでページ数を得る
	$pagecount = $pdf->setSourceFile("Book1.pdf");
	# ページ番号より ID を取得する
	$tplidx = $pdf->ImportPage(1);
	//**********************************************************
	// 設定
	//**********************************************************
	$pdf->setFontSubsetting(false);
	$pdf->setPrintHeader(false);
	$pdf->setPrintFooter(false);
	$pdf->SetFont('meiryo001', '', 12);
	// デフォルトが true なので、デバッグ時に混乱しないように false に設定
	$pdf->SetAutoPageBreak(false);

	$pdf->AddPage();
	// テンプレートの適用
	$pdf->useTemplate($tplidx);
	// AddPage 実行後に取得する

	$query = apply_value("select.sql");
	$result = $connect->query($query); 

	$counter = 0;

	$cur_position = print_header( $pdf );
	while ($row = $result->fetch_array(MYSQLI_BOTH)) {

		$counter++;
		if ( $counter > 20 ) {
			$counter = 0;
			$pdf->AddPage();
			// テンプレートの適用
			$pdf->useTemplate($tplidx);
			$cur_position = print_header( $pdf );
		}

		user_text( $pdf, 10, $cur_position, $row['社員コード'] );
		user_text( $pdf, 28, $cur_position, $row['氏名'] );

		$cur_position = user_text( $pdf, 63, $cur_position, number_format($row['給与']), 20, 0, "R" );

	}

	// ブラウザへ PDF を出力します
	$pdf->Output("syain.pdf", "I");

	// 実際の SQL の結果の情報を返します
	return $result;

}

// ***********************************************
// ヘッダ印字
// ***********************************************
function print_header( $pdf ) {

	$page_info = $pdf->getPageDimensions();
	$cur_position = $page_info['tm'];	// トップマージン

	$cur_position = user_text( $pdf, 125, $cur_position, "社員マスター一覧表" );
	$cur_position = user_text( $pdf, 0, $cur_position, "" );
	user_text( $pdf, 10, $cur_position, "コード" );
	user_text( $pdf, 28, $cur_position, "名前" );
	$cur_position = user_text( $pdf, 63, $cur_position, "給与", 20, 0, "R" );

	return $cur_position;

}

?>

TCPDF で動作している場合 FPDI を 読み込んで、TCPDF クラス をそのまま FPDI クラスに変更し、既存 PDF を読み込んで、AddPage する毎にテンプレート使用( $pdf->useTemplate($tplidx) ) を実行するだけです。

本来の目的であるフォームのオーバーレイを想定して、枠線だけを持つ PDF を Microsoft Excel で作成して重ねました。

実行結果

FPDI のドキュメントはこちらを参照

▼ 以下は TCPDF 用の実行環境設定用のファイルです( require_once します )
<?php
// Include the main TCPDF library (search for installation path).
$path = "C:\user\web\tcpdf";
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
require_once('examples/config/tcpdf_config_alt.php');
require_once('tcpdf.php');
?>


▼ 以下は、印字用の関数です( 今回の FPDI に関するでページあふれ対応はしていません )
# **********************************************************
#  テキスト印字
# **********************************************************
function user_text( $pdf, $x, $y, $text, $w=1, $h=0, $p="L" ) {

	text( $pdf, $x, $y, $text, $w, $h, $p );

	return $y;

}

# **********************************************************
# 位置指定印字
# ※ 改行コードで自動改行
# ※ ページあふれで自動改ページ
# ※ 内部印字位置は保存( 元に戻す )
# **********************************************************
function text( $pdf, $x=0, &$y=0, $txt='', $w=1, $h=0, $p="L" ) {

	$a = $pdf->GetX();
	$b = $pdf->GetY();

	$hm = $pdf->getPageHeight( );
	$dm = $pdf->getPageDimensions();
	$tm = $dm['tm'];
	$bm = $dm['bm'];

	$txt = str_replace( "\r","", $txt );
	$data = explode("\n", $txt );
	if ( count( $data ) > 1 ) {
		for( $i = 0; $i < count($data); $i++ ) {
			if ( $i == 0 ) {
				$pdf->SetXY( $x, $y );
			}
			else {
				$y += $pdf->getLastH();
				if ( $y >= ( $hm - $tm - $bm ) ) {
					$pdf->AddPage();
					$y = $tm;
				}
				$pdf->SetXY( $x, $y );
			}
			$pdf->Cell($w, $h, $data[$i], 0, 0, $p);
		}
	}
	else {
		$pdf->SetXY( $x, $y );
		$pdf->Cell($w, $h, $txt, 0, 0, $p);
	}
	$y += $pdf->getLastH();

	$pdf->SetXY($a,$b);

}
TCPDF に関しては、『TCPDFマニュアル(勝手訳)』といのが検索するとすぐ見つかります。これでほぼ OK です。



関連する記事

TCPDF で非埋め込み型として『メイリオ』を使う手順



▼ 以下は古い記事です
2006-11-26 の記事
PDF は、基本ブラウザに埋め込まれるので、Webアプリの印刷処理として最適です。

多少制限もありますが普通に日本語使えますし。知らないと損しますね。

詳細は↓
http://winofsql.jp/VA003334/phpVarious061126183640.htm


一つのパッケージでは無いので構成するのにそれなりの知識が必要になります。ソースも少し書き換えが発生します。

既存のPDF 利用の部分は日本語マニュアル無いみたいですし・・・
でもまあ、プログラマなら理解できる程度の英語です。


posted by at 2014-09-28 01:15 | PHP+PDF | このブログの読者になる | 更新情報をチェックする

2013年03月16日

TCPDF : getPageDimensions の中身

getPageDimensions は、ページ数を引数に取れますが、とりあえず省略して 
$dm = $pdf->getPageDimensions();
file_put_contents("log.txt", print_r($dm,true)); 
で出力しました。 処理としては、上下余白サイズをページの縦サイズから差し引いて座標して行く為です。
Array
(
    [MediaBox] => Array
        (
            [llx] => 0
            [lly] => 0
            [urx] => 595.276
            [ury] => 841.89
        )

    [CropBox] => Array
        (
            [llx] => 0
            [lly] => 0
            [urx] => 595.276
            [ury] => 841.89
        )

    [BleedBox] => Array
        (
            [llx] => 0
            [lly] => 0
            [urx] => 595.276
            [ury] => 841.89
        )

    [TrimBox] => Array
        (
            [llx] => 0
            [lly] => 0
            [urx] => 595.276
            [ury] => 841.89
        )

    [ArtBox] => Array
        (
            [llx] => 0
            [lly] => 0
            [urx] => 595.276
            [ury] => 841.89
        )

    [Rotate] => 0
    [PZ] => 1
    [w] => 595.276
    [h] => 841.89
    [wk] => 210.00014444444
    [hk] => 297.00008333333
    [tm] => 10.00125
    [bm] => 20.0025
    [lm] => 10.00125
    [rm] => 10.00125
    [pb] => 1
    [or] => P
    [olm] => 10.00125
    [orm] => 10.00125
)

利用サンプルソースコード



posted by at 2013-03-16 04:12 | PHP+PDF | このブログの読者になる | 更新情報をチェックする

2010年06月27日

TCPDF利用前の注意事項

サンプルとして付属している日本語は非埋め込み型

Arial Uni CID0 (arialunicid0) は、フォント本体が PC にあって、定義ファイルは
arialunicid0.php 一つのみです。
そもそも、arialunicid0.php が日本語定義ファイルのサンプルですので中を見ると
多少ですが説明があります。全ての説明は README を見る必要があります。

小塚ゴシックPro M (kozgopromedium) と 小塚明朝Pro M (kozminproregular) は
Adobe のフォントです。定義ファイルもそれぞれ一つづつな上に、中を見てもフォ
ントデータを参照している様子もありません。おそらく、非埋め込み型なのだと思
います( 少なくともファイルサイズ的には非埋め込み型です )


日本語にイタリック等は実装されていない

小塚ゴシックPro M (kozgopromedium) と 小塚明朝Pro M (kozminproregular) は
日本語以外はイタリックになりますが、他のフォントはそもそもその書体が無い
はずなので、利用できません。ですから、定義ファイルもそれぞれ一つだけです。


通常の MS フォントを実装するには

MS ゴシック、MS Pゴシック、MS UIゴシック、MS 明朝、MS P明朝
が一番欲しいです。特に印刷処理ですから、MS 明朝が必要です。
手作業はたいへんなので、全自動のスクリプトを作成しました


VBScript : TCPDFで MSフォントが使えるようにする全自動スクリプト
元々利用可能なフォントに加えて、MSフォントの印字サンプルです Cellの印字サンプル これは初心者向きで、適当にやっても表が作成できます PHP : TCPDF の Cell で一覧表を印字するサンプル 位置指定で右寄せ可能なサンプル cell メソッドの応用ですが、これが無いと業務用の印字は無理です。 PHP : TCPDF の Cell を使って位置指定印字を行うサンプル 関連する記事
TCPDFに関する3つの誤解
posted by at 2010-06-27 15:15 | PHP+PDF | このブログの読者になる | 更新情報をチェックする

2010年06月17日

TCPDF:固定ピッチフォントが無いようなので、位置指定でCell出力

現在の位置を保存しておいて、SetXY メソッドで強制的に座標変更して
Cell の枠なしで幅内で右詰めします。Cell は同時に罫線印字するのに便利
ですが、実際は既存のフォームに位置合わせする必要がありますし、固定ピッチ
のフォントで可能な文字単位の位置合わせの代替えとして利用できます。

現在の位置を保存するのは、通常の Cell 印字と混在して正しく動作させる為に、
位置指定した出力の終了後に元へ戻す為です。
$a = $pdf->GetX();
$b = $pdf->GetY();

$pdf->SetXY(0,0);
$pdf->Cell(15,5,'1,234',1,0,'L');

$pdf->SetXY(0,5);
$pdf->Cell(15,5,'1,234',1,0,'R');

// 幅が足りない、かつ左詰め
$pdf->SetXY(15,10);
$pdf->Cell(2,5,'1,234',1,0,'L');

// 幅が足りない、かつ右詰め
$pdf->SetXY(40,10);
$pdf->Cell(2,5,'1,234',1,0,'R');

// 高さが足りない
$pdf->SetXY(55,10);
$pdf->Cell(15,1,'1,234',1,0,'R');

$pdf->SetXY($a,$b);
上記コードの実行結果

※ Cell の高さは、実際に必要な高さより小さい場合は無視されます。



posted by at 2010-06-17 15:02 | PHP+PDF | このブログの読者になる | 更新情報をチェックする

2008年08月26日

【PHP】SHIFT_JISに無い文字を画像変換後FPDFで表示する



いっこ前の、  【PDF処理 -- PHP】 FPDF v1.6 + FPDI 日本語利用詳細 

の延長で、本来業務的にやりたかった事の内容が完成しました。
あとは、実装・・・明日やる予定

以下は、SHIFT_JIS に無いので、Unicode に対応していないアプリでは、
? としか表示されない文字の例です( データとして欠落します )。
但し、MS ゴシックを使っているのでフォントには存在しています。
ですから、画像には変換できるはずなので、PHP + FPDF での実装をテストしてみます。

No_shift_jis

※ ↓ IE6 以外のブラウザならきちんと表示されると思います

Ѽ,⅓,Ⓐ,〠,㏾



posted by at 2008-08-26 16:51 | PHP+PDF | このブログの読者になる | 更新情報をチェックする

2008年08月25日

【PDF処理--PHP】FPDFv1.6+FPDI日本語利用詳細



FPDF が 8月の最初にバージョンアツプされたので、動作確認を兼ねてまとめようとした時に、どうしてもフォントの名前( ポストスクリプト名 ) に関して記述したくて 【Java】PCのフォント一覧とポストスクリプト名からJTableの標準化 のほうへ路線が変わってたのが、やっと戻って来て完成です。

以前まとめた内容よりも現在時点で、事実変わっていますし、その時書かなかった情報もぜんぶ吐き出しました

今さっき英文フォントを使う為の面倒な手順を調査終了しました。Windows ユーザは大変です・・・が、普通使わないので無視するといいでしょう。ただ、理屈は知っておかないと、Font が命の業種もありますから、システム屋として、その時どうにかできる情報は持っておくべきです。

後は、印字用のパッケージ化ですが・・・

当分優先順位低いです。






posted by at 2008-08-25 17:13 | PHP+PDF | このブログの読者になる | 更新情報をチェックする

2007年07月06日

PHPでPDF出力(FPDF)

直接印刷処理ではありませんが、WEB 上で使えば立派に印刷の代替処理になります。

php.exe print_pdf.php
<?php
# ******************************
# FPDF を使用しています
# ******************************
require("http://homepage2.nifty.com/lightbox/phppdf/japanese.php");

$GLOBALS['margin'] = 5;

# ポートレイト、単位(ミリメートル)、サイズA4
$pdf = new PDF_Japanese( 'P', 'mm', 'A4' );

# 使えそうなマシンにインストール済みのフォント名
# ( GIMP で調べました )
$pdf->AddSJISFont("HGSoeiKakupoptai");

# 2ページぶんの処理
for( $page = 0; $page < 2; $page++ ) {

	# ページ追加
	$pdf->AddPage();
	# 塗りつぶす為の色
	$pdf->SetFillColor( 200, 230, 185 );

	# タイトル印字
	$pdf->SetFont('SJIS','B',20);
	$text = 'PHP 印字テスト';
	$pdf->Text( $GLOBALS['margin'], 13.5, $text );

	# 通常印字フォント
	$pdf->SetFont('SJIS','',10);

	for( $i = 1; $i <= 20; $i++ ) {

		$pdf->SetX( $GLOBALS['margin'] );
		$pdf->SetY( ( $i-1 ) * 8 + 40 );
		$pdf->SetTextColor( 0, 0, 0 );
		# 幅、高さ、印刷文字列、罫線あり、不要、センタリング、色を塗る
		$pdf->Cell( 100, 6, "$i 行", 1, 0, 'C', 1 );

	}
}

# 書き込み
$pdf->Output("print.pdf");

# ******************************
# Windows 経由の 外部実行
# ******************************
$WshShell = new COM("WScript.Shell");
$command = "RunDLL32.EXE shell32.dll,ShellExec_RunDLL ";
$command .= ""print.pdf"";
$WshShell->Run( $command, 1, TRUE );

print "処理が終了しました\n";

?>




posted by at 2007-07-06 21:15 | PHP+PDF | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します