PHPでPDF出力 4(罫線を引く)
4.罫線の処理の追加
文字表示の体裁は整ったので、罫線の表示を追加する。
TCPDFで罫線の定義は次の通りである。
Line(開始X座標、開始Y座標、終了X座標、終了Y座標、スタイル)
スタイル:幅、末端部、結合部、破線パターン、破線パターンの開始位置、色
Excelはセル書式の「Borders」プロパティから取得できる。
下記の線種がどのような値で取得できるのか、上罫線で確認してみた。
1行目から順に、 -4142、1、1、-1418、5、4、-4155、-4119となった。
3行目の点線は直線と同じ値で区別がつかない。
これでジェネレートする処理を組み込もうとしたが、今度は、
TCPDFに鎖線(5,4)と二重線(-4119)に対応する定義がない。
取り敢えず、鎖線は破線、二重線は太い実線で組み込んだソースと実行結果は、
-------------------------------------------------------------
$tcpdf->Line(9, 6.5, 134.3, 6.5, array('width' => 0.2, 'cap' => 'butt', 'join' => 'miter','dash' => 0, 'color' => array(0,0,0)));
$tcpdf->Line(9, 11, 134.3, 11, array('width' => 0.2, 'cap' => 'butt', 'join' => 'miter','dash' => 0, 'color' => array(0,102,255)));
$tcpdf->Line(9, 15.5, 134.3, 15.5, array('width' => 0.2, 'cap' => 'butt', 'join' => 'miter','dash' => 1, 'color' => array(255,0,0)));
$tcpdf->Line(9, 20, 134.3, 20, array('width' => 0.2, 'cap' => 'butt', 'join' => 'miter','dash' => 2, 'color' => array(0,176,80)));
$tcpdf->Line(9, 24.5, 134.3, 24.5, array('width' => 0.2, 'cap' => 'butt', 'join' => 'miter','dash' => 2, 'color' => array(226,107,10)));
$tcpdf->Line(9, 29, 134.3, 29, array('width' => 0.2, 'cap' => 'butt', 'join' => 'miter','dash' => 2, 'color' => array(255,0,255)));
$tcpdf->Line(9, 33.8, 134.3, 33.8, array('width' => 0.6, 'cap' => 'butt', 'join' => 'miter','dash' => 0, 'color' => array(96,73,122)));
-------------------------------------------------------------
鎖線を単純に破線にすると、メリハリがなくなる。また、二重線も気になる。
破線パターンで線のON-OFFができることが分かり、それぞれ変更してみた。
$tcpdf->Line(9, 20, 134.3, 20, array('width' => 0.2, 'cap' => 'butt', 'join' => 'miter','dash' => '5,2' 'color' => array(0,176,80)));
$tcpdf->Line(9, 24.5, 134.3, 24.5, array('width' => 0.2, 'cap' => 'butt', 'join' => 'miter','dash' => '5,1', 'color' => array(226,107,10)));
また、二重線は実線2つに分解することで対応した。
左右の罫線は、右罫線を表示し、A列の左罫線を有効として実行した。
結合セルの扱い
何やら結合セルに余計な罫線が出力されている。
それも行が結合されているセルを疑い調査する。
Excelはセル書式の「Borders」プロパティの上罫線を取得しているのは前述している。
これだと最終行の下罫線が漏れてしまうので、解析は最終行+1で処理している。
セル(B2)は上罫線ONで、セル(B3)も上罫線ONになる。結合セルは見た目は罫線なしだが、プロパティはしっかりONになっている。
結合セルの2行目以降は無視する必要がある
結合セルは、「MergeCells」プロパティで判定でき、行数と列数はそれぞれ「MergeArea.Rows.Count」と「MergeArea.Columns.Count」で取得できる。
上記処理を追加して出力した結果である。
満足できる出来栄えで、ひとりニヤつくが、単価が5桁で目一杯に気づき我に返る。
カンマや6桁以上にではどうなる。
案の定、罫線に掛かってしまった。
次は、「縮小して全体を表示する」と「折り返して全体を表示する」の処理を追加。
これは、ジェネレーターだけでは対応できず、PHPでの処理になる。
PHPでPDF出力 3(体裁を整える)
3.縦、横位置を定義して体裁を整える
取り敢えず、Microsoft Visual StudioのVB.NETで開発することにした。
まずは、Excelファイルを読み込み、セル書式から文字列をジェネレートするために、
文字列、フォント名、フォントサイズ、前景色、横縦揃えに絞った。
その結果は、1行に重なってしまった。
セルの絶対位置の取得
Excelのセル位置を先頭からの絶対値(ミリ)で取得することにした。
1ピクセルが約0.0846ミリとして計算すれば、該当セルまでの絶対値が求まる、ハズ。
0.0何ミリと細かくしても意味がないので、10ピクセルで0.85ミリで計算することにした。
結果は、以下の通り無残な状態。
ピクセルからミリへの変換が間違っているのか確かめたが、10ピクセルで0.085で計算し、小数点2位で四捨五入している。
ならば、セルのピクセル数の取得が・・・。
Excelのページレイアウト表示で、受注日(列B)と図番(列D)までの値を調べた。
受注日(列B)は1.1ミリ(4ピクセル)、図番(列D)は21.4ミリ(82ピクセル)
まるで違う。はて?
嗚呼~、なんてこった。ピクセルではなく単位はポイント(世間の常識?)
1ポイントを0.35ミリにプログラムを修正して再実行。
結果は満足できる出来栄えに、ひとり悦に入る。
SetXYを忘れずに。
--------------------------------------------------------------
$tcpdf->SetFont('kozgopromedium', '',11);
$tcpdf->SetTextColor(0,0,0);
$source ='受 注 日';
$tcpdf->SetXY(1.2, 2.9);
$tcpdf->Cell(21,8, $source, 0, 0,'C',0,'',0,0,'T','M');
$source ='図 番';
$tcpdf->SetFont('kozgopromedium', '',11);
$tcpdf->SetXY(21.9, 2.9);
$tcpdf->Cell(59,8, $source, 0, 0,'C',0,'',0,0,'T','M');
--------------------------------------------------------------
次は、罫線の処理の追加
EXCELをPHPでPDF出力 2(TCPDFジェネレーター開発)
2.TCPDFソースジェネレーター開発着手
ExcelからTCPDF用の定義を出力を考え、ジェネレーターを作成することにした。
Webで完結するために、PHPでExcelの書式を取得できないかと模索したが、それらしきものを見つける出すことができなかった。
取り敢えず、Microsoft Visual StudioのVB.NETで開発することにした。
まずは、Excelファイルを読み込み、セル書式から文字列をジェネレートすることにした。
取得する情報は、
文字列、フォント名、フォントサイズ、前景色、横縦揃えに絞った。
これらの情報から定義できるのは、以下のようになる。
SetFont(フォント名、サイズ)
SetTextColor(前景色)
Cell(幅、高さ、文字列、横揃え、縦揃え)
下図のExcelの3行目まで実行してみた。
定義ソースは、それらしく出力された。
--------------------------------------------------------------------------------------------------
$tcpdf->SetFont('kozgopromedium', '',11);
$tcpdf->SetTextColor(0,0,0);
$source ='受 注 日';
$tcpdf->Cell(21,8, $source, 0, 0,'C',0,'',0,0,'T','M');
$source ='図 番';
$tcpdf->SetFont('kozgopromedium', '',$info);
$tcpdf->Cell(59,8, $source, 0, 0,'C',0,'',0,0,'T','M');
$source ='個数';
$tcpdf->SetFont('kozgopromedium', '',11);
$tcpdf->Cell(12,8, $source, 0, 0,'C',0,'',0,0,'T','M');
$source ='単 価';
$tcpdf->SetFont('kozgopromedium', '',11);
$tcpdf->Cell(20,8, $source, 0, 0,'C',0,'',0,0,'T','M');
$source ='納 期';
$tcpdf->Cell(24,8, $source, 0, 0,'C',0,'',0,0,'T','M');
$tcpdf->SetFont('kozgopromedium', '',11);
$source ='回数';
$tcpdf->Cell(14,8, $source, 0, 0,'C',0,'',0,0,'T','M');
$tcpdf->SetFont('kozgopromedium', '',24);
$source ='製 造 指 示 書';
$tcpdf->Cell(82,14, $source, 0, 0,'C',0,'',0,0,'T','M');
$tcpdf->SetFont('kozgopromedium', '',11);
$source ='8/8';
$tcpdf->SetFont('kozgopromedium', '',$info);
$tcpdfs->Cell(9,13, $source, 0, 0,'C',0,'',0,0,'T','M');
$tcpdf->SetFont('kozgopromedium', '',22);
$tcpdf->SetTextColor(255,0,0);
$source ='Ⅹ';
$tcpdf->Cell(12,13, $source, 0, 0,'C',0,'',0,0,'T','M');
$tcpdf->SetFont('kozgopromedium', '',18);
$tcpdf->SetTextColor(0,0,0);
$source ='HFA-450-091';
$tcpdf->SetFont('kozgopromedium', '',18);
$tcpdf->Cell(47,13, $source, 0, 0,'C',0,'',0,0,'T','M');
$source ='10';
$tcpdf->SetFont('kozgopromedium', '',11);
$tcpdf->Cell(12,13, $source, 0, 0,'C',0,'',0,0,'T','M');
$source ='12000';
$tcpdf->SetFont('kozgopromedium', '',11);
$tcpdf->Cell(20,13, $source, 0, 0,'C',0,'',0,0,'T','M');
$source ='9/1';
$tcpdf->Cell(24,13, $source, 0, 0,'C',0,'',0,0,'T','M');
$source ='5';
$tcpdf->Cell(14,13, $source, 0, 0,'C',0,'',0,0,'T','M');
-----------------------------------------------------------------------------------------------
果たして、PDFを出力してみると下図の通り。1行に重なってしまった。
SetXYが定義されていないためであることが判明した。
そこで、SetXYで定義する縦位置と横位置を取得する処理を追加することになる。
これが、単純そうでなかなかの苦戦であった。
EXCELをPHPでPDF出力(tcpdf) 1
- 1.開発依頼
1.開発依頼
とあるクライアントからEXCEL管理をWeb化したい旨の依頼があった。
当初は、Excelを更新してダウンロードする形で進んでいたのだが、
PDFで製造部署がダウンロードする仕様変更が出された。
Excelに更新するだけであれば、工数的にも費用的にも十分余裕があった。
だが、PDF出力となると正直経験不足である。
色々なサイトを調べると、TCPDFがお手軽にhtmlから変換できるようなので、
TCPDFを試してみた。
残念ながら、下図のExcel「製造指示書」にまったく対応できない。
phpにオウンコーディングで試みたが、直ぐに挫折した。
1行目だけで下記のようなコーディングになる。これに罫線の設定をすると気が遠くなる。
-----------------------------------------------------------------------------------------------
include "lib/TCPDF/tcpdf.php";
$tcpdf = new TCPDF('L','mm','A4',true,'UTF-8')
$tcpdf ->setPrintFooter(0);
$tcpdf ->setHeaderMargin(0);
$tcpdf ->setFooterMargin(0);
$tcpdf ->SetMargins(0.1,2.9,-1,true);
$tcpdf ->AddPage();
$a = $tcpdf ->GetX();
$b = $tcpdf ->GetY();
$tcpdf ->SetFont('kozgopromedium', '',11);
$tcpdf ->SetTextColor(0,0,0);
$tcpdf ->SetXY(1.2,2.9);
$tcpdf ->Cell(21,8, '受 注 日', 0, 0,'C',0,'',0,0,'T','M');
$tcpdf ->SetXY($a,$b);
$tcpdf ->SetXY(21.9, 2.9);
$tcpdf ->Cell(59,8, '図 番', 0, 0,'C',0,'',0,0,'T','M');
$tcpdf ->SetXY($a,$b);
$tcpdf ->SetXY(84.9, 2.9);
$tcpdf ->Cell(12,8, '個数', 0, 0,'C',0,'',0,0,'T','M');
$tcpdf ->SetXY($a,$b);
$tcpdf ->SetXY(92.1, 2.9);
$tcpdf ->Cell(20,8, '単 価', 0, 0,'C',0,'',0,0,'T','M');
$tcpdf ->SetXY($a,$b);
$tcpdf ->SetXY(111.8, 2.9);
$tcpdf ->Cell(24,8, 納 期', 0, 0,'C',0,'',0,0,'T','M');
$tcpdf ->SetXY($a,$b);
$tcpdf ->SetXY(135.4,2.9);
$tcpdf ->Cell(14,8, '回数', 0, 0,'C',0,'',0,0,'T','M');
$tcpdf->Output('seizousiji.pdf', 'I');
続きを読む