PHPでPDF出力(tcpdf) 9 (列の繰り返しと折り返して全体表示)

9.列の繰り返しと折り返して全体表示

ほぼ満足のいく結果が得られたが、「列の繰り返し」と「折り返しての全体表示」に課題が残った。

まず、取り掛かったのが「列の繰り返し」である。

Excelでの変数定義は、行と同様に「{$配列名変数名]}」とした。

TCPDF定義ファイルの出力は下記の通り、簡単に作成でき結果も良好である。

 // 列の幅
$wd = 16.4;
// 行高さ
$hi = 6.2;
// 列の開始位置
$col = 2;
$maxCol = 13;
$hPos=8.8;
$vPos=28.4;
foreach ($this->_pdf_vars['lp'] as $key) {
$source = $key['mon'];
$this->Rect($hPos, $vPos,$wd, $hi,'F','',array(226,239,218));
$this->SetTextColor(0,0,0);
$pos=$vPos;
$this->SetFont('kozgopromedium', '',11);
for ($k= 0; $k != -1;  ) {
$info = $this->adjustToHeight($source, $k,16.4,15.4,6.2,kozgopromedium,11);
$k = $info['length'];
$text = $info['text'];
$this->SetXY($hPos, $pos);
$this->Cell(16.4, $info['height'],  $text, 0, 0,'R',0,'',0,0,'T','M');
$pos += $info['height'];
}
$hPos += $wd;
$col++; 
}

 pdf列の繰り返し

1行での列の繰り返しであり、行の繰り返しの中で列の繰り返しもある。

これだと対応できない。

行の繰り返しと列の繰り返しをどう融合させるか?

二次元配列で実装することにした。

Excelでの変数定義は、「{$配列名配列名1][変数名]}」で配列名1は列の配列で使用することにした。

Excelの定義と出力定義ファイルとindex.phpは次のようになる。

  excel二次元定義

tcpdf定義ファイル
// 行の高さ
$hi = 6.5;
// 行の開始位置
$vPos = 19.4;
$row = 2;
$maxRow = 5;
foreach ($this->_pdf_vars['lp1'] as $key) {
// 列の幅
$wd = 31.7;
// 行高さ
$hi = 6.5;
// 列の開始位置
$col = 2;
$maxCol = 7;
foreach($key as $key1) {
foreach($key1 as $key2) {
$hPos=9.8;
for ($ix= 0;$ix < count($key2['kin']); $ix++) {
$source = $key2['kin'][$ix];
$this->Rect($hPos, $vPos,$wd, $hi,'F','',array(226,239,218));
$this->SetTextColor(0,0,0);
$this->SetXY($hPos, $vPos);
$this->Cell( $wd, $hi, $source, 0, 0,'R',0,'',0,0,'T','M');
$hPos += $wd;
$col++; 
}
$vPos += $hi;
$row++;
}
}
index.php
$lp = array();
for ($iy= 1; $iy < 5;$iy++) {
$lpdata=array();
for($ix=1; $ix< 7; $ix++){
//列の代入   $lpdata['kin'][] = $iy.-$ix; }
//行の代入 $lp['mon'][] = $lpdata; } $pdf->append("lp1",$lp);

 果たして、tcpdfで出力結果は

  f:id:sesjk:20200514162514p:plain

背景色が先頭行と同じになってしまうが、これは先頭行の繰り返しであるので、仕様(仕方ない)と考え妥協する。

 

折り返して全体表示

 ジェネレーターでは対応できないので、PHPでPDFを出力時に処理する必要がある。 

これは、PHPでPDF出力 5(縮小・折り返しで全体表示)で作成した関数「adjustToHeight」を修正した。

 

/*******************************************************************

折り返して表示

 $source:文字列, $pos:開始文字位置, $maxwidth:表示エリア幅,

    $width:表示する幅, $height:行の高さ

   $font:使用するフォント名, $fontsize:使用するフォントサイズ

  $count:セルに収まる1行当たりの文字数

********************************************************************/

public function adjustToHeight($source, $pos, $maxwidth, $width, $height, $font, $fontsize,$count) {

$info = array();

$text = mb_substr($source,$pos, null,"UTF-8");

$size = $fontsize;

$info["text"] = $text;
$info["height"] = $hei;
$info["length"] = -1;

if ($pos == 0) {
$info["height"] = $height;

//セルに収まるフォントサイズを算出
$limt = $maxwidth * $height;
while(1) {
//文字高さを取得
$hei = $this->getStringHeight(0,mb_substr($text,0,1,"UTF-8"));
//文字列幅を取得
$wid = $this->getStringWidth($text,$font,"",$size);
// 必要セル数
$needWidth = ceil*1 {
//フォントサイズを下げる
$size -= 1;
if ($size < 7) break;
$this->SetFont($font, '',$size);
} else {
break;
}
}
} else {
$hei = $this->getStringHeight(0,mb_substr($text,0,1,"UTF-8"));
}

$arrlen = $this->GetStringWidth($text,"","","",true);

if ($count == 1 && $pos > 0) {
// 1行1文字
$info["text"] = mb_substr($text,0,1,"UTF-8");
$info["height"] = $hei;
$info["length"] = 1 + $pos;
$info["count"] = 1;
if (count($arrlen) == 1) {
$info["length"] = -1;
}
return $info;
}

$len = 0;
//文字列がセルに収まるかのチェック
if ($this->GetStringWidth($text) > $maxwidth) {
$blktxt = $text;
$text="";
for ($j =0; $j < count($arrlen); $j++) {
$len += $arrlen[$j];
if ($len > $width) {
$info["text"] = $text;
$info["height"] = $hei;
$info["length"] = $j + $pos;
$info["count"] = $j;
break;
}
$text .= mb_substr($blktxt,$j,1,"UTF-8");
}
if ($j == count($arrlen)) {
$info["length"] = -1;
}
}

return $info;
}

 

*1:$wid+0.5) / $maxwidth);

if ($limt <= ($hei * $wid