ITの隊長のブログ

ITの隊長のブログです。Rubyを使って仕事しています。最近も色々やっているお(^ω^ = ^ω^)

【CakePHP】Pluginと「wkhtmltopdf」を使って、viewをpdf化する方法

スポンサードリンク

あんましうまくいっていないけどメモ

環境

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.10.5
BuildVersion:   14F27

$ ./Console/cake
Welcome to CakePHP v2.6.11 Console

CakePHPも使うけど、すでにインストールされている前提で進めます。

「wkhtmltopdf」をインストール

wkhtmltopdf

↑のページからダウンロードできます。WindowsLinuxMac版がありました。

今回の環境はMacなので、Macにしています。

$ /usr/local/bin/wkhtmltopdf

ここにインストールされました。

CakePHPにPlugin「CakePdf」をインストール

CakePHPでPDF化するときに抽象化(?)してくれるPluginです。色々なモジュールが使えますが、今回は先程インストールした「wkhtmltopdf」を使います。

github.com

ここにインストールの手法が書かれています。私はgitで対応しました。

$ git submodule add git://github.com/friendsofcake/CakePdf.git Plugin/CakePdf
$ git submodule init
$ git submodule update

セットアップ

  • ~/Config/bootstrap
<?php
// ~ 省略 ~
CakePlugin::load('CakePdf', array('bootstrap' => true, 'routes' => true));
Configure::write('CakePdf', array(
    'engine' => 'CakePdf.WkHtmlToPdf',
    'binary' => '/usr/local/bin/wkhtmltopdf', // WkHtmlToPdfバイナリファイルのパス
    'options' => array(
        'print-media-type' => false,
        'outline' => true,
        'dpi' => 96
    ),
    'margin' => array(
        'bottom' => 5,
        'left' => 5,
        'right' => 5,
        'top' => 5
    ),
    'orientation' => 'portrait',
    'download' => false // 表示のみだったらfalseでおk、ダウンロードしたいんならtrue
));
  • ~/Config/routes.php
    Router::parseExtensions('pdf');

テスト

試して見ました。

  • ~/Controller/PdfTestController.php
<?php

App::uses('AppController', 'Controller');

class PdfTestController extends AppController {

    public $components = array('RequestHandler');

    public function index() {
        $this->render('/PdfTest/pdf/index');
    }
}
  • ~/View/Layout/pdf/default.ctp
<?php
/**
 * @link          http://cakephp.org CakePHP(tm) Project
 * @package       app.View.Layouts
 * @since         CakePHP(tm) v 0.10.0.1076
 */

?>
<!DOCTYPE html>
<html>
<head>
    <?php echo $this->Html->charset(); ?>
    <title>
        <?php echo $cakeDescription ?>:
        <?php echo $this->fetch('title'); ?>
    </title>
    <?php
        echo $this->Html->meta('icon');

        // echo $this->Html->css('cake.generic');

        // echo $this->fetch('meta');
        // echo $this->fetch('css');
        // echo $this->fetch('script');
    ?>
</head>
<body>
    <div id="container">
        <div id="header">
        </div>
        <div id="content">

            <?php echo $this->Session->flash(); ?>

            <?php echo $this->fetch('content'); ?>
        </div>
        <div id="footer">
            <?php /*echo $this->Html->link(
                    $this->Html->image('cake.power.gif', array('alt' => $cakeDescription, 'border' => '0')),
                    'http://www.cakephp.org/',
                    array('target' => '_blank', 'escape' => false)
                );*/
            ?>
        </div>
    </div>
    <?php echo $this->element('sql_dump'); ?>
</body>
</html>
  • ~/View/PdfTest/pdf/index.ctp
<style>
  li {
    list-style:none;
    float:left;
    margin-left:10px;
  }
</style>

<ul>
  <?php for ($i = 0; $i <= 100; $i++) : ?>
    <li>テスト</li>
  <?php endfor; ?>
</ul>
<br clear="all" />


<ul>
  <?php for ($i = 0; $i <= 1000; $i++) : ?>
    <li>テスト</li>
  <?php endfor; ?>
</ul>

こうするとですね。

f:id:aipacommander:20150909200604p:plain

とまぁ、こんな感じになります。

よくわからないこと

cakephp CakePdf due to network error: OperationCanceledError

エラーが良く出ました。お気づきの方もいると思いますが、先程用意した~/View/Layout/pdf/default.ctpCakePHPのデフォとから少し修正しています。

実は外部読み込みのコードを削除しています。理由は不明ですが、外部読み込みのコードがあるとこのエラーが出力して500エラーになります。

検索してみても難しい英語ばかりでいまいちピンときていないんですが、どうにか解決したいです。

雑メモ

以前、tcpdfを使ったことがありますが、これより遥かに便利ですね!

cssborderborder-radiusも動いてくれるし、またHtml & cssでページ改行もしてくれるのですごく楽です。

これどうにか使いこなせないかなー。(そうすると近いうち来るプロジェクトがすごく楽になりそう)

期待する。