参考サイト
はじめに
こんにちは。
今週全くブログを書けておらずめちゃめちゃ焦っている僕です。
仕事が忙しくて書けなかったのです。。。
でも仕事が忙しいからっていって、結局書けずじまいというのは絶対に嫌だったので、頑張って時間作って書こうと思います。
@kakakakakkuさんも言ってるしね。忙しくてブログ書けませんでした。とは言わないぞ!
今回は前回と似たようなものので、pythonのPDFライブラリPyPDF2 + PdfFormFiller
とPHPのtcpdf + fpdf
どっちが使いやすいの??っていう検証です。
前回はエクセルの取扱で比べたのですが、PDFもwebサービスやってるとよく使われる機能だったりするので、今回も調べてみました。
環境
php
$ php -v PHP 7.1.5 (cli) (built: May 22 2017 00:14:43) ( NTS ) Copyright (c) 1997-2017 The PHP Group Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies with Zend OPcache v7.1.5, Copyright (c) 1999-2017, by Zend Technologies with Xdebug v2.5.3, Copyright (c) 2002-2017, by Der
python
$ python --version Python 3.6.0 :: Anaconda 4.3.1 (x86_64)
事前準備
$ mkdir -p pdf_test/php $ mkdir pdf_test/python $ cd pdf_test/php/ $ composer require tecnickcom/tcpdf $ composer require setasign/fpdi $ composer require setasign/fpdi-tcpdf $ composer require setasign/fpdf $ pip install PyPDF2 pdfformfiller
今回はよくある、PDFにデータを書き込んで、ダウンロードさせる的な機能を想定して、ダウンロードさせる対象のPDFファイルを作成する部分までを検証しようと思います。
使用するPDFのテンプレートは、とりあえず簡単な職務経歴書的なのを作ってみました。
このテンプレートPDFをtest_pdf_template.pdfとして、それぞれ先程作った、pdfフォルダ、pythonフォルダに置いておきます。
php
では早速php側やってみます。
<?php require_once './vendor/autoload.php'; $pdf = new \setasign\Fpdi\TcpdfFpdi("L"); $pdf->setSourceFile(realpath(__DIR__) . '/test_pdf_template.pdf'); var_dump($pdf);
一旦これで読み取れるかを実験したところ、早速エラー
$ php sample.php PHP Fatal error: Uncaught setasign\Fpdi\PdfParser\CrossReference\CrossReferenceException: This PDF document probably uses a compression technique which is not supported by the free parser shipped with FPDI.
調べてみると結構同じような罠に引っかかっている人がいるようでした。
PDFが圧縮されているからフリー版のFPDIでは扱えないということらしいのですがそのためだけにacrobatを落とすの辛いなと思い、調べてると以下のサイトで再圧縮を書けてたところ、うまく読み取れました。
よかったよかった。
https://smallpdf.com/jp/compress-pdf
では改めて。
sample.php として以下を作成します。
<?php require_once './vendor/autoload.php'; $template_path = realpath(__DIR__) . '/test_pdf_template.pdf'; $output_path = realpath(__DIR__) . '/out.pdf'; $pdf = new \setasign\Fpdi\TcpdfFpdi("L"); $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); $pdf->setSourceFile($template_path); $pdf->addPage(); $importPage = $pdf->importPage(1); $pdf->useTemplate($importPage, 0, 0); // 開発期間 $pdf->SetFont("az", "", 7); $pdf->SetXY(14, 79, true); $pdf->MultiCell(0, 0, "2018/01/01 〜 <br />2018/01/31", 0, "J", false, 1, '', '', true, 0, true); $pdf->SetXY(14, 88, true); $pdf->MultiCell(0, 0, "2018/02/01 〜 <br />2018/02/28", 0, "J", false, 1, '', '', true, 0, true); $pdf->SetXY(14, 98, true); $pdf->MultiCell(0, 0, "2018/03/01 〜", 0, "J", false, 1, '', '', true, 0, true); // 業務内容 $pdf->SetFont("kozminproregular", "", 12); $pdf->Text(50, 79, "API開発"); $pdf->Text(50, 88, "ユーザー登録画面開発"); $pdf->Text(50, 96, "管理画面開発"); // 担当箇所 $pdf->Text(110, 79, "バックエンドのみ"); $pdf->Text(110, 88, "バックエンド & フロント"); $pdf->Text(110, 96, "バックエンド & フロント"); // 人数 $pdf->Text(188, 79, "2"); $pdf->Text(188, 88, "1"); $pdf->Text(188, 96, "4"); // ポジション $pdf->Text(202, 79, "PG"); $pdf->Text(202, 88, "PG"); $pdf->Text(202, 96, "PG"); // 開発環境 $pdf->SetFont("kozminproregular", "", 7); $pdf->SetXY(222, 79, true); $pdf->MultiCell(0, 0, "PHP7.1, MySQL5.7, Apache2.4<br />Redis, Git", 0, "J", false, 1, '', '', true, 0, true); $pdf->SetXY(222, 88, true); $pdf->MultiCell(0, 0, "PHP7.1, MySQL5.7, Apache2.4<br />Redis, Git", 0, "J", false, 1, '', '', true, 0, true); $pdf->SetXY(222, 96, true); $pdf->MultiCell(0, 0, "PHP7.1, MySQL5.7, Apache2.4<br />Redis, Git", 0, "J", false, 1, '', '', true, 0, true); $pdf->Output($output_path, "F");
実行します。
$ php sample.php
出来てました。これくらいのPDFならば実行速度は早いですね!
python
次pythonやってみます。
phpと同じく、sample.pyを作成してやってみます。
PHPの場合はTCPDFが内部で持っている kozminproregular
というフォントを使用していましたが、pythonの場合はネットで落として用意しました。
↑のフォントを同ディレクトリに置いて作業します。
# coding: utf-8 from reportlab.lib.styles import ParagraphStyle from reportlab.lib.enums import TA_CENTER from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont from pdfformfiller import PdfFormFiller # 準備(フォント設定、テンプレート読み込みなど) pdfmetrics.registerFont(TTFont('VL-Gothic-Regular', './python/VL-Gothic-Regular.ttf')) sty = ParagraphStyle('sty', alignment=TA_CENTER, fontName='VL-Gothic-Regular', fontSize=9) filler = PdfFormFiller("./python/test_pdf_template.pdf") # 開発期間 filler.add_text(u"2018/01/01〜<br />2018/01/31", 0, (40, 221), (110, 250), sty) filler.add_text(u"2018/02/01〜<br />2018/02/28", 0, (40, 245), (110, 275), sty) filler.add_text(u"2018/03/01〜", 0, (40, 275), (110, 310), sty) # 業務内容 filler.add_text(u"API開発", 0, (120, 225), (300, 250), sty) filler.add_text(u"ユーザー登録画面開発", 0, (120, 250), (300, 275), sty) filler.add_text(u"管理画面開発", 0, (120, 275), (300, 310), sty) # 担当箇所 filler.add_text(u"バックエンドのみ", 0, (320, 225), (500, 250), sty) filler.add_text(u"バックエンド & フロント", 0, (320, 250), (500, 275), sty) filler.add_text(u"バックエンド & フロント", 0, (320, 275), (500, 310), sty) # 人数 filler.add_text(u"2", 0, (480, 225), (600, 250), sty) filler.add_text(u"1", 0, (480, 250), (600, 275), sty) filler.add_text(u"4", 0, (480, 275), (600, 310), sty) # ポジション filler.add_text(u"PG", 0, (540, 225), (640, 250), sty) filler.add_text(u"PG", 0, (540, 250), (640, 275), sty) filler.add_text(u"PG", 0, (540, 275), (640, 310), sty) # 開発環境 filler.add_text(u"PHP7.1, MySQL5.7, Apache2.4<br />Redis, Git", 0, (615, 223), (770, 243), sty) filler.add_text(u"PHP7.1, MySQL5.7, Apache2.4<br />Redis, Git", 0, (615, 247), (770, 267), sty) filler.add_text(u"PHP7.1, MySQL5.7, Apache2.4<br />Redis, Git", 0, (615, 270), (770, 290), sty) filler.write('./python/output.pdf')
問題なし!
こちらも速度的には全く問題ない感じでした。
やってみて
どちらも、速度・結果ともに問題なしでした。
ただ、python(というか使用したライブラリ?)のほうが、より直感的にかけるイメージでした。
改行も
だし。
phpも一応しらべて
での改行を認識する書き方をしましたが、見ての通りコードのわかりやすさはpythonの方です。
あと、こちらも使用したライブラリによるかもしれませんが、pythonの方は、PHP側で起きた PDFが圧縮されているから読み込めない
というエラーは起きず、php側でエラーが起きたPDFでも問題なく開いて編集ができました。
勉強になりました。