SQLの窓

2016年11月22日


1会話・IFRAME(TCPDF)テンプレート : jQuery + Bootstrap(css) + mmenu + Firebase + TCPDF + PHP

デモページ




▼ このプラグインを使用して、ヘッダ部分で条件入力して PDF をその下の IFRAME へ表示するテンプレートです。
かつての FRAME のように画面下部に張り付く IFRAME を実装する jQuery プラグイン

全体の表示部分のテンプレート部分は、jQuery + Bootstrap(css) + mmenu で構成されており、独自の仕様ではありますが、見ればだいたい解るようには作成してあります。

アプリケーション部分

データ部分 : Firebase
PDF部分 : TCPDF
処理部分 : PHP

となっており、Firebase は PHP から直接読み込む必要があるので、Firebase Database REST API を使用しています。

TCPDF は文字列印字部分をユーザ関数化して、昔ながらの印刷用アルゴリズムで出力しています。

TCPDF 関数部分 : print.php
<?php
define ('K_PATH_FONTS', "tcpdf/");
require_once('tcpdf/tcpdf.php');

// ************************************************
//   P or PORTRAIT(縦:既定)
//   L or LANDSCAPE(横))
// ---------------------------
//   pt: ポイント
//   mm: mm(既定)
//   cm: cm
//   in: インチ
// ---------------------------
//   用紙サイズ
// ---------------------------
// boolean $unicode = true
// ---------------------------
// String $encoding = 'UTF-8'
// ---------------------------
// boolean $diskcache = false
// ---------------------------
// PDF/A モード
// ---------------------------
// 
// 全てデフォルトなので $pdf = new TCPDF("L") でもOK
// ************************************************
$pdf = new TCPDF("L");
/*
$pdf = new TCPDF(
	"L",
	"mm",
	"A4",
	true,
	"UTF-8",
	false,
	false
);
*/

// ************************************************
// 設定
// ************************************************
$pdf->setFontSubsetting(false);
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->SetAutoPageBreak(false);


// ************************************************
// デバッグ用ログ
// ************************************************
function log_out( $text ) {

	// クリア
	if ( $text == null ) {
		file_put_contents("log.txt","");
		return;
	}

	// 書き込み
	file_put_contents("log.txt", $text . "\n", FILE_APPEND );

}

// ************************************************
//  テキスト印字
// $p は L で左揃え、R で右揃え
// $w : 矩形領域の幅(1だと最低幅) : 右揃えに必要
// $h : 矩形領域の高さ
// http://tcpdf.penlabo.net/method/c/Cell.html
// ************************************************
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 で非埋め込み型として『メイリオ』を使う手順

フォントファイルは、define ('K_PATH_FONTS', "tcpdf/"); で指定した場所です。
※ MSゴシックとMS明朝も同梱しています。

印刷用アルゴリズム部分
<?php
// ************************************************
// セッションとキャッシュなし
// ************************************************
session_cache_limiter('nocache');
session_start();

// ************************************************
// 印字関数
// ************************************************
require_once("print.php");

log_out(null);
$rh		= 8;	// 行間の距離
$hh		= 40;	// ヘッダーの下の次の印字位置
$rmax	= 15;	// ページ内の最大明細行数
// ************************************************
// フォント
// 第二引数は フォント・スタイル(空文字で標準)
// http://tcpdf.penlabo.net/method/s/SetFont.html
// ************************************************
$pdf->SetFont('meiryo001', '', 14);

$pdf->AddPage();

// ************************************************
// データベース
// ※ パスの先にデータが無い事は考慮していない
// ************************************************
$url = "https://freebase-654b7.firebaseio.com/class.json";
$file = @file_get_contents($url);
if ( $file !== false ) {
	// 連想配列形式で返す
	$result = json_decode( $file, true );

	if ( $result == null ) {
		// テキストのサイズ変更
		$pdf->SetFont('meiryo001', '', 20);
		// テキストの色
		$pdf->SetTextColor(255, 0, 0);
		user_text( $pdf, 10, 10, 'データが存在しません' );
		$pdf->Output("test_output.pdf", "I");
		exit();
	}

}

$url = "https://freebase-654b7.firebaseio.com/refdata/syozoku.json";
$file = @file_get_contents($url);
if ( $file !== false ) {
	$syozoku = json_decode( $file, true );

	// log_out(print_r($syozoku,true));

	if ( $syozoku == null ) {
		$syozoku = json_decode( '{"0001":"営業部第一","0002":"技術開発","0003":"人事部"}', true );
	}
}

// ************************************************
// 印刷用変数
// ************************************************
$counter = 0;	// ページ用カウンタ
$lcount = 0;	// 行数カウンタ
$sum = 0;		// ページ毎合計
$sumall = 0;	// 総合計

// 最初のヘッダーを出力して現在位置(y)を取得
$cur_position = print_header( $pdf );

// ************************************************
// 処理ループ
// ************************************************
foreach( $result as  $key => $obj ) {

	if ( $_GET['fld1'] != '' ) {
		if ( mb_strpos($obj["name"],$_GET['fld1'],0,"utf-8") === false ) {
			continue;
		}
	}

	$lcount++;
	if ( $lcount > $rmax ) {
		$counter++;
		$lcount = 0;
		user_text( $pdf, 108, $cur_position, "ページ計" );
		user_text( $pdf, 138, $cur_position, number_format($sum), 20, 0, "R" );
		$sum = 0;

		// 新しいページ
		$pdf->AddPage();
		$cur_position = print_header( $pdf );
	}

	user_text( $pdf, 10, $cur_position, $obj["code"] );
	user_text( $pdf, 28, $cur_position, $obj["name"] );
	user_text( $pdf, 51, $cur_position, $obj["furi"] );
	user_text( $pdf, 95, $cur_position, $syozoku[$obj["syozoku"]] );
	if ( $obj["sex"] == "0" ) {
		$pdf->Image("man.png", 125+3.2, $cur_position, 5, 5);
	}
	else {
		$pdf->Image("lady.png", 125+3.2, $cur_position, 5, 5);
	}
	user_text( $pdf, 138, $cur_position, number_format($obj["kyuyo"]), 20, 0, "R" );
	$sum += $obj["kyuyo"];
	$sumall += $obj["kyuyo"];

	// 手当ては文字列として設計されているので数値化
	user_text( $pdf, 163, $cur_position, number_format($obj["teate"]+0), 20, 0, "R" );
	user_text( $pdf, 183, $cur_position, $obj["birthday"] );

	$cur_position += $rh;

}

// ************************************************
// 最大行数が、最後の2行が入るように想定されて
// いるので、以下は無条件に出力する
// ************************************************

user_text( $pdf, 108, $cur_position, "ページ計" );
user_text( $pdf, 138, $cur_position, number_format($sum), 20, 0, "R" );

// 次の行
$cur_position += $rh;
user_text( $pdf, 108, $cur_position, "総合計" );
user_text( $pdf, 138, $cur_position, number_format($sumall), 20, 0, "R" );


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

// デバッグ用
file_put_contents( "../log/global.txt", print_r($GLOBALS, true) );
//file_put_contents( "../log/global.txt", "[_GET]\n".print_r($_GET, true)."\n"."[_POST]\n".print_r($_POST, true)."\n"."[_COOKIE]\n".print_r($_COOKIE, true)."\n"."[_SESSION]\n".print_r($_SESSION, true) );

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

	global $counter;

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

	user_text( $pdf, 125, $cur_position, "社員一覧表" );
	user_text( $pdf, 224, $cur_position, "ページ :" );
	user_text( $pdf, 250, $cur_position, number_format($counter+1), 5, 0, "R" );

	// 2行
	$cur_position += $GLOBALS['rh'] * 2;
	user_text( $pdf, 10, $cur_position, "コード" );
	user_text( $pdf, 28, $cur_position, "名前" );

	user_text( $pdf, 51, $cur_position, "フリガナ" );
	user_text( $pdf, 95, $cur_position, "所属" );
	user_text( $pdf, 125, $cur_position, "性別" );

	user_text( $pdf, 138, $cur_position, "給与", 20, 0, "R" );
	user_text( $pdf, 163, $cur_position, "手当", 20, 0, "R" );
	user_text( $pdf, 183, $cur_position, "生年月日" );

	$cur_position += $GLOBALS['rh'];

	// 直線のスタイル
	$pdf->SetLineStyle(
		array(
			'width' => 0.4,
			'cap' => 'round',
			'join' => 'round',
			'dash' => 0,
			'color' => array(0xFF,0xC0,0xCB)	// pink
		)
	);
	// 直線
	$pdf->Line(
		$page_info['lm'],	// 左マージン
		$cur_position+1.5,
		$page_info['wk']-$page_info['lm']-$page_info['rm'],	// ページ幅 - 左右マージン
		$cur_position+1.5);
	
	return $GLOBALS['hh'];

}
?>

いろいろなページを構成する定数を元に、ヘッダと明細部分を分けてコントロールするオーソドックスなものです。改ページは、次に印字すべき位置があらかじめ決めた行数を超えた時に処理され、次のページの先頭には必ずヘッダ部分が出力されます。

このサンプルでは、合計部分の行数はあらかじめ想定してあるため、ページ内の明細行数は少なめになっていますが、本来は合計部分も改ページコントロールの対象にする事が昔は多かったですが、合計部分が固定位置となるような、専用の用紙であればこちらに近くなるはずです。

▼ Firebase database データ
https://freebase-654b7.firebaseio.com/class.json



【IFRAME パッケージの最新記事】
posted by lightbox at 2016-11-22 20:24 | Comment(0) | IFRAME パッケージ | このブログの読者になる | 更新情報をチェックする
バッチ処理

Microsoft Office
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

Android SDK ポケットリファレンス
改訂版 Webデザイナーのための jQuery入門
今すぐ使えるかんたん ホームページ HTML&CSS入門
CSS ドロップシャドウの参考デモ
Google Hosted Libraries
cdnjs
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり