EC-CUBE4でwkhtmltopdfを利用する方法
EC-CUBE Advent Calendar 2022 12日目の記事です。
EC-CUBE4では、納品書出力という機能はtcpdf
というライブラリを利用してPDF出力を行なっています。
このライブラリは2系から利用されており非常に便利なのですが、レイアウトの修正など煩わしい問題があります。
今回は簡単にレイアウトの修正が行えるようにするwkhtmltopdf
というライブラリの利用方法を説明します。
wkhtmltopdf
というライブラリはhtmlをそのままpdfへと変換するライブラリとなります。詳しくは以下のURLを参照してください。
wkhtmltopdfのインストール
EC-CUBE4で利用するためには、こちらを参考に、
wkhtmltopdf
をcomposerコマンドを使ってインストールします。
composer require h4cc/wkhtmltopdf-amd64 0.12.x composer require h4cc/wkhtmltoimage-amd64 0.12.x
Macを利用されている方で正常にインストールできないという方は、下記よりダウンロードしてください。
https://wkhtmltopdf.org/downloads.html
KnpSnappyBundleのインストール
準備が整えば、今度はKnpSnappyBundle
というライブラリをインストールします。
インストール方法は記載されている通り、composerコマンドを利用します。
composer require knplabs/knp-snappy-bundle
その後、以下の設定を行います。
- app/config/eccube/bundles.phpの修正
return [ Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['all' => true], Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true], Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true, 'install' => true], Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true, 'install' => true], Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], Knp\Bundle\PaginatorBundle\KnpPaginatorBundle::class => ['all' => true], Exercise\HTMLPurifierBundle\ExerciseHTMLPurifierBundle::class => ['all' => true], Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true], Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true], Knp\Bundle\SnappyBundle\KnpSnappyBundle::class => ['all' => true], ];
Knp\Bundle\SnappyBundle\KnpSnappyBundle::class => ['all' => true],
を最終行に追加します。
- app/config/eccube/packages/knp_snappy.yamlの作成
knp_snappy: pdf: enabled: true binary: /usr/local/bin/wkhtmltopdf #"\"C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf.exe\"" for Windows users options: [] image: enabled: true binary: /usr/local/bin/wkhtmltoimage #"\"C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltoimage.exe\"" for Windows users options: [] temporary_folder: "%kernel.cache_dir%/snappy"
上記の通り、knp_snappy.yamlファイルを作成します。
PDFファイルの作成
準備が出来れば後はhtmlファイルやtwigファイルを作成するのみとなります。
- Contorollerに関数を追加
どのControllerクラスでも構いませんし、新規作成しても構いませんので一例として以下の関数を作成します。
<php ・ ・ use Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse; use Knp\Snappy\Pdf; ・ ・ /** * @Route("/outputpdf", name="outputpdf", methods={"GET"}) */ public function pdfAction(Pdf $knpSnappyPdf) { $html = $this->renderView('Pdf/outputpdf.twig', [ 'name' => 'ああああ', ]); return new PdfResponse( $knpSnappyPdf->getOutputFromHtml($html), 'output.pdf' ); }
- app/template/default/Pdf/outputpdf.twigファイルの作成
<!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <title>請求書</title> <style> body { font-family: "Hiragino Kaku Gothic ProN", "segoe ui", 'Noto Serif JP', serif, sans-serif; font-size: 1rem; line-height: 1.6; background: #fff; } main { position: relative; overflow: hidden; } </style> </head> <body> <header> <div class="wrap"> <div> <h2>請 求 書</h2> </div> </div> </header> <main> {{ name }} 様<br> 請求書の内容を作成 </main> </body> </html>
以上を作成後、http://xxxx/outputpdf
を入力するとtwigで作成されたものがPDFダウンロードされます。
あとは、twigファイルに対して出力したい内容を組み立てていけば、htmlを修正するだけで簡単にレイアウト変更が可能となります。
wkhtmltopdf
ですがflex
指定が出来ない時もありますのでhtmlを作成する場合、昔ながらの方法でcss指定を行なってください。
PDFが出力されず、
Exit with code 1 due to network error: ProtocolUnknownError
というエラーが発生した場合、画像やCSSファイルはフルパスで記述する必要がありますのでご注意ください。
wkhtmltopdfは横向きや縦向きなど色んなオプションが用意されています。
getOutputFromHtml
関数の第2引数に対して、
$options = [ 'encoding' => 'utf-8', 'page-size' => 'A4', 'margin-top' => '30px', 'margin-bottom' => '30px', 'margin-left' => '20px', 'margin-right' => '20px', ]; return new PdfResponse( $knpSnappyPdf->getOutputFromHtml($html, $options), 'output.pdf' );
とオプション指定すれば設定可能です。 オプションについては下記のURLをご覧ください。
https://wkhtmltopdf.org/usage/wkhtmltopdf.txt
PDFが動作しないという方はコメントに記載ください。