質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.52%

cakePHPのPDF出力について

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,848

 前提・実現したいこと

PDF出力にphp文を組み込みたい
(cakePHP3.6)

ここに質問の内容を詳しく書いてください。
"tecnickcom/tcpdf": "^6.2" を使ってpdf出力をしていますが、html以外無視するのか、php文を読み込みません。
Bootstrapも無視されます。
htmlのみの記述の時は綺麗に出力されます。

 発生している問題・エラーメッセージ

pdf出力した際、エラーはなく、php文で書いたところが空欄になってしまう

 該当のソースコード

cakePHP3.6
"tecnickcom/tcpdf": "^6.2"

MstPubController
...
// pdf出力をおこなうアクション
public function print()
  {
    $mstPub = $this->MstPub->newEntity();
// mstPubテーブルの全データをセット
    $this->set(compact('mstPub'));
    $this->response->type('pdf');
    $this->response->charset('UTF-8');
    // $this->response->download('print.pdf'); ブラウザ出力だけにするのでダウンロードはいらない
    $this->layout = false;
  }
...

print.ctp

<?php
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8');
$pdf->SetFont('kozgopromedium');
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->AddPage(); // 1ページ目を準備

$html = <<< EOF
<html>
<head>
    <style type="text/css">
    h1 {
        text-align: center;
    }
    </style>
</head>
<body>
<h1>店舗データ</h1>
<table border="1">
<thead>
      <tr>
        <th>店舗コード</th>
        <th>'店舗ネーム'</th>
      </tr>
</thead>
<tbody>
// ここから下が空欄で出力されてしまっている
<?php foreach ($mstPub as $mstPub): ?>
  <tr>
    <td><div class="text-center"><?= h($mstPub->pub_cd) ?></div></td>
    <td><div class="text-center"><?= h($mstPub->pub_name) ?></div></td>
  </tr>
<?php endforeach; ?>
</tbody>
</table>
</body>
</html>
EOF;
// 作った HTML を書きだします。
// PDF を出力 ( I = ブラウザ出力, D = ダウンロード, F = ローカルファイルとして保存, S = 文字列として出力 )
$pdf->writeHTML($html, false);
echo $pdf->Output('', 'I');
?>

 試したこと

純粋にhtmlとcssだけでtableタグ内を表記すると綺麗に表示され、問題ないのですが、それでは、mstPubテーブルのデータ一覧を渡すことができないので困っています。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

 自己解決しました

pdfにphpを埋め込んだものがネットにリソースが全然なかったのでかなり手こずりましたが、解決策は単純に

$html = <<< EOF
EOF;

のなかで変数を入れる時は、
<?= h($mstPub->pub_cd) ?> を使わずに
<td>$mstPub->pub_cd</td>みたいにそのままぶち込むこと、およびループなどの計算処理をEOF内で使わないことでした。

理由は <<< EOF ... EOF はphpで長い文字列の定義であるため、string型の変数に代入されている状態であり、
最後に $pdf->writeHTML($html, false); でただの文字列がhtml変換されているからです。
ゆえに、htmlで変換できない処理が文字列に加わるとエラーを吐かれます。

よって、ループでテーブルデータ一覧を表示させたい時はEOF外でforeach文を使って文字列連結させれば良いうまくいきました。

↓ソースコード

pdf出力アクション 
print.ctp

<?php
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8');
$pdf->SetFont('kozgopromedium');
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->AddPage(); // 1ページ目を準備

$html = <<< EOF
<html>
<head>
    <style type="text/css">
    h1 {
        text-align: center;
    }
    </style>
</head>
<body>
<h1>店舗データ</h1>
<table border="1">
<thead>
      <tr>
        <th>店舗コード</th>
        <th>店舗ネーム</th>
        <th>住所</th>
        <th>店舗種類コード</th>
        <th>店舗サービスコード</th>
        <th>紹介画像</th>
        <th>電話番号</th>
      </tr>
</thead>
EOF;

$pubData = "";
foreach ($mstPub as $mstPub) {
            $pubData .= "<tr><td>".$mstPub->pub_cd."</td>";
            $pubData .= "<td>".$mstPub->pub_name."</td>";
            $pubData .= "<td>".$mstPub->address1."</td>";

            $pubData .= "<td>";
            if ($mstPub->pub_type_cd){
                    if (isset($masterPubTypeValid[$mstPub->pub_type_cd])){
                      $pubData .= $masterPubTypeValid[$mstPub->pub_type_cd];
                    }
                  }
            $pubData .= "</td>";
            $pubData .= "<td>";

            // サービスコード変換
            if ($mstPub->pub_service_cd){
                $serviceCdArray = explode(",", $mstPub->pub_service_cd);
                foreach ($serviceCdArray as $value) {
                    if (isset($masterPubServiceValid[$value])){
            $pubData .= $masterPubServiceValid[$value]."<br>";
            }
          }
        }
            $pubData .= "</td>";
            $pubData .= "<td>".$mstPub->present_image."</td>";
            $pubData .= "<td>".$mstPub->tel_no."</td></tr>";
        }

$html .= <<< EOF
<tbody>
$pubData
</tbody>
</table>
</body>
</html>
EOF;

// 作った HTML を書きだします。
// PDF を出力 ( I = ブラウザ出力, D = ダウンロード, F = ローカルファイルとして保存, S = 文字列として出力 )
$pdf->writeHTML($html, false);
// echo $pdf->Output('', 'S');
echo $pdf->Output('', 'I');
?>
controller

public function print()
  {
    $mstPub = $this->MstPub->find()->all();
    $this->set(compact('mstPub'));
    $this->response->type('pdf');
    $this->response->charset('UTF-8');
    // $this->response->download('print.pdf');
    $this->layout = false;
  }

$masterPubTypeValidとか$masterPubServiceValidとかは見てもわからないでしょうが、大事なのは
<<< EOF が長文字列であるため、文字列の中に計算処理を入れないことです。
スッキリ
ちなみにbootstrapはpdfファイルでは適用されないため、cssでレイアウトしていく予定です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる