スペーシングによる印刷処理のツボ ( php,asp,java,c++ )

  帳表設計



2007/01/07 PHP と ASP のパッケージを統合しました。(ASPにPHPのグラフ処理の呼び出しを追加しています)
2006/12/30 現在、PHP バージョンには、以下のサンプルが付属しています
1) PDF 処理( 読み込みとブラウザ出力 )
2) unix 上で使用可能な PEAR の Excel 出力
3) PEAR グラフ処理

  ** 所属別支給額合計表 **    page:ZZ9

  CD   氏名                給与      手当
-------------------------------------------
所属:J-------J
  9999 J-----J Z,ZZZ,ZZ9 Z,ZZZ,ZZ9
  9999 J-----J Z,ZZZ,ZZ9 Z,ZZZ,ZZ9
  9999 J-----J Z,ZZZ,ZZ9 Z,ZZZ,ZZ9
  9999 J-----J Z,ZZZ,ZZ9 Z,ZZZ,ZZ9
  9999 J-----J Z,ZZZ,ZZ9 Z,ZZZ,ZZ9
                          合計 ZZ,ZZZ,ZZ9

1) 典型的な、COBOL の流れをを汲(く)む帳表設計です。
2) 氏名データには実際には半角スペースが含まれています(全角に変換が必要です)。
3) DBの手当データには NULL が含まれています(注意が必要です)。
4) カンマ編集は、アプリ側で行います。

※ 【重要】
印刷処理であって、印刷ではありません。
php、asp ではブラウザに表示してから印刷を行います( 改ページは、スタイルで行います )
java、c++ は、テキストファイルに出力します( 改ページは、行計算で行います )

  PHP





出力部分
  
<PRE style='font-family:"MS 明朝";font-size:12px;'>
<?= $OutData ?>
</PRE>
  

  
# 最初のデータ取得
$Column = $SQL->QueryEx( $Query . $Cond );

global $OutData;		// 出力バッファ
$GLOBALS['pagecnt']	= 0;
$GLOBALS['rowcnt']	= 1;
$GLOBALS['rowmax']	= 9;
$GLOBALS['syozoku']	= "";
$GLOBALS['sum']		= 0;
$FIRST = 1;				// 初回フラグ

while ( $Column ) {

	# 初回ヘッダー印刷
	if ( $FIRST == 1 ) {
		$FIRST = 0;
		EditHeader(  );
	}

	# ブレイク処理
	if ( $GLOBALS['syozoku'] != $Column['所属'] ) {

		// 初回は合計は必要無い
		if ( $GLOBALS['syozoku'] != "" ) {
			// コントロールフッター
			EditNextPage(  );
			EditSum(  );
		}

		// コントロールヘッダー
		EditNextPage(  );
		EditBreakHeader( $Column );
	}

	# 数値データの集計処理
	$GLOBALS['sum'] += $Column['給与'];
	$GLOBALS['sum'] += (("0" . $Column['手当'])+0);

	// 明細行
	EditNextPage(  );
	EditDetail( $Column );

	# ブレイクデータの保存
	$GLOBALS['syozoku'] = $Column['所属'];

	# 次データの取得
	$Column = $SQL->QueryEx( );

}

# 最終の合計( データが存在した時のみ出力 )
if ( $FIRST == 0 ) {
	EditNextPage(  );
	EditSum(  );
}
  

  
# **********************************************************
# 改ページ処理
# **********************************************************
function EditNextPage(  ) {

	global $OutData;

	if ( $GLOBALS['rowcnt'] > $GLOBALS['rowmax'] ) {
		$OutData .= "</PRE>";
		$OutData .= "<PRE style='font-family:\"MS 明朝\";font-size:12px;";
		$OutData .= "page-break-before:always'>";
		EditHeader(  );	// ヘッダー印刷
	}

}

# **********************************************************
# ヘッダーの編集
# **********************************************************
function EditHeader(  ) {

	global $OutData;

	$GLOBALS['pagecnt']++;

	$str = EditNumberFormat( $GLOBALS['pagecnt'], 3 );

	$OutData .= "  ** 所属別支給額合計表 **    page:$str  \n";
	$OutData .= "\n";
	$OutData .= "  CD   氏名                給与      手当\n";
	$OutData .= "-------------------------------------------\n";

	$GLOBALS['rowcnt'] = 5;
}

# **********************************************************
# ブレイクヘッダーの編集
# **********************************************************
function EditBreakHeader( &$Column ) {

	global $OutData;

	$OutData .= "所属:{$Column['名称']}\n";

	# 行カウントアップ
	$GLOBALS['rowcnt']++;
	
}

# **********************************************************
# 明細の編集
# **********************************************************
function EditDetail( &$Column, $mode=0 ) {

	global $OutData;

# 社員コード
	$OutData .= "  " . $Column['社員コード'];
	$OutData .= " ";

# 氏名
	$OutData .= EditStringFormat( $Column['氏名'], 14 );
	$OutData .= " ";

# 給与
	$OutData .= EditNumberFormat( $Column['給与'], 9 );
	$OutData .= " ";

# 手当
	$OutData .= EditNumberFormat( $Column['手当'], 9 );
	$OutData .= "\n";

	# 行カウントアップ
	$GLOBALS['rowcnt']++;

}

# **********************************************************
# 合計の編集
# **********************************************************
function EditSum(  ) {

	global $OutData;

	$OutData .= str_repeat( " ", 24 ) . "合計:";
	$OutData .= EditNumberFormat( $GLOBALS['sum'], 12 );
	$OutData .= "\n";
	$GLOBALS['sum'] = 0;

	# 行カウントアップ
	$GLOBALS['rowcnt']++;
}

# **********************************************************
# 数値編集
# **********************************************************
function EditNumberFormat( $nData, $nCol ) {

	$ret = number_format($nData);
	$ret = str_repeat(" ", $nCol) . $ret;
	$ret = substr( $ret, strlen( $ret )-$nCol, $nCol );

	return $ret;

}

# **********************************************************
# 文字列編集
# **********************************************************
function EditStringFormat( $sData, $nCol ) {

	# スペーシングの為に、半角スペースを全角スペースに変更
	$ret = str_replace( " ", " ", $sData);
	$ret .= "        ";
	$ret = substr( $ret, 0, $nCol );

	return $ret;

}
  

  ASP

  
<PRE style='font-family:"MS 明朝";font-size:12px;'>
<%= OutData %>
</PRE>
  

  
Call DBGet( Cn, Rs, Query & strCond, false )

OutData	= ""
nPage	= 0
nRow	= 1
nRowMax	= 9
sBreak	= ""
bFirst	= true

Do While not DBEof( Rs )

	' 初回ヘッダー印刷
	if bFirst then
		bFirst = false
		Call EditHeader()
	End if

	' ブレイク処理
	if sBreak <> Rs.Fields("所属").Value then

		' 初回は合計は必要無い
		if sBreak <> "" then
			// コントロールフッター
			EditNextPage(  )
			EditSum(  )
		End If

		' コントロールヘッダー
		EditNextPage(  )
		EditBreakHeader( )
	End if

	' 数値データの集計処理
	nSum = nSum + Rs.Fields("給与").Value
	nSum = nSum + CLng("0" & Rs.Fields("手当").Value)

	' 明細行
	EditNextPage(  )
	EditDetail( )

	' ブレイクデータの保存
	sBreak = Rs.Fields("所属").Value

	Rs.MoveNext

Loop

' 最終の合計( データが存在した時のみ出力 )
if not bFirst then
	EditNextPage(  )
	EditSum(  )
End if
  

  
' **********************************************************
' 改ページ処理
' **********************************************************
Function EditNextPage(  )

	if nRow > nRowMax then
		OutData = OutData & "</PRE>"
		OutData = OutData & "<PRE style='font-family:""MS 明朝"";font-size:12px;"
		OutData = OutData & "page-break-before:always'>"
		EditHeader(  )	' ヘッダー印刷
	end if

End Function

' **********************************************************
' ヘッダ出力
' **********************************************************
Function EditHeader(  )

	nPage = nPage + 1

	str = EditNumberFormat( nPage, 3 )

	OutData = OutData & "  ** 所属別支給額合計表 **    page:" & str & vbCrLf
	OutData = OutData & vbCrLf
	OutData = OutData & "  CD   氏名                給与      手当" & vbCrLf
	OutData = OutData & "-------------------------------------------" & vbCrLf

	nRow = 5

End Function

' **********************************************************
' ブレイクヘッダーの編集
' **********************************************************
Function EditBreakHeader( )

	OutData = OutData & "所属:" & Rs.Fields("名称").Value & vbCrLf

	' 行カウントアップ
	nRow = nRow + 1
	
End Function

' **********************************************************
' 1行出力
' **********************************************************
Function EditDetail( )

' 社員コード
	OutData = OutData & "  " & Rs.Fields("社員コード").Value
	OutData = OutData & " "

' 氏名
	OutData = OutData & EditStringFormat( Rs.Fields("氏名").Value, 7 )
	OutData = OutData & " "

' 給与
	OutData = OutData & EditNumberFormat( Rs.Fields("給与").Value, 9 )
	OutData = OutData & " "

' 手当
	OutData = OutData & EditNumberFormat( Rs.Fields("手当").Value, 9 )
	OutData = OutData & vbCrLf

' 行カウントアップ
	nRow = nRow + 1

End Function

' **********************************************************
' 合計の編集
' **********************************************************
Function EditSum(  )

	OutData = OutData & String( 24, " " ) & "合計:"
	OutData = OutData & EditNumberFormat( nSum, 12 )
	OutData = OutData & vbCrLf
	nSum = 0

	' 行カウントアップ
	nRow = nRow + 1

End Function

' **********************************************************
' 数値編集
' **********************************************************
Function EditNumberFormat( sTarget, nCol )

	strFormat = FormatNumber( CLng("0"&sTarget),0,,,-1 )
	strFormat = String( nCol, " " ) & strFormat
	strFormat = Right( strFormat, nCol )

	EditNumberFormat = strFormat

End Function

' **********************************************************
' 文字列編集
' **********************************************************
Function EditStringFormat( sTarget, nCol )

	' スペーシングの為に、半角スペースを全角スペースに変更
	strFormat = Replace( sTarget, " ", " " )
	strFormat = strFormat & String( nCol, " " )
	strFormat = Left( strFormat, nCol )

	EditStringFormat = strFormat

End Function
  

  java



※ ResultSet は、2度同じフィールドにアクセスできません
( MyDB.Fields は、getString 単純ラッパーです )

  
log.fWriteOpen( "conf.log" );

if ( !uf.MyDB.Connect() ) {
	Me.MsgOk(
		"データベースの接続に失敗しました\n" +
		uf.MyDB.ErrorMessage
	);
	log.fClose();
	return;
}

String Query;
// SQL を作成する
Query = "select * from V所属別支給額合計表";
Query += " order by 所属";

// SQL を実行する。
boolean bRet = false;
long nValue = 0;
String Line = "";
String Work = "";
DecimalFormat decFormat = null;

bRet = uf.MyDB.Query(Query);
while( bRet ) {

	Syozoku		= uf.MyDB.Fields("所属");
	SyozokuMei	= uf.MyDB.Fields("名称");
	Scode		= uf.MyDB.Fields("社員コード");
	Shimei		= uf.MyDB.Fields("氏名");
	Kyuyo		= uf.MyDB.Fields("給与");
	Teate		= uf.MyDB.Fields("手当");
	if ( Teate == null ) {
		Teate = "0";
	}

	// 初回ヘッダー印刷
	if ( bFirst ) {
		bFirst = false;
		EditHeader(  );
	}

	// ブレイク処理
	if ( !sBreak.equals(Syozoku) ) {

		// 初回は合計は必要無い
		if ( !sBreak.equals( "" ) ) {
			// コントロールフッター
			EditNextPage(  );
			EditSum(  );
		}

		// コントロールヘッダー
		EditNextPage(  );
		EditBreakHeader( );
	}

	// 数値データの集計処理
	nSum += Long.parseLong( Kyuyo );
	nSum += Long.parseLong( Teate );

	// 明細行
	EditNextPage(  );
	EditDetail( );

	// ブレイクデータの保存
	sBreak = Syozoku;

	bRet = uf.MyDB.Query();
}

// 最終の合計( データが存在した時のみ出力 )
if ( !bFirst ) {
	EditNextPage(  );
	EditSum(  );
}

uf.MyDB.DisConnect();

log.fClose();
  

  
// **********************************************************
// 改ページ処理
// **********************************************************
void EditNextPage(  ) {

	long i = 0;

	if ( nRowCnt > nRowMax ) {
		// 1ページあたりの最大行まで改行する
		for( i = nRowCnt; i <= nRowParPage; i++ ) {
			log.fPuts( "" );
		}
		EditHeader(  );	// ヘッダー印刷
	}

}

// **********************************************************
// ヘッダーの編集
// **********************************************************
void EditHeader(  ) {

	nPage++;

	String str = EditNumberFormat( nPage+"", (long)3 );

	String Line = "";

	log.fPuts( "  ** 所属別支給額合計表 **    page:" + str );
	log.fPuts( "" );
	log.fPuts( "  CD   氏名                給与      手当" );
	log.fPuts( "-------------------------------------------" );

	nRowCnt = 5;

}

// **********************************************************
// ブレイクヘッダーの編集
// **********************************************************
void EditBreakHeader( ) {

	log.fPuts("所属:" + SyozokuMei );

	// 行カウントアップ
	nRowCnt++;
	
}

// **********************************************************
// 明細の編集
// **********************************************************
void EditDetail( ) {

	String Line = "";

	// 社員コード
	Line += "  " + Scode;
	Line += " ";

	// 氏名
	Line += EditStringFormat( Shimei, (long)7 );
	Line += " ";

	// 給与
	Line += EditNumberFormat( Kyuyo, (long)9 );
	Line += " ";

	// 手当
	Line += EditNumberFormat( Teate, (long)9 );

	log.fPuts( Line );

	// 行カウントアップ
	nRowCnt++;

}

// **********************************************************
// 合計の編集
// **********************************************************
void EditSum(  ) {

	log.fPuts("                        合計:"
		+ EditNumberFormat( nSum+"", (long)12 ) );
	nSum = 0;

	// 行カウントアップ
	nRowCnt++;
}

// **********************************************************
// 数値編集
// **********************************************************
String EditNumberFormat( String sData, long nCol ) {

	String sValue = sData;
	long nLen = 0;
	String Work = "";
	DecimalFormat decFormat = null;

	if ( sValue == null ) {
		sValue = "0";
	}

	decFormat = new DecimalFormat(",##0");
	Work = decFormat.format(Long.parseLong(sValue));
	Work = "                " + Work;
	nLen = Work.length();
	Work = Work.substring( (int)(nLen-nCol), (int)nLen );

	return Work;

}

// **********************************************************
// 文字列編集
// **********************************************************
String EditStringFormat( String sData, long nCol ) {

	String sValue = sData;
	long nLen = 0;
	String Work = "";

	Work = sValue.replace( " ", " " );
	Work += "              ";
	Work = Work.substring( (int)0, (int)nCol );

	return Work;

}
  

  C++



  
// *******************************************************************
// 仮想印刷
// *******************************************************************
void App::VirtualPrint()
{

	LboxString Column,LWork;
	int nRow;

	// 出力用テキストファイルを開く
	this->fp = fopen( "PRT.TXT", "wt" );
	if ( this->fp == NULL ) {
		this->Dlg->MsgOk( "ファイルを OPEN できませんでした   " );
		return;
	}

	this->nPage = 0;
	this->nRowCnt = 1;
	this->nRowMax = 9;
	this->nRowParPage = 10;
	this->nSum = 0;
	this->bFirst = true;
	this->sBreak = "";

	// リストビューの読み出しループ
	nRow = -1;
	while( this->Lview->FindNextRow( &nRow ) ) {

		// 初回ヘッダー印刷
		if ( this->bFirst ) {
			this->bFirst = false;
			this->EditHeader(  );
		}

		this->Lview->GetColumnText( 0, LWork );
		// ブレイク処理
		if ( this->sBreak != LWork ) {

			// 初回は合計は必要無い
			if ( this->sBreak != "" ) {
				// コントロールフッター
				this->EditNextPage(  );
				this->EditSum(  );
			}

			// コントロールヘッダー
			this->EditNextPage(  );
			this->EditBreakHeader( );
		}

		// 数値データの集計処理
		this->Lview->GetColumnText( 4, LWork );
		this->nSum += LWork.Atoi();
		this->Lview->GetColumnText( 5, LWork );
		this->nSum += LWork.Atoi();
	
		// 明細行
		this->EditNextPage(  );
		this->EditDetail( );
	
		// ブレイクデータの保存
		this->Lview->GetColumnText( 0, this->sBreak );
	}

	// 最終の合計( データが存在した時のみ出力 )
	if ( !this->bFirst ) {
		this->EditNextPage(  );
		this->EditSum(  );
	}

	// 閉じる
	fclose( this->fp );

	// メモ帳で表示
	Tool.Execute( "notepad.exe PRT.TXT", NULL );

}
  

  
// *******************************************************************
// 改ページ処理
// *******************************************************************
void App::EditNextPage()
{
	int i;

	if ( this->nRowCnt > this->nRowMax ) {
		// 1ページあたりの最大行まで改行する
		for( i = this->nRowCnt; i <= this->nRowParPage; i++ ) {
			fprintf( this->fp, "\n" );
		}
		EditHeader(  );	// ヘッダー印刷
	}
}

// *******************************************************************
// ヘッダーの編集
// *******************************************************************
void App::EditHeader()
{

	nPage++;

	LboxString str = EditNumberFormat( nPage, 3 );
	str.Insert( "  ** 所属別支給額合計表 **    page:" );

	fprintf( this->fp, "%s\n", str.szLboxString );
	fprintf( this->fp, "\n" );
	fprintf( this->fp, "%s\n", "  CD   氏名                給与      手当" );
	fprintf( this->fp, "%s\n", "-------------------------------------------" );

	nRowCnt = 5;
}

// **********************************************************
// ブレイクヘッダーの編集
// **********************************************************
void App::EditBreakHeader( )
{
	LboxString LWork;

	this->Lview->GetColumnText( 1, LWork );

	fprintf( this->fp, "所属:%s\n", LWork.szLboxString );

	// 行カウントアップ
	nRowCnt++;
	
}
// **********************************************************
// 明細の編集
// **********************************************************
void App::EditDetail( )
{

	LboxString Line("");
	LboxString LWork;

	// 社員コード
	this->Lview->GetColumnText( 2, LWork );
	Line += "  " + LWork;
	Line += " ";

	// 氏名
	this->Lview->GetColumnText( 3, LWork );
	Line += EditStringFormat( LWork, (long)7 );
	Line += " ";

	// 給与
	this->Lview->GetColumnText( 4, LWork );
	Line += EditNumberFormat( LWork, (long)9 );
	Line += " ";

	// 手当
	this->Lview->GetColumnText( 5, LWork );
	Line += EditNumberFormat( LWork, (long)9 );

	fprintf( this->fp, "%s\n", Line.szLboxString );

	// 行カウントアップ
	nRowCnt++;

}

// **********************************************************
// 合計の編集
// **********************************************************
void App::EditSum(  )
{
	LboxString LWork;

	LWork.Repeat( " ", 24 );
	LWork += "合計:";
	LWork += EditNumberFormat( nSum, 12 );
	
	fprintf( this->fp, LWork );
	nSum = 0;

	// 行カウントアップ
	nRowCnt++;
}

// **********************************************************
// 数値編集
// **********************************************************
LboxString App::EditNumberFormat( int nData, int nCol )
{

	LboxString LWork;
	LboxString LSpace;

	LWork = nData;
	LSpace.Repeat( " ", nCol );
	LWork.NumberFormat( );

	LWork.Insert( &LSpace );
	LWork.Right( nCol );

	return LWork;

}
LboxString App::EditNumberFormat( LboxString &sData, int nCol )
{

	LboxString LWork;
	LboxString LSpace;

	LWork = sData;
	LSpace.Repeat( " ", nCol );
	LWork.NumberFormat( );

	LWork.Insert( &LSpace );
	LWork.Right( nCol );

	return LWork;

}

// **********************************************************
// 文字列編集
// **********************************************************
LboxString App::EditStringFormat( LboxString &sData, int nCol )
{

	LboxString LWork;
	LboxString LSpace;

	LWork = sData;
	LWork.Replace( " ", " " );
	LSpace.Repeat( " ", nCol );
	LWork += LSpace;
	LWork.Left( nCol * 2 );

	return LWork;

}
  











   SQLの窓    create:2006/10/13  update:2014/09/07   管理者用(要ログイン)





フリーフォントWEBサービス

SQLの窓WEBサービス

SQLの窓フリーソフト

写真素材

一般WEBツールリンク

SQLの窓

フリーソフト

JSライブラリ