PHPでPDF出力 4(罫線を引く)

4.罫線の処理の追加

文字表示の体裁は整ったので、罫線の表示を追加する。

 TCPDFで罫線の定義は次の通りである。

Line(開始X座標、開始Y座標、終了X座標、終了Y座標、スタイル)

 スタイル:幅、末端部、結合部、破線パターン、破線パターンの開始位置、色

Excelはセル書式の「Borders」プロパティから取得できる。

下記の線種がどのような値で取得できるのか、上罫線で確認してみた。

   Excl線種の確認

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)));

-------------------------------------------------------------

    PDF線種の確認

鎖線を単純に破線にすると、メリハリがなくなる。また、二重線も気になる。

破線パターンで線の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 StudioVB.NETで開発することにした。

まずは、Excelファイルを読み込み、セル書式から文字列をジェネレートするために、

文字列、フォント名、フォントサイズ、前景色、横縦揃えに絞った。

その結果は、1行に重なってしまった。

 

セルの絶対位置の取得

 Excelのセル位置を先頭からの絶対値(ミリ)で取得することにした。

1ピクセルが約0.0846ミリとして計算すれば、該当セルまでの絶対値が求まる、ハズ。

0.0何ミリと細かくしても意味がないので、10ピクセルで0.85ミリで計算することにした。

結果は、以下の通り無残な状態。

     f:id:sesjk:20200429113610p:plain

ピクセルからミリへの変換が間違っているのか確かめたが、10ピクセルで0.085で計算し、小数点2位で四捨五入している。

ならば、セルのピクセル数の取得が・・・。

Excelのページレイアウト表示で、受注日(列B)と図番(列D)までの値を調べた。

受注日(列B)は1.1ミリ(4ピクセル)、図番(列D)は21.4ミリ(82ピクセル)

まるで違う。はて?

嗚呼~、なんてこった。ピクセルではなく単位はポイント(世間の常識?)

1ポイントを0.35ミリにプログラムを修正して再実行。

結果は満足できる出来栄えに、ひとり悦に入る。

f:id:sesjk:20200429121314p:plain

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で完結するために、PHPExcelの書式を取得できないかと模索したが、それらしきものを見つける出すことができなかった。

 

取り敢えず、Microsoft Visual StudioVB.NETで開発することにした。

まずは、Excelファイルを読み込み、セル書式から文字列をジェネレートすることにした。

取得する情報は、

 文字列、フォント名、フォントサイズ、前景色、横縦揃えに絞った。

これらの情報から定義できるのは、以下のようになる。

 SetFont(フォント名、サイズ)

    SetTextColor(前景色)

 Cell(幅、高さ、文字列、横揃え、縦揃え)

下図のExcelの3行目まで実行してみた。

   f:id:sesjk:20200428123103p:plain

定義ソースは、それらしく出力された。

--------------------------------------------------------------------------------------------------

$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行に重なってしまった。

     f:id:sesjk:20200428162406p:plain

SetXYが定義されていないためであることが判明した。

 

そこで、SetXYで定義する縦位置と横位置を取得する処理を追加することになる。

これが、単純そうでなかなかの苦戦であった。

 

 

 

 

EXCELをPHPでPDF出力(tcpdf) 1

  •  1.開発依頼

 1.開発依頼

とあるクライアントからEXCEL管理をWeb化したい旨の依頼があった。

当初は、Excelを更新してダウンロードする形で進んでいたのだが、

PDFで製造部署がダウンロードする仕様変更が出された。

Excelに更新するだけであれば、工数的にも費用的にも十分余裕があった。

だが、PDF出力となると正直経験不足である。

 

色々なサイトを調べると、TCPDFがお手軽にhtmlから変換できるようなので、

TCPDFを試してみた。

残念ながら、下図のExcel「製造指示書」にまったく対応できない。

       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');

続きを読む