[2023/02/06] PHP TCPDFの画像ファイルの出力について(imageメソッド)・その2 (No.305)
[2023/02/03] PHP TCPDFの画像ファイルの出力について(imageメソッド) (No.304)
[2023/02/01] PHP TCPDFのHTML書式の出力について(writeHTMLメソッド) (No.303)
[2023/01/31] PHP TCPDFのトランザクション処理について(startTransaction, rollbackTransaction, commitTransactionメソッド) (No.302)
-
「PHP PDF出力の方法について・マージンとヘッダ/フッタ(TCPDF)」 の記事では TCPDF クラスを継承し Header メソッドを上書きすることでページのヘッダ処理のカスタマイズを行いました。
この Header メソッドは、ページを追加するメソッドの AddPage を実行すると毎回CALLされる様になっています。
TCPDF クラスを継承し Header メソッドのに、ページ全体に背景画像を設定する様にしてみます。
取敢えず Image メソッドの引数はに付いて以下に記します。// Imageメソッド public function Image($file, $x=null, $y=null, $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0, $fitbox=false, $hidden=false, $fitonpage=false, $alt=false, $altimgs=array()) // $file : 画像ファイル名 // $x : 領域左上のX座標[指定しない場合、現在のX座標位置] // $y : 領域左上のY座標[指定しない場合、現在のY座標位置] // $w : 領域の幅 [指定しない場合、自動計算される] // $h : 領域の高さ [指定しない場合、自動計算される] // $type : 画像フォーマット("JPEG", "PNG") // $link : AddLink()で作成したリンク識別子 // $align : 次の画像を表示する位置 // [T]: top-right for LTR or top-left for RTL // [M]: middle-right for LTR or middle-left for RTL // [B]: bottom-right for LTR or bottom-left for RTL // [N]: next line // $resize : [true]画像サイズを$wや$hに合わせてリサイズ // $dpi : 解像度(dot per inch) // $palign : 画像を現在の行のどこに配置するか // [L] : 左端 // [C] : 中央 // [R] : 右端 // ['']: 左端(RTLの場合は右端) // $ismask : [true]画像をマスクする場合 // $imgmask : 画像オブジェクトをメソッドの戻り値として取得する // (描画しない、w、h、x、yは無視される)場合true // $border : 境界線表示(0:枠無し,1:枠有 または "LRTB"の文字列で「左右上下」を指定) // $fitbox : [ture]($w, $h)で指定する領域に合わせて拡縮 // $hidden : [ture]画像を画面に表示しない // $fitonpage : [ture]ページの大きさに拡大する // $alt : If true the image will be added as alternative and not directly printed // (the ID of the image will be returned). // $altimgs : Array of alternate images IDs. Each alternative image must be an array with two values: // an integer representing the image ID (the value returned by the Image method) // and a boolean value to indicate if the image is the default for printing.
■ページを追加するごとに、画像を用紙全体に表示する
画像データは以下のものを使います。画像の大きさは「459×640」ピクセルです。
この画像を用紙全体に表示を行います。
TCPDF を継承しクラス名を EXPDF とします。 Header メソッド内の処理は先ず getBreakMargin メソッドで改頁までの余白を取得し getAutoPageBreak メソッドで自動改ページモードを取得し退避します。
その後で SetAutoPageBreak メソッドで自動改ページ機能をOFF、及びページ下端からのマージンを「0」に設定します。 そして Image メソッドで画像をページ全体指定で表示します。
画像表示後 SetAutoPageBreak メソッドで自動改ページ状態と改頁までの余白の設定値を戻してやります。
ここで少し注意点があります。TCPDF クラスではデフォルトでヘッダ出力の設定が true になっているので AddPage メソッド実行時に上書きした Header メソッドが実行されます。 ただし setPrintHeader メソッドで false に設定すると Header メソッドが実行されなくなるので注意が必要です。<?php require_once('../tcpdf/tcpdf.php'); // TCPDF クラスを継承 class EXPDF extends TCPDF { // [Header]を上書き public function Header() { // 改頁までの余白取得 $svBreakMargin = $this->getBreakMargin(); // 自動改ページモード取得 $svAutoPageBreak = $this->getAutoPageBreak(); // 自動改ページ機能をOFF(ページ下端からのマージン;0設定) $this->SetAutoPageBreak(false, 0); // ページ全体に画像を張り付け $this->Image('../_test_pdf/test-backg.png', 0, 0, 210, 297); // ページ設定を元に戻す $this->SetAutoPageBreak($svAutoPageBreak, $svBreakMargin); } } // TCPDFを継承したクラス生成 $pdf = new EXPDF(); // デフォルトで用意されている日本語フォント[小塚ゴシックPro M] $strFont = "kozgopromedium"; // ヘッダ・フッタ出力設定 $pdf->setPrintHeader(true); // デフォルトではヘッダ出力「true」なので要らないが $pdf->setPrintFooter(false); // 本文の日本語フォント[小塚ゴシックPro M] $pdf->SetFont($strFont, "", 10); // 新しいpdfページを追加 $pdf->AddPage(); // 1ページ目タイトル表示 $strOut = '<h1>HTML Imageテスト3・1ページ目表示</h1>'; $pdf->writeHTML($strOut, true, false, true, false, ''); // 新しいpdfページを追加 $pdf->AddPage(); // 1ページ目タイトル表示 $strOut = '<h1>HTML Imageテスト3・2ページ目表示</h1>'; $pdf->writeHTML($strOut, true, false, true, false, ''); // pdf表示設定 $pdf->Output('pdf-img-7-1.pdf', 'I'); ?>
これの実行結果は以下の通りです。
PR -
「PHP TCPDFの画像ファイルの出力について(imageメソッド)」 の記事では Image メソッドの基本的な使い方を説明しましたが、今回はこのメソッドについてその他のトピックスを記します。
取敢えず Image メソッドの引数はに付いて以下に記します。// Imageメソッド public function Image($file, $x=null, $y=null, $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0, $fitbox=false, $hidden=false, $fitonpage=false, $alt=false, $altimgs=array()) // $file : 画像ファイル名 // $x : 領域左上のX座標[指定しない場合、現在のX座標位置] // $y : 領域左上のY座標[指定しない場合、現在のY座標位置] // $w : 領域の幅 [指定しない場合、自動計算される] // $h : 領域の高さ [指定しない場合、自動計算される] // $type : 画像フォーマット("JPEG", "PNG") // $link : AddLink()で作成したリンク識別子 // $align : 次の画像を表示する位置 // [T]: top-right for LTR or top-left for RTL // [M]: middle-right for LTR or middle-left for RTL // [B]: bottom-right for LTR or bottom-left for RTL // [N]: next line // $resize : [true]画像サイズを$wや$hに合わせてリサイズ // $dpi : 解像度(dot per inch) // $palign : 画像を現在の行のどこに配置するか // [L] : 左端 // [C] : 中央 // [R] : 右端 // ['']: 左端(RTLの場合は右端) // $ismask : [true]画像をマスクする場合 // $imgmask : 画像オブジェクトをメソッドの戻り値として取得する // (描画しない、w、h、x、yは無視される)場合true // $border : 境界線表示(0:枠無し,1:枠有 または "LRTB"の文字列で「左右上下」を指定) // $fitbox : [ture]($w, $h)で指定する領域に合わせて拡縮 // $hidden : [ture]画像を画面に表示しない // $fitonpage : [ture]ページの大きさに拡大する // $alt : If true the image will be added as alternative and not directly printed // (the ID of the image will be returned). // $altimgs : Array of alternate images IDs. Each alternative image must be an array with two values: // an integer representing the image ID (the value returned by the Image method) // and a boolean value to indicate if the image is the default for printing.
以下の各種のテストをしてみます。■画像を用紙全体に表示
画像データは以下のものを使います。画像の大きさは「100×30」ピクセルです。
この画像を用紙全体に表示を行います。
方法としては、先ず SetAutoPageBreak メソッドで自動改ページ機能をOFF、及びページ下端からのマージンを「0」に設定します。 その後 Image メソッドでページ全体指定で表示します。
SetAutoPageBreak メソッドの実行前には現在の自動改ページ状態と改頁までの余白を取得して退避し、 画像表示後にその設定値を戻してやります。<?php require_once('../tcpdf/tcpdf.php'); // クラス生成 $pdf = new TCPDF(); // デフォルトで用意されている日本語フォント[小塚ゴシックPro M] $strFont = "kozgopromedium"; // ヘッダ・フッタ出力設定(特にいらないが) $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); // 本文の日本語フォント[小塚ゴシックPro M] $pdf->SetFont($strFont, "", 10); // 新しいpdfページを追加 $pdf->AddPage(); // 改頁までの余白取得 $svBreakMargin = $pdf->getBreakMargin(); // 自動改ページモード取得 $svAutoPageBreak = $pdf->getAutoPageBreak(); // 自動改ページ機能をOFF(ページ下端からのマージン;0設定) $pdf->SetAutoPageBreak(false, 0); // ページ全体に画像を張り付け $pdf->Image('test-logo.png', 0, 0, 210, 297); // ページ設定を元に戻す $pdf->SetAutoPageBreak($svAutoPageBreak, $svBreakMargin); // タイトル表示 $strOut = '<h1>HTML Imageテスト・全体に画像表示</h1>'; $pdf->writeHTML($strOut, true, false, true, false, ''); // pdf表示設定 $pdf->Output('pdf-img-6-1.pdf', 'I'); ?>
これの実行結果は以下の通りです。
■画像がページをまたがって表示
画像の「Y座標」位置がページをまたがる様な指定の場合には、どの様な表示になるのでしょうか。
以下のソースを見て下さい。
最初の画像表示は Image メソッドの「Y座標」をA4サイズ「297mm」から 「画像の縦の長さ:30mm」、「ページブレイク長:20mm」及び「1mm」を引いた値で設定しています。
2番目の画像表示は、「Y座標」を最初の画像表示よりさらに「1mm」を引いた値で設定しています。<?php require_once('../tcpdf/tcpdf.php'); // クラス生成 $pdf = new TCPDF(); // デフォルトで用意されている日本語フォント[小塚ゴシックPro M] $strFont = "kozgopromedium"; // ヘッダ・フッタ出力設定(特にいらないが) $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); // 本文の日本語フォント[小塚ゴシックPro M] $pdf->SetFont($strFont, "", 10); // 新しいpdfページを追加 $pdf->AddPage(); // HTMLの定義 $strOut = '<h1>HTML Imageテスト</h1>'; $pdf->writeHTML($strOut, true, false, true, false, ''); $strOut = '画像の横幅・高さ(100×30 mm)指定し、PageBreakを超える感じて表示'; $pdf->cell(null, null, $strOut, 0, 1); // 縦位置:紙の縦幅「297mm」-画像縦幅「30mm」-PageBreak幅「20mm(デフォルト値)」 $pdf->Image('test-logo.png', 10, 297 - 30 - 20, 100, 30, 'PNG', '', 'N', false); // 縦位置:紙の縦幅「297mm」-画像縦幅「30mm」-PageBreak幅「20mm+1mm」 $pdf->Image('test-logo.png', 10, 297 - 30 - 21, 100, 30, 'PNG', '', 'N', false); // pdf表示設定 $pdf->Output('pdf-img-6-2.pdf', 'I'); ?>
実行結果は以下の様な表示になります。
最初の画像表示は1ページにおさまらないので、2ページ目のマージンの先頭から画像が表示されています。
2番目の画像表示は、2ページ目におさまるため2ページ目の一番下の方に表示されます。
依って Image メソッドのでは指定された「Y座標」+画像の縦サイズがそのページにおさまらない場合は、 「Y座標」は次のページの先頭になる様です。 この点は注意が必要かと思います。■画像が回転して表示される場合の処理(Exif)
Image メソッドで スマートフォンなどでカメラ機能で画像を取り込んだものをそのまま表示すると、回転して表示される場合があります。
このテストですが、仮に回転する画像データを Image メソッドで表示させてみます。<?php require_once('../tcpdf/tcpdf.php'); // クラス生成 $pdf = new TCPDF(); // デフォルトで用意されている日本語フォント[小塚ゴシックPro M] $strFont = "kozgopromedium"; // ヘッダ・フッタ出力設定(特にいらないが) $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); // 本文の日本語フォント[小塚ゴシックPro M] $pdf->SetFont($strFont, "", 10); // 新しいpdfページを追加 $pdf->AddPage(); // HTMLの定義 $strOut = '<h1>HTML Imageテスト・回転1</h1>'; $pdf->writeHTML($strOut, true, false, true, false, ''); // 画像ファイルをそのまま表示 $pdf->Image('trotate.jpg', null, null, 100, 0, 'JPG', '', 'N', false); // pdf表示設定 $pdf->Output('pdf-img-6-3-1.pdf', 'I'); ?>
(この画像は右に90度回転しています)
回転する画像ファイルをHTMLのimgタグで表示させるようにしてHTMLファイルを作成します。<html> <head> <meta charset="utf-8"> <title>HTML TABLE</title> </head> <body> <h2>HTML 回転する画像データテスト</h2> <img src="trotate.jpg" width="600" /> </body> </html>
ブラウザで表示させると、正しく回転を直してくれています。これはブラウザ側で「Exif」情報を元に画像データの回転補正を行っている様です。
この結果から、画像ファイルの「Exif」情報を元に画像データの回転補正を行う様にソースにその処理を追加してみます。 ソースは以下の様になります。<?php /** * 画像の回転 * @access private * @param string $strImagePath 画像ファイルフルパス * @return string 回転後の画像ファイルフルパス */ function rotateImageFile($strImagePath) { // EXIF取得 $exif = @exif_read_data($strImagePath); $exif = $exif ? $exif : []; $orientation = $exif['Orientation'] ?? 1; if ($orientation == 1) { // 回転無し:そのままファイルパスを返す return $strImagePath; } // 画像イメージ $image = imagecreatefromstring(file_get_contents($strImagePath)); // 画像の回転処理 $image = rotateImage($image, $orientation); // 保存 $filetype = pathinfo($strImagePath, PATHINFO_EXTENSION); $strTmpFile = date('YmdHis')."-img.".$filetype; imagejpeg($image, $strTmpFile); // 保存先を返す return $strTmpFile; } /** * 画像を回転させる * @param object $image 画像イメージデータ * @param integer $orientation 回転フラグ * @return resource */ function rotateImage($image, $orientation) { switch ($orientation) { case 1: // 何もしない break; case 2: // 水平方向の反転 imageflip($image, IMG_FLIP_HORIZONTAL); break; case 3: // 180度回転 $image = imagerotate($image, 180, 0); break; case 4: // 垂直方向の反転 imageflip($image, IMG_FLIP_VERTICAL); break; case 5: // 右270度回転、水平方向の反転 $image = imagerotate($image, 270, 0); imageflip($image, IMG_FLIP_HORIZONTAL); break; case 6: // 右270度回転 $image = imagerotate($image, 270, 0); break; case 7: // 右90度回転して水平方向反転 $image = imagerotate($image, 90, 0); imageflip($image, IMG_FLIP_HORIZONTAL); break; case 8: // 右90度回転 $image = imagerotate($image, 90, 0); break; } return $image; } require_once('../tcpdf/tcpdf.php'); // クラス生成 $pdf = new TCPDF(); // デフォルトで用意されている日本語フォント[小塚ゴシックPro M] $strFont = "kozgopromedium"; // ヘッダ・フッタ出力設定(特にいらないが) $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); // 本文の日本語フォント[小塚ゴシックPro M] $pdf->SetFont($strFont, "", 10); // 新しいpdfページを追加 $pdf->AddPage(); // HTMLの定義 $strOut = '<h1>HTML Imageテスト・回転3</h1>'; $pdf->writeHTML($strOut, true, false, true, false, ''); // 画像ファイルをそのまま表示 $strFile = 'trotate.jpg'; $pdf->Image($strFile, null, null, 100, 0, 'JPG', '', 'N', false); $pdf->writeHTML('', true, false, true, false, ''); // 画像ファイルの回転 $strRotateFile = rotateImageFile($strFile); $pdf->Image($strRotateFile, null, null, 100, 0, 'JPG', '', 'N', false); if ($strRotateFile != $strFile) { // 画像ファイルが回処理されている場合、削除 unlink($strRotateFile); } // pdf表示設定 $pdf->Output('pdf-img-6-3-3.pdf', 'I'); ?>
実行結果は以下の様な表示になります。
回転処理は全てをテストしていませんので、悪しからずお願いします。
-
「 PHP PDF出力の方法について・マージンとヘッダ/フッタ(TCPDF)」 の記事ではいきなり Image メソッド使いましたが、今回はこのメソッドについてどの位使えるのかをテストしたいと思います。
Image メソッドの引数は以下の様になっています。// Imageメソッド public function Image($file, $x=null, $y=null, $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0, $fitbox=false, $hidden=false, $fitonpage=false, $alt=false, $altimgs=array()) // $file : 画像ファイル名 // $x : 領域左上のX座標[指定しない場合、現在のX座標位置] // $y : 領域左上のY座標[指定しない場合、現在のY座標位置] // $w : 領域の幅 [指定しない場合、自動計算される] // $h : 領域の高さ [指定しない場合、自動計算される] // $type : 画像フォーマット("JPEG", "PNG") // $link : AddLink()で作成したリンク識別子 // $align : 次の画像を表示する位置 // [T]: top-right for LTR or top-left for RTL // [M]: middle-right for LTR or middle-left for RTL // [B]: bottom-right for LTR or bottom-left for RTL // [N]: next line // $resize : [true]画像サイズを$wや$hに合わせてリサイズ // $dpi : 解像度(dot per inch) // $palign : 画像を現在の行のどこに配置するか // [L] : 左端 // [C] : 中央 // [R] : 右端 // ['']: 左端(RTLの場合は右端) // $ismask : [true]画像をマスクする場合 // $imgmask : 画像オブジェクトをメソッドの戻り値として取得する // (描画しない、w、h、x、yは無視される)場合true // $border : 境界線表示(0:枠無し,1:枠有 または "LRTB"の文字列で「左右上下」を指定) // $fitbox : [ture]($w, $h)で指定する領域に合わせて拡縮 // $hidden : [ture]画像を画面に表示しない // $fitonpage : [ture]ページの大きさに拡大する // $alt : If true the image will be added as alternative and not directly printed // (the ID of the image will be returned). // $altimgs : Array of alternate images IDs. Each alternative image must be an array with two values: // an integer representing the image ID (the value returned by the Image method) // and a boolean value to indicate if the image is the default for printing.
以下の各種のテストをしてみます。■画像の大きさ・リサイズ
画像データは以下のものを使います。画像の大きさは「100×30」ピクセルです。
この画像を使って以下の表示をテストします。- 画像の横幅・高さを指定しないでそのまま表示
- 画像の横幅・高さを指定して表示(20×6 mm)
- 画像の横幅・高さを指定して表示(100×30 mm)
- 画像の横幅・高さを指定して表示(100×30 mm) リサイズ指定有り
<?php require_once('../tcpdf/tcpdf.php'); // クラス生成 $pdf = new TCPDF(); // デフォルトで用意されている日本語フォント[小塚ゴシックPro M] $strFont = "kozgopromedium"; // ヘッダ・フッタ出力設定(特にいらないが) $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); // 本文の日本語フォント[小塚ゴシックPro M] $pdf->SetFont($strFont, "", 10); // 新しいpdfページを追加 $pdf->AddPage(); // HTMLの定義 $strOut = '<h1>HTML Imageテスト</h1>'; $pdf->writeHTML($strOut, true, false, true, false, ''); $strOut = '画像の横幅・高さを指定しないでそのまま表示(100×30 px)'; $pdf->cell(0, 0, $strOut, 0, 1); $pdf->Image('test-logo.png', null, null, 0, 0, 'PNG', '', 'N'); $unit = $pdf->pixelsToUnits(100);//px => mm $strOut = '画像の横幅(100px ==> mm 換算):'.$unit.'mm (pixelsToUnitsメソッド使用)'; $pdf->cell(0, 0, $strOut, 0, 1); $pdf->cell(0, 0, '', 0, 1); $strOut = '画像の横幅・高さを指定して表示(20×6 mm)'; $pdf->cell(0, 0, $strOut, 0, 1); $pdf->Image('test-logo.png', null, null, 20, 6, 'PNG', '', 'N', false,300); $pdf->cell(0, 0, '', 0, 1); $strOut = '画像の横幅・高さを指定して表示(100×30 mm)'; $pdf->cell(0, 0, $strOut, 0, 1); $pdf->Image('test-logo.png', null, null, 100, 30, 'PNG', '', 'N', false); $strOut = '画像の横幅・高さを指定して表示(100×30 mm) (resize:true 指定)'; $pdf->cell(0, 0, $strOut, 0, 1); $pdf->Image('test-logo.png', null, null, 100, 30, 'PNG', '', 'N', true, 300); // pdf表示設定 $pdf->Output('pdf-img-5-1.pdf', 'I'); ?>
これの実行結果は以下の通りです。
「画像の横幅・高さを指定しないでそのまま表示」の場合は実際PDF上でどのくらいの大きさで表示されるのかと言いますと、 画像データのピクセル値から DPI を加味して以下の計算で分かります。 (pixelsToUnits メソッドを使用すればピクセルからPDF上の長さが分かります。)
「画像のPDF上の横幅(mm)」=「画像の横幅ピクセル値」/(「PDFでの指定DPI」/「25.4」)
この画像の場合は、以下の計算となります。
「画像のPDF上の横幅(mm)」=「100px」/(「72」/「25.4」)=「35.2777…」
(「DPI」のデフォルトは「72」になっています)
「画像の横幅・高さを指定して表示(20×6 mm)」では指定通り「20×6 mm」に縮小された表示になっています。
また、「画像の横幅・高さを指定して表示(100×30 mm)」では指定通り「100×30 mm」に拡大された表示になっています。
最後のリサイズ指定を「true」にした場合ですが、指定しない場合との違いが良くわかりませんでした。 指定の仕方が悪いのかそれともテストした画像データが適切ではなかったのか?機会があればもう少し調べたいと思います。
■次の画像位置指定・現在行の表示位置
「次の画像位置指定」は「$align」の引数ですが指示内容は以下の通りです。
- 'T' 画像TOPでかつ右端
- 'M' 画像縦方向の中央でかつ右端
- 'T' 画像BOTTOMでかつ右端
- 'N' 次の行
この指定は、画像表示が終わった時点でカレントのX,Y座標をどの位置にするかを示します。
「現在行の表示位置」は「$palign」の引数ですが指示内容は以下の通りです。- 'L' 左揃え
- 'C' 中央揃え
- 'R' 右揃え
- '' 左揃え(RTLの場合は右端)
<?php require_once('../tcpdf/tcpdf.php'); // クラス生成 $pdf = new TCPDF(); // デフォルトで用意されている日本語フォント[小塚ゴシックPro M] $strFont = "kozgopromedium"; // ヘッダ・フッタ出力設定(特にいらないが) $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); // 本文の日本語フォント[小塚ゴシックPro M] $pdf->SetFont($strFont, "", 10); // 新しいpdfページを追加 $pdf->AddPage(); // HTMLの定義 $strOut = '<h1>HTML Imageテスト</h1>'; $pdf->writeHTML($strOut, true, false, true, false, ''); // 元の画像そのまま $pdf->writeHTML('<h4>元の画像(サイズ指定無し)</h4>', true, false, true, false, ''); $pdf->Image('test-logo.png', null, null, 0, 0, 'PNG'); // $align : 次の画像を表示する位置 $pdf->SetXY(0, 35); $pdf->writeHTML('<h4>次の画像の表示位置「$align」</h4>', true, false, true, false, ''); $pdf->Image('test-logo.png', null, 40, 0, 0, 'PNG', '', 'T'); //top-right $pdf->Image('test-logo.png', null, null, 0, 0, 'PNG', '', 'M'); //middle-right $pdf->Image('test-logo.png', null, null, 0, 0, 'PNG', '', 'B'); //bottom-right $pdf->Image('test-logo.png', null, null, 0, 0, 'PNG', '', 'N'); //next line $pdf->Image('test-logo.png', null, null, 0, 0, 'PNG', '', 'N'); //next line // $palign : 画像を現在の行のどこに配置するか $pdf->SetXY(0, 80); $pdf->writeHTML('<h4>現在行の配置指定「$palign」</h4>', true, false, true, false, ''); $pdf->writeHTML('<h4>・幅[50mm]指定・左寄せ</h4>', true, false, true, false, ''); $pdf->Image('test-logo.png', null, null, 40, 0, 'PNG', '', 'N', false, 300, 'L'); $pdf->writeHTML('<h4>・幅[50mm]指定・中央揃え</h4>', true, false, true, false, ''); $pdf->Image('test-logo.png', null, null, 40, 0, 'PNG', '', 'N', false, 300, 'C'); $pdf->writeHTML('<h4>・幅[50mm]指定・右寄せ</h4>', true, false, true, false, ''); $pdf->Image('test-logo.png', null, null, 40, 0, 'PNG', '', 'N', false, 300, 'R'); // pdf表示設定 $pdf->Output('pdf-img-5-2.pdf', 'I'); ?> ?>
実行結果は以下の様な表示になります。
■幅・高さ($w, $h)指定領域に合わせて拡縮
幅・高さ($w, $h)指定領域に合わせて拡縮を行う引数である「$fitbox」についてテストを行います。
「$fitbox」は2文字で指定し、1文字目は水平方向の配置指定で、2文字目は垂直方向の配置指定となります。
「1文字目は水平方向」- 'L' 左寄せ
- 'C' 中央揃え
- 'R' 右寄せ
「2文字目は垂直方向」
- 'T' 上寄せ
- 'M' 中央揃え
- 'B' 下寄せ
3種類ずつなので9種類の組み合わせがります。 但し、画像のサイズと描画領域($w, $h)の値により表示がいろいろあります。<?php require_once('../tcpdf/tcpdf.php'); // クラス生成 $pdf = new TCPDF(); // デフォルトで用意されている日本語フォント[小塚ゴシックPro M] $strFont = "kozgopromedium"; // ヘッダ・フッタ出力設定(特にいらないが) $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); // 本文の日本語フォント[小塚ゴシックPro M] $pdf->SetFont($strFont, "", 10); // 新しいpdfページを追加 $pdf->AddPage(); // HTMLの定義 $strOut = '<h1>HTML Imageテスト</h1>'; $pdf->writeHTML($strOut, true, false, true, false, ''); $pdf->Image('test-logo.png', null, null, 0, 0, 'PNG', '', 'N'); $unit = $pdf->pixelsToUnits(100);//px => mm $strOut = '画像の横幅(100px ==> mm 換算):'.$unit.'mm (pixelsToUnitsメソッド使用)'; $pdf->MultiCell( 0, 0, $strOut, 0, '', false, 1, 50, 18); $unit = $pdf->pixelsToUnits(30);//px => mm $strOut = '画像の高さ( 30px ==> mm 換算):'.$unit.'mm (pixelsToUnitsメソッド使用)'; $pdf->MultiCell( 0, 0, $strOut, 0, '', false, 1, 50, 23); // 引数「fitbox」用alignment $h_align = array('L', 'C', 'R'); $v_align = array('T', 'M', 'B'); $x = 15; $y = 32; $w = 30; $h = 7; // 横方向のアライメント for ($i = 0; $i < 3; ++$i) { $x = 15; for ($j = 0; $j < 3; ++$j) { $fitbox = $h_align[$i].$v_align[$j]; $pdf->Rect($x, $y, $w, $h, 'F', array(), array(128,255,128)); $pdf->Image('test-logo.png', $x, $y, $w, $h, 'PNG', '', '', false, 300, '', false, false, 0, $fitbox, false, false); $pdf->MultiCell( 0, 0, '$fitbox = '.$fitbox, 0, '', false, 1, $x, $y + $h); $x += 62; // カラムを右へ } $y += 14; // 次の行 } $x = 15; $y += 2; $w = 30; $h = 15; // 縦方向のアライメント for ($i = 0; $i < 3; ++$i) { $x = 15; for ($j = 0; $j < 3; ++$j) { $fitbox = $h_align[$i].$v_align[$j]; $pdf->Rect($x, $y, $w, $h, 'F', array(), array(255,128,128)); $pdf->Image('test-logo.png', $x, $y, $w, $h, 'PNG', '', '', false, 300, '', false, false, 0, $fitbox, false, false); $pdf->MultiCell( 0, 0, '$fitbox = '.$fitbox, 0, '', false, 1, $x, $y + $h); $x += 62; // カラムを右へ } $y += ($h + 6); // 次の行 } // pdf表示設定 $pdf->Output('pdf-img-5-3.pdf', 'I'); ?>
実行結果は以下の様な表示になります。
この表示領域の配置指定は、画像のサイズと描画領域($w, $h)の値により表示のされ方が独特です。
最初の9個のブロック(背景が黄緑色)は1文字目の指定の水平方向しか動作していない様に見えます。
また、その下の9個のブロック(背景が薄赤色)は2文字目の指定の垂直方向しか動作していない様に見えます。
最初のブロックの場合、「$w = 30」「$h = 7」(単位はmm)で指定しています。
画像の大きさは「100×30px」ですので横を基準とした場合の「縦」を計算します。
「縦」=「30($w)」×(「30px」/「100px」)=「9」mm
「縦=9mm」では指定の「$h = 7」を超えてしまうので、逆に「$h = 7」を基準にして「横」を計算します。
「横」=「7($h)」×(「100px」/「30px」)=「23.3…」mm
「横=23.3…mm」で指定の「$w = 30」におさまります。 よって、垂直方向は一杯になり水平方向しか配置が動作しない様に見えるわけです。
2番目のブロックの場合、「$w = 30」「$h = 15」(単位はmm)で指定しています。
画像の大きさは「100×30px」ですので横を基準とした場合の「縦」を計算します。
「縦」=「30($w)」×(「30px」/「100px」)=「9」mm
さらにに「$h = 15」を基準にして「横」を計算します。
「横」=「15($h)」×(「100px」/「30px」)=「50」mm
「横=50mm」のため「$w = 30」の指定を超えてしまいます。 よって、「縦=9mm」の画像として、水平方向は一杯になり垂直方向しか配置が動作しない様に見えるわけです。
-
一連のPDF出力の初回の 「PHP PDF出力の方法について(TCPDF)」 の記事ではいきなり writeHTML メソッド使いましたが、今回はこのメソッドについてどの位使えるのかをテストしたいと思います。
writeHTML メソッドの引数は以下の様になっていますので、大まかに各引数について説明します。// writeHTMLメソッド public function writeHTML($html, $ln=true, $fill=false, $reseth=false, $cell=false, $align='') // $html : 出力するHTMLテキスト // $ln : 改行指定[true:改行](デフォルト:true) // $fill : 背景の塗つぶし指定 [false:透明(既定) true:塗つぶす](デフォルト:false) // $reseth : [true]前回の高さ設定をリセットする。[false]引き継ぐ // $cell : [true]setCellPadding()で設定されたセルのpaddingを挿入する // $align : テキストの整列を指定 // [L] or 空文字: 左揃え(既定) // [C]: 中央揃え // [R]: 右揃え // [J]: 両端揃え
各種の HTML タグをテストしてみます。■リストタグ
HTML では ul、ol、li の3つのタグを使ってリストを作ることができますが、 「ul、li」または「ol、li」のセットで指定をします。 各リストの項目に以下の様な修飾タグをテストしてみます。
- 画像表示タグ:<img>
- 文字の太字(ボールド):<b>
- 文字のイタリック:<i>
- 文字の下線(アンダーライン):<u>
- アンカータグ:<a>
- 文字の取消線:<del>
- フォントサイズ:<font>
- 下付き文字要素:<sub>
- 上付き文字要素:<sup>
<?php require_once('../tcpdf/tcpdf.php'); // クラス生成 $pdf = new TCPDF(); // デフォルトで用意されている日本語フォント[小塚ゴシックPro M] $strFont = "kozgopromedium"; // ヘッダ・フッタ出力設定(特にいらないが) $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); // 本文の日本語フォント[小塚ゴシックPro M] $pdf->SetFont($strFont, "", 10); // 新しいpdfページを追加 $pdf->AddPage(); // HTMLの定義 $html = <<< EOF <h1>HTML リストタグテスト(<ol> <li>)(<ul> <li>)</h1> <h4>リスト例:(<ol> <li>)</h4> <ol> <li><img src="test-logo.png" alt="" width="100" height="" border="0" />イメージ テスト</li> <li><b>ボールド テスト</b></li> <li><i>イタリック テスト</i></li> <li><u>下線 テスト</u></li> <li><b>ボールド <i>ボールド・イタリック <u>ボールド・イタリック・下線</u></i></b></li> <li><a href="https://www.yahoo.co.jp/" dir="ltr">https://www.yahoo.co.jp/へのリンク</a></li> <li>これは改行の<br />が文字列の中に入るテストです。<br /> ここは2行目です。<br /> ここは3行目です。 </li> <li>サブリスト <ol> <li>サブリスト1行目 <ul> <li>さらにサブリスト1行目</li> <li>さらにサブリスト2行目</li> </ul> </li> <li>サブリスト1行目</li> </ol> </li> <li><del>取り消し線 テスト</del></li> <li><font size="+3">フォントサイズ テスト:"+ 3"</font></li> <li><small>フォント:small</small> フォント:通常 <sub>下付き文字要素</sub> 通常に戻す <sup>上付き文字要素</sup> 通常に戻す</li> </ol> <h4>リスト例:(<ul> <li>)</h4> <ul> <li><b>ボールド テスト</b></li> <li><i>イタリック テスト</i></li> <li><u>下線 テスト</u></li> </ul> EOF; // HTML書式で出力する $pdf->writeHTML($html); // pdf表示設定 $pdf->Output('pdfwrtHTML-1.pdf', 'I'); // 'I':ブラウザに出力する(既定) ?>
これの実行結果は以下の通りです。
■TABLEタグテスト
TABLEタグの以下の様なテスト行ってみます。
- TABLEの border, cellspacing, cellpadding 属性
- <th> の align 属性
- <td> の align, bgcolor, colspan 属性
- <td> のセル内の文字列属性(イタリック、aタグ、下付き文字、上付き文字など)
- <td> のセル内の TABLE 記述
- <td> の color, bgcolor, colspan, rowspan 属性
<?php require_once('../tcpdf/tcpdf.php'); // クラス生成 $pdf = new TCPDF(); // デフォルトで用意されている日本語フォント[小塚ゴシックPro M] $strFont = "kozgopromedium"; // ヘッダ・フッタ出力設定(特にいらないが) $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); // 本文の日本語フォント[小塚ゴシックPro M] $pdf->SetFont($strFont, "", 10); // 新しいpdfページを追加 $pdf->AddPage(); // HTMLの定義 $html = '<h2>HTML TABLEテスト</h2> <table border="1" cellspacing="6" cellpadding="4"> <tr> <td>a</td> <td>b</td> </tr> <tr> <td>c</td> <td>d</td> </tr> </table>'; $html = '<h2>HTML TABLEテスト</h2> <table border="1" cellspacing="3" cellpadding="4"> <tr> <th>タイトル</th> <th align="right">右寄せタイトル</th> <th align="left">左寄せタイトル</th> <th align="center">中央揃えタイトル</th> </tr> <tr> <td>通常のtd</td> <td bgcolor="#cccccc" align="center" colspan="2"> <i>イタリックテスト</i> aタグテスト<a href="https://www.yahoo.co.jp/">yahoo</a> 最後に改行<br /> <small>フォント:small</small> フォント:通常 <sub>下付き文字要素</sub> 通常に戻す <sup>上付き文字要素</sup> 通常に戻す <ol> <li>リスト1番目 <ol> <li>サブリスト1番目</li> <li>サブリスト2番目</li> </ol> </li> <li>リスト2番目</li> </ol> <small color="#FF0000" bgcolor="#FFFF00">小文字指定「small」の文字列テスト</small> </td> <td align="center">中央揃え td:4B</td> </tr> <tr> <td> セルの中のTABLE<br /> <table border="1" cellspacing="3" cellpadding="4"> <tr> <td>a</td> <td>b</td> </tr> <tr> <td>c</td> <td>d</td> </tr> </table> </td> <td bgcolor="#0000FF" color="yellow" align="center">[背景色:青色][中央揃え]</td> <td bgcolor="#FFFF00" align="left">[中央揃え]<font color="#FF0000">[赤]</font>[背景色:黄色]</td> <td>4C</td> </tr> <tr> <td>セル:1A</td> <td rowspan="2" colspan="2" bgcolor="#FFFFCC">セル:2AA<br />セル:2AB<br />セル:2AC</td> <td bgcolor="#FF0000">セル:4D</td> </tr> <tr> <td>セル:1B</td> <td>セル:4E</td> </tr> <tr> <td>セル:1C</td> <td align="right" >右寄せセル:2C</td> <td align="left" >左寄せセル:3C</td> <td align="center">中央揃えセル:4F</td> </tr> </table>'; // HTML書式で出力する $pdf->writeHTML($html); // pdf表示設定 $pdf->Output('pdfwrtHTML-2.pdf', 'I'); // 'I':ブラウザに出力する(既定) ?>
実行結果は以下の様な表示になります。 TABLEタグの描画は普通の使い方であれば、結構できそうな感じです。
■TABLEタグテスト・その2(注意点)
引き続きTABLEタグテストを行いますが、注意点を示そうと思い以下のソースをテストしてみます。
setPrintHeader(false); $pdf->setPrintFooter(false); // 本文の日本語フォント[小塚ゴシックPro M] $pdf->SetFont($strFont, "", 10); // 新しいpdfページを追加 $pdf->AddPage(); // HTMLの定義 $html = '<h2>HTML TABLEの中の画像データテスト</h2> <table cellpadding="1" cellspacing="1" border="1" style="text-align:center;"> <tr> <td height="50"><img src="test-logo.png" border="0" width="100" /></td> </tr> <tr style="text-align:left; vertical-align:top;"> <td height="50"><img src="test-logo.png" border="0" width="100" /></td> </tr> <tr style="text-align:center; vertical-align:middle;"> <td height="50"><img src="test-logo.png" border="0" width="100" /></td> </tr> <tr style="text-align:right; vertical-align:bottom;"> <td height="50"><img src="test-logo.png" border="0" width="100" /></td> </tr> </table>'; // HTML書式で出力する $pdf->writeHTML($html); // pdf表示設定 $pdf->Output('pdfwrtHTML-3.pdf', 'I'); // 'I':ブラウザに出力する(既定) ?>
実行結果は以下の様な表示になります。
画像の縦の配置を tr タグのスタイルで style="vertical-align:middle;" などと指定したのですが、常にTOP位置での表示になります。
HTML ソースでこれを以下の様に記述して、ブラウザで表示させると、正しい表示になります。<html> <head> <meta charset="utf-8"> <title>HTML TABLE</title> </head> <body> <h2>HTML TABLEの中の画像データテスト</h2> <table cellpadding="1" cellspacing="1" border="1" style="text-align:center;" width="800"> <tr> <td height="50"><img src="test-logo.png" border="0" width="100" /></td> </tr> <tr style="text-align:left; vertical-align:top;"> <td height="50"><img src="test-logo.png" border="0" width="100" /></td> </tr> <tr style="text-align:center; vertical-align:middle;"> <td height="50"><img src="test-logo.png" border="0" width="100" /></td> </tr> <tr style="text-align:right; vertical-align:bottom;"> <td height="50"><img src="test-logo.png" border="0" width="100" /></td> </tr> </table> </body> </html>
実行結果は以下の様な表示になります。
writeHTML メソッドでは、どうも css (スタイル)の指定で style="vertical-align:xxxxx;" は効かない様です。
ネットで調べると以下の css (スタイル)しか指定できない様です。
font-family, font-size, font-weight, font-style, color, background-color, text-decoration, width, height, text-align
vertical-align が使えないとなると改行などで位置合わせをする必要がありそうです。
■前景色、背景色の色名テスト
TCPDF ではPHPのプログラムでWEB上のカラー名を宣言してありますので、それを利用できます。
TCPDF_COLORS クラスのstatic宣言されている $webcolor がそれで、キーにカラー名、値にRGBの16進表記の数値文字列が定義されています。
以下に使用例を示します。<?php require_once('../tcpdf/tcpdf.php'); // クラス生成 $pdf = new TCPDF(); // デフォルトで用意されている日本語フォント[小塚ゴシックPro M] $strFont = "kozgopromedium"; // ヘッダ・フッタ出力設定(特にいらないが) $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); // 本文の日本語フォント[小塚ゴシックPro M] $pdf->SetFont($strFont, "", 10); // 新しいpdfページを追加 $pdf->AddPage(); // HTMLの定義 $strOut = '<h1>HTML カラー名テスト</h1>'; $strOut .= '<h2>前景色</h2>'; $strColor = 'red'; $strColorHex = TCPDF_COLORS::$webcolor[$strColor]; $strOut .= '<span color="#'.$strColorHex.'">'.$strColor.'-test</span><br />'; $strColor = 'green'; $strColorHex = TCPDF_COLORS::$webcolor[$strColor]; $strOut .= '<span color="#'.$strColorHex.'">'.$strColor.'-test</span><br />'; $strColor = 'blue'; $strColorHex = TCPDF_COLORS::$webcolor[$strColor]; $strOut .= '<span color="#'.$strColorHex.'">'.$strColor.'-test</span><br />'; $pdf->writeHTML($strOut, true, false, true, false, ''); $strOut = '<h2>背景色</h2>'; $strColor = 'red'; $strColorHex = TCPDF_COLORS::$webcolor[$strColor]; $strOut .= '<span bgcolor="#'.$strColorHex.'" color="white">'.$strColor.'-test</span><br />'; $strColor = 'green'; $strColorHex = TCPDF_COLORS::$webcolor[$strColor]; $strOut .= '<span bgcolor="#'.$strColorHex.'" color="white">'.$strColor.'-test</span><br />'; $strColor = 'blue'; $strColorHex = TCPDF_COLORS::$webcolor[$strColor]; $strOut .= '<span bgcolor="#'.$strColorHex.'" color="white">'.$strColor.'-test</span><br />'; $pdf->writeHTML($strOut, true, false, true, false, ''); // pdf表示設定 $pdf->Output('pdfwrtHTML-4-1.pdf', 'I'); // 'I':ブラウザに出力する(既定) ?>
実行結果は以下の様な表示になるはずです。
ちなみに宣言されているカラー名を全て表示すると以下の様になります。<?php require_once('../tcpdf/tcpdf.php'); // クラス生成 $pdf = new TCPDF(); // デフォルトで用意されている日本語フォント[小塚ゴシックPro M] $strFont = "kozgopromedium"; // ヘッダ・フッタ出力設定(特にいらないが) $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); // 本文の日本語フォント[小塚ゴシックPro M] $pdf->SetFont($strFont, "", 10); // 新しいpdfページを追加 $pdf->AddPage(); // HTMLの定義 $strOut = '<h1>HTML カラー名テスト</h1>'; $strOut .= '<h2>前景色</h2>'; foreach(TCPDF_COLORS::$webcolor as $k => $v) { $strOut .= '<span color="'.$k.'">'.$v.'</span> '; } $strOut .= '<h2>背景色</h2>'; foreach(TCPDF_COLORS::$webcolor as $k => $v) { $strOut .= '<span bgcolor="'.$k.'" color="#404040">'.$v.'</span> '; } $pdf->writeHTML($strOut, true, false, true, false, ''); // pdf表示設定 $pdf->Output('pdfwrtHTML-4-2.pdf', 'I'); // 'I':ブラウザに出力する(既定) ?>
実行結果は以下の様な表示になるはずです。
-
今回は TCPDF に備わっている トランザクション処理 について説明したいと思います。
トランザクション処理と言えばデータベースでの更新処理には付きものの処理で PHP でプログラムした方であれば使用したことがあると思います。
TCPDF に備わっているトランザクション処理も、データベース処理でのものとよく似ています。
トランザクションを開始し処理がOKであればコミットを行い、何か問題があればロールバックすることになります。
TCPDF のトランザクション処理メソッドは以下の通りです。- startTransaction() : トランザクション開始
- commitTransaction() : トランザクションコミット
- rollbackTransaction() : トランザクションロールバック
それでは簡単な例として以下のソースを見て下さい。<?php require_once('../tcpdf/tcpdf.php'); // クラス生成 $pdf = new TCPDF(); // デフォルトで用意されている日本語フォント[小塚ゴシックPro M] $strFont = "kozgopromedium"; // ヘッダ・フッタ出力設定(特にいらないが) $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); // 本文の日本語フォント[小塚ゴシックPro M] $pdf->SetFont($strFont, "", 10); // 新しいpdfページを追加 $pdf->AddPage(); // valign テスト $pdf->Write(0, "transaction テスト\n"); // transaction開始 $pdf->startTransaction(); // 2行書込み $pdf->Write(0, "transaction - 1\n"); $pdf->Write(0, "transaction - 2\n"); // transactionリスタート $pdf->startTransaction(); // 1行書込み $pdf->Write(0, "transaction - 3\n"); // 最後のtransactionに戻る $pdf = $pdf->rollbackTransaction(); // 戻り値を元の「$pdf」にコピーに注意!! // transaction無し・2行書込み $pdf->Write(0, "transaction - 4\n"); $pdf->Write(0, "transaction - 5\n"); // transaction開始 $pdf->startTransaction(); // 1行書込み $pdf->Write(0, "transaction - 6\n"); // transactionコミット $pdf->commitTransaction(); // pdf表示設定 $pdf->Output('pdftrans-1.pdf', 'I'); // 'I':ブラウザに出力する(既定) ?>
これの実行結果は以下の通りです。
この例で注意する点が startTransaction メソッドでトランザクションを開始し、PDF出力処理を行った後に再度トランザクションを開始しています。
そうしますと結果として再度のトランザクションはそれまでのトランザクションをコミットし、再度トランザクションを開始する様です。 その後 Write メソッドで「transaction - 3」の文字列の出力を行いますが、rollbackTransaction メソッドでロールバックを行うと、 「transaction - 3」の文字列が表示されなくなります。
rollbackTransaction メソッドの戻り値は TCPDF オブジェクトを返すのですが、 そのオブジェクトはトランザクションで貯めていたPDF出力操作がクリアな状態になります。
TCPDF のトランザクション処理はそこまで難しくは無いのですが、私としてはどの様な時に使うのかがいまいちよく分かりません。
■トランザクション処理のページ跨ぎのテスト
上記の例でトランザクション処理のロールバックにより、 startTransaction メソッドから rollbackTransaction メソッドに はさまれたPDF出力の処理が行われないことを説明しました。
ところで以前 MultiCell メソッドにおいて縦方向が伸長される場合があることを記しました。 その時、次のページへの伸長もあることを説明しましたが、これにトランザクション処理を入れた場合 ページの処理はどうなるかが気になりましたので、以下のソースでテストしてみました。<?php require_once('../tcpdf/tcpdf.php'); // クラス生成 $pdf = new TCPDF(); // デフォルトで用意されている日本語フォント[小塚ゴシックPro M] $strFont = "kozgopromedium"; // ヘッダ・フッタ出力設定(特にいらないが) $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); // 本文の日本語フォント[小塚ゴシックPro M] $pdf->SetFont($strFont, "", 10); // 新しいpdfページを追加 $pdf->AddPage(); // valign テスト $pdf->Write(0, 'valign テスト', '', false, '', true); $strAdd = "\r\n0123456789\r\n0123456789"; $strTxt = "\$valign['T']:Top \r\n\$align['L']左揃え" .$strAdd; // 以下の「MultiCell」の一連の処理をトランザクションで挟む // transaction開始 $pdf->startTransaction(); // 線のStyleで「破線」指示 $pdf->SetLineStyle(array('dash' => '2')); // 縦サイズ:20で文字列を表示 $h = 10; $y = 265; $pdf->MultiCell(60, $h, $strTxt, 1, 'L', false, 1, 10, $y, true, 0, false, true, 60,'T'); // ロールバック $pdf = $pdf->rollbackTransaction(); //$pdf->commitTransaction(); // 線のStyleで「破線」指示で、色がRGB指定で「赤」 $pdf->setPage(1); $pdf->SetLineStyle(array('dash' => '2', 'color' => array(255, 0, 0))); // 四角い枠線を表示(縦サイズ:20) $pdf->Rect( 10, $y, 60, $h, 'D'); // pdf表示設定 $pdf->Output('pdftrans-2.pdf', 'I'); ?>
これの実行結果は以下の通りです。
MultiCell メソッドの描画が割愛された表示になっているのが分かります。
ロールバックとコミットのコメントを入れ替えると、 ページが伸長され2ページ渡って MultiCell メソッドの描画が行われるはずです。