src/Eccube/Service/OrderPdfService.php line 32

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  6.  *
  7.  * http://www.ec-cube.co.jp/
  8.  *
  9.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Eccube\Service;
  13. use Eccube\Common\EccubeConfig;
  14. use Eccube\Entity\BaseInfo;
  15. use Eccube\Entity\OrderItem;
  16. use Eccube\Entity\Shipping;
  17. use Eccube\Repository\BaseInfoRepository;
  18. use Eccube\Repository\OrderPdfRepository;
  19. use Eccube\Repository\OrderRepository;
  20. use Eccube\Repository\ShippingRepository;
  21. use Eccube\Twig\Extension\EccubeExtension;
  22. use Eccube\Twig\Extension\TaxExtension;
  23. use setasign\Fpdi\Tcpdf\Fpdi;
  24. /**
  25.  * Class OrderPdfService.
  26.  * Do export pdf function.
  27.  */
  28. class OrderPdfService extends Fpdi
  29. {
  30.     /** @var OrderRepository */
  31.     protected $orderRepository;
  32.     /** @var ShippingRepository */
  33.     protected $shippingRepository;
  34.     /** @var OrderPdfRepository */
  35.     protected $orderPdfRepository;
  36.     /** @var TaxRuleService */
  37.     protected $taxRuleService;
  38.     /**
  39.      * @var EccubeConfig
  40.      */
  41.     protected $eccubeConfig;
  42.     /**
  43.      * @var EccubeExtension
  44.      */
  45.     protected $eccubeExtension;
  46.     /**
  47.      * @var TaxExtension
  48.      */
  49.     protected $taxExtension;
  50.     // ====================================
  51.     // 定数宣言
  52.     // ====================================
  53.     /** ダウンロードするPDFファイルのデフォルト名 */
  54.     public const DEFAULT_PDF_FILE_NAME 'nouhinsyo.pdf';
  55.     /** FONT ゴシック */
  56.     public const FONT_GOTHIC 'kozgopromedium';
  57.     /** FONT 明朝 */
  58.     public const FONT_SJIS 'kozminproregular';
  59.     // ====================================
  60.     // 変数宣言
  61.     // ====================================
  62.     /** @var BaseInfo */
  63.     public $baseInfoRepository;
  64.     /** 購入詳細情報 ラベル配列
  65.      * @var array
  66.      */
  67.     protected $labelCell = [];
  68.     /*** 購入詳細情報 幅サイズ配列
  69.      * @var array
  70.      */
  71.     protected $widthCell = [];
  72.     /** 最後に処理した注文番号 @var string */
  73.     protected $lastOrderId null;
  74.     // --------------------------------------
  75.     // Font情報のバックアップデータ
  76.     /** @var string フォント名 */
  77.     protected $bakFontFamily;
  78.     /** @var string フォントスタイル */
  79.     protected $bakFontStyle;
  80.     /** @var string フォントサイズ */
  81.     protected $bakFontSize;
  82.     // --------------------------------------
  83.     // lfTextのoffset
  84.     protected $baseOffsetX 0;
  85.     protected $baseOffsetY = -4;
  86.     /** ダウンロードファイル名 @var string */
  87.     protected $downloadFileName null;
  88.     /** 発行日 @var string */
  89.     protected $issueDate '';
  90.     /**
  91.      * OrderPdfService constructor.
  92.      *
  93.      * @param EccubeConfig $eccubeConfig
  94.      * @param OrderRepository $orderRepository
  95.      * @param ShippingRepository $shippingRepository
  96.      * @param TaxRuleService $taxRuleService
  97.      * @param BaseInfoRepository $baseInfoRepository
  98.      * @param EccubeExtension $eccubeExtension
  99.      * @param TaxExtension $taxExtension
  100.      *
  101.      * @throws \Exception
  102.      */
  103.     public function __construct(EccubeConfig $eccubeConfigOrderRepository $orderRepositoryShippingRepository $shippingRepositoryTaxRuleService $taxRuleServiceBaseInfoRepository $baseInfoRepositoryEccubeExtension $eccubeExtensionTaxExtension $taxExtension)
  104.     {
  105.         $this->eccubeConfig $eccubeConfig;
  106.         $this->baseInfoRepository $baseInfoRepository->get();
  107.         $this->orderRepository $orderRepository;
  108.         $this->shippingRepository $shippingRepository;
  109.         $this->taxRuleService $taxRuleService;
  110.         $this->eccubeExtension $eccubeExtension;
  111.         $this->taxExtension $taxExtension;
  112.         parent::__construct();
  113.         // 購入詳細情報の設定を行う
  114.         // 動的に入れ替えることはない
  115.         $this->labelCell[] = 'バーコード';
  116.         $this->labelCell[] = 'JANコード';
  117.         $this->labelCell[] = '商品名';
  118.         $this->labelCell[] = '数量';
  119.         $this->labelCell[] = '定価';
  120.         $this->labelCell[] = '棚コード';
  121.         $this->labelCell[] = '出荷';
  122.         $this->widthCell = [502852817178];
  123.         // Fontの設定しておかないと文字化けを起こす
  124.         $this->SetFont(self::FONT_SJIS);
  125.         // PDFの余白(上左右)を設定
  126.         $this->SetMargins(22);
  127.         // ヘッダーの出力を無効化
  128.         $this->setPrintHeader(false);
  129.         // フッターの出力を無効化
  130.         $this->setPrintFooter(true);
  131.         $this->setFooterMargin();
  132.         $this->setFooterFont([self::FONT_SJIS''8]);
  133.     }
  134.     /**
  135.      * 注文情報からPDFファイルを作成する.
  136.      *
  137.      * @param array $formData
  138.      *                        [KEY]
  139.      *                        ids: 注文番号
  140.      *                        issue_date: 発行日
  141.      *                        title: タイトル
  142.      *                        message1: メッセージ1行目
  143.      *                        message2: メッセージ2行目
  144.      *                        message3: メッセージ3行目
  145.      *                        note1: 備考1行目
  146.      *                        note2: 備考2行目
  147.      *                        note3: 備考3行目
  148.      *
  149.      * @return bool
  150.      */
  151.     public function makePdf(array $formData)
  152.     {
  153.         // 発行日の設定
  154.         $this->issueDate '作成日: '.$formData['issue_date']->format('Y年m月d日');
  155.         // ダウンロードファイル名の初期化
  156.         $this->downloadFileName null;
  157.         // データが空であれば終了
  158.         if (!$formData['ids']) {
  159.             return false;
  160.         }
  161.         // 出荷番号をStringからarrayに変換
  162.         $ids explode(','$formData['ids']);
  163.         foreach ($ids as $id) {
  164.             $this->lastOrderId $id;
  165.             // 出荷番号から出荷情報を取得する
  166.             /** @var Shipping $Shipping */
  167.             $Shipping $this->shippingRepository->find($id);
  168.             if (!$Shipping) {
  169.                 // 出荷情報の取得ができなかった場合
  170.                 continue;
  171.             }
  172.             // テンプレートファイルを読み込む
  173.             $Order $Shipping->getOrder();
  174.             if ($Order->isMultiple()) {
  175.                 // 複数配送の時は読み込むテンプレートファイルを変更する
  176.                 $userPath $this->eccubeConfig->get('eccube_html_admin_dir').'/assets/pdf/nouhinsyo_multiple.pdf';
  177.             } else {
  178.                 $userPath $this->eccubeConfig->get('eccube_html_admin_dir').'/assets/pdf/nouhinsyo_multiple.pdf';
  179.             }
  180.             $this->setSourceFile($userPath);
  181.             //$tplidx = $this->pdf->ImportPage(1);
  182. //            $totalNumOfPages = $this->tcpdf->getNumPages();
  183.             // PDFにページを追加する
  184.             $this->addPdfPage();
  185.             // タイトルを描画する
  186.             //$this->renderTitle($formData['title']);
  187.             // 店舗情報を描画する
  188.             //$this->renderShopData();
  189.             // 注文情報を描画する
  190.             $this->renderOrderData($Shipping);
  191.             // メッセージを描画する
  192.             //$this->renderMessageData($formData);
  193.             // 出荷詳細情報を描画する
  194.             $this->renderOrderDetailData($Shipping);
  195.             // 備考を描画する
  196.             $this->renderEtcData($formData);
  197.         }
  198.         return true;
  199.     }
  200.     /**
  201.      * PDFファイルを出力する.
  202.      *
  203.      * @return string|mixed
  204.      */
  205.     public function outputPdf()
  206.     {
  207.         return $this->Output($this->getPdfFileName(), 'S');
  208.     }
  209.     /**
  210.      * PDFファイル名を取得する
  211.      * PDFが1枚の時は注文番号をファイル名につける.
  212.      *
  213.      * @return string ファイル名
  214.      */
  215.     public function getPdfFileName()
  216.     {
  217.         if (!is_null($this->downloadFileName)) {
  218.             return $this->downloadFileName;
  219.         }
  220.         $this->downloadFileName self::DEFAULT_PDF_FILE_NAME;
  221.         if ($this->PageNo() == 1) {
  222.             $this->downloadFileName 'nouhinsyo-No'.$this->lastOrderId.'.pdf';
  223.         }
  224.         return $this->downloadFileName;
  225.     }
  226.     /**
  227.      * フッターに発行日を出力する.
  228.      */
  229.     public function Footer()
  230.     {
  231.         $this->Cell(00$this->issueDate00'R');
  232.     }
  233.     /**
  234.      * 作成するPDFのテンプレートファイルを指定する.
  235.      */
  236.     protected function addPdfPage()
  237.     {
  238.         // ページを追加
  239.         $this->AddPage();
  240.         // テンプレートに使うテンプレートファイルのページ番号を取得
  241.         $tplIdx $this->importPage(1);
  242.         //var_dump($tplIdx);
  243.         // テンプレートに使うテンプレートファイルのページ番号を指定
  244.         $this->useTemplate($tplIdxnullnullnullnulltrue);
  245.         $this->setPageMark();
  246.     }
  247.     /**
  248.      * PDFに店舗情報を設定する
  249.      * ショップ名、ロゴ画像以外はdtb_helpに登録されたデータを使用する.
  250.      */
  251.     protected function renderShopData()
  252.     {
  253.         // 基準座標を設定する
  254.         $this->setBasePosition();
  255.         // ショップ名
  256.         $this->lfText(12560$this->baseInfoRepository->getShopName(), 8'B');
  257.         // 都道府県+所在地
  258.         $text $this->baseInfoRepository->getPref().$this->baseInfoRepository->getAddr01();
  259.         $this->lfText(12565$text8);
  260.         $this->lfText(12569$this->baseInfoRepository->getAddr02(), 8);
  261.         // 電話番号
  262.         $text 'TEL: '.$this->baseInfoRepository->getPhoneNumber();
  263.         $this->lfText(12572$text8); // TEL・FAX
  264.         // メールアドレス
  265.         if (strlen($this->baseInfoRepository->getEmail01()) > 0) {
  266.             $text 'Email: '.$this->baseInfoRepository->getEmail01();
  267.             $this->lfText(12575$text8); // Email
  268.         }
  269.         // インボイス登録番号
  270.         if (!empty($this->baseInfoRepository->getInvoiceRegistrationNumber())) {
  271.             $text '登録番号: '.$this->baseInfoRepository->getInvoiceRegistrationNumber();
  272.             $this->lfText(12579$text8);
  273.         }
  274.         // user_dataにlogo.pngが配置されている場合は優先的に読み込む
  275.         $logoFile $this->eccubeConfig->get('eccube_html_dir').'/user_data/assets/pdf/logo.png';
  276.         if (!file_exists($logoFile)) {
  277.             $logoFile $this->eccubeConfig->get('eccube_html_admin_dir').'/assets/pdf/logo.png';
  278.         }
  279.         $this->Image($logoFile1244640);
  280.     }
  281.     /**
  282.      * メッセージを設定する.
  283.      *
  284.      * @param array $formData
  285.      */
  286.     protected function renderMessageData(array $formData)
  287.     {
  288.         $this->lfText(2770$formData['message1'], 8); // メッセージ1
  289.         $this->lfText(2774$formData['message2'], 8); // メッセージ2
  290.         $this->lfText(2778$formData['message3'], 8); // メッセージ3
  291.     }
  292.     /**
  293.      * PDFに備考を設定数.
  294.      *
  295.      * @param array $formData
  296.      */
  297.     protected function renderEtcData(array $formData)
  298.     {
  299.         // フォント情報のバックアップ
  300.         $this->backupFont();
  301.         $this->Cell(010''01'C'0'');
  302.         // 行頭近くの場合、表示崩れがあるためもう一個字下げする
  303.         if (270 <= $this->GetY()) {
  304.             $this->Cell(010''01'C'0'');
  305.         }
  306.         $this->SetFont(self::FONT_GOTHIC'B'9);
  307.         $this->MultiCell(06'< 備考 >''T'2'L'0'');
  308.         $this->SetFont(self::FONT_SJIS''8);
  309.         $this->Ln();
  310.         // rtrimを行う
  311.         $text preg_replace('/\s+$/us'''$formData['note1']."\n".$formData['note2']."\n".$formData['note3']);
  312.         $this->MultiCell(04$text''2'L'0'');
  313.         // フォント情報の復元
  314.         $this->restoreFont();
  315.     }
  316.     /**
  317.      * タイトルをPDFに描画する.
  318.      *
  319.      * @param string $title
  320.      */
  321.     protected function renderTitle($title)
  322.     {
  323.         // 基準座標を設定する
  324.         $this->setBasePosition();
  325.         // フォント情報のバックアップ
  326.         $this->backupFont();
  327.         // 文書タイトル(納品書・請求書)
  328.         $this->SetFont(self::FONT_GOTHIC''15);
  329.         $this->Cell(010$title02'C'0'');
  330.         $this->Cell(066''02'R'0'');
  331.         $this->Cell(50''00'R'0'');
  332.         // フォント情報の復元
  333.         $this->restoreFont();
  334.     }
  335.     /**
  336.      * 購入者情報を設定する.
  337.      *
  338.      * @param Shipping $Shipping
  339.      */
  340.     protected function renderOrderData(Shipping $Shipping)
  341.     {
  342.         // 基準座標を設定する
  343.         $this->setBasePosition();
  344.         // フォント情報のバックアップ
  345.         $this->backupFont();
  346.         // =========================================
  347.         // 購入者情報部
  348.         // =========================================
  349.         $Order $Shipping->getOrder();
  350.         // 購入者都道府県+住所1
  351.         // $text = $Order->getPref().$Order->getAddr01();
  352.         $text $Shipping->getPref().$Shipping->getAddr01();
  353.         //$this->lfText(27, 47, $text, 10);
  354.         $this->lfText(518$text10);
  355.         //$this->lfText(27, 51, $Shipping->getAddr02(), 10); // 購入者住所2
  356.         $this->lfText(522$Shipping->getAddr02(), 10); // 購入者住所2
  357.         // 購入者氏名
  358.         if (null !== $Shipping->getCompanyName()) {
  359.             // 会社名
  360.             $text $Shipping->getCompanyName();
  361.             //$this->lfText(27, 57, $text, 11);
  362.             $this->lfText(526$text11);
  363.             // 氏名
  364.             $text $Shipping->getName01().' '.$Shipping->getName02().' 様';
  365.             //$this->lfText(27, 63, $text, 11);
  366.             $this->lfText(531$text11);
  367.         } else {
  368.             $text $Shipping->getName01().' '.$Shipping->getName02().' 様';
  369.             //$this->lfText(27, 59, $text, 11);
  370.             $this->lfText(531$text11);
  371.         }
  372.         // =========================================
  373.         // お買い上げ明細部
  374.         // =========================================
  375.         $this->SetFont(self::FONT_SJIS''10);
  376.         // ご注文日
  377.         $orderDate $Order->getCreateDate()->format('Y/m/d');
  378.         if ($Order->getOrderDate()) {
  379.             $orderDate $Order->getOrderDate()->format('Y/m/d');
  380.         }
  381.         //$this->lfText(25, 75, $orderDate, 10);
  382.         $this->lfText(2541$orderDate10);
  383.         // 注文番号
  384.         //$this->lfText(25, 80, $Order->getOrderNo(), 10);
  385.         $this->lfText(8041$Order->getOrderNo(), 10);
  386.         // 総合計金額
  387.         //if (!$Order->isMultiple()) {
  388.             //$this->SetFont(self::FONT_SJIS, 'B', 15);
  389.             //$paymentTotalText = $this->eccubeExtension->getPriceFilter($Order->getPaymentTotal());
  390.             //$this->setBasePosition(120, 95.5);
  391.             //$this->Cell(5, 7, '', 0, 0, '', 0, '');
  392.             //$this->Cell(67, 8, $paymentTotalText, 0, 2, 'R', 0, '');
  393.             //$this->Cell(0, 45, '', 0, 2, '', 0, '');
  394.         //}
  395.         // フォント情報の復元
  396.         $this->restoreFont();
  397.     }
  398.     /**
  399.      * 購入商品詳細情報を設定する.
  400.      *
  401.      * @param Shipping $Shipping
  402.      */
  403.     protected function renderOrderDetailData(Shipping $Shipping)
  404.     {
  405.         $arrOrder = [];
  406.         // テーブルの微調整を行うための購入商品詳細情報をarrayに変換する
  407.         // =========================================
  408.         // 受注詳細情報
  409.         // =========================================
  410.         $i 0;
  411.         $isShowReducedTaxMess false;
  412.         $Order $Shipping->getOrder();
  413.         /* @var OrderItem $OrderItem */
  414.         foreach ($Shipping->getOrderItems() as $OrderItem) {
  415.             //if (!$Order->isMultiple() && !$OrderItem->isProduct()) {
  416.             //    continue;
  417.             //}
  418.             // class categoryの生成
  419.             $classCategory '';
  420.             /** @var OrderItem $OrderItem */
  421.             if ($OrderItem->getClassCategoryName1()) {
  422.                 $classCategory .= ' [ '.$OrderItem->getClassCategoryName1();
  423.                 if ($OrderItem->getClassCategoryName2() == '') {
  424.                     $classCategory .= ' ]';
  425.                 } else {
  426.                     $classCategory .= ' * '.$OrderItem->getClassCategoryName2().' ]';
  427.                 }
  428.             }
  429.             // product
  430.             $productName $OrderItem->getProductName();
  431.             if (null !== $OrderItem->getProductCode()) {
  432.                 $productName .= ' / '.$OrderItem->getProductCode();
  433.             }
  434.             if ($classCategory) {
  435.                 $productName .= ' / '.$classCategory;
  436.             }
  437.             if ($this->taxExtension->isReducedTaxRate($OrderItem)) {
  438.                 $productName .= ' ※';
  439.                 $isShowReducedTaxMess true;
  440.             }
  441.             // バーコード
  442.             $arrOrder[$i][0] = '/var/www/data/order/barcode/'.$OrderItem->getProductCode().'.jpg';
  443.             // JANコード
  444.             $arrOrder[$i][1] = $OrderItem->getProductCode();
  445.             //商品名
  446.             $arrOrder[$i][2] = $OrderItem->getProductName();
  447.             // 購入数量
  448.             $arrOrder[$i][3] = number_format($OrderItem->getQuantity());
  449.             // 税込金額(単価)
  450.             $arrOrder[$i][4] = $this->eccubeExtension->getPriceFilter($OrderItem->getPrice());
  451.             // 小計(商品毎)
  452.             //$arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($OrderItem->getTotalPrice());
  453.             // 棚コード
  454.             $arrOrder[$i][5] = '';
  455.             // チェック
  456.             $arrOrder[$i][6] = '';
  457.             ++$i;
  458.         }
  459.         $i 0;
  460.         foreach ($Shipping->getProductOrderItems() as $ProductOrderItem) {
  461.             $productClass $ProductOrderItem->getProductClass();
  462.             // 棚コード
  463.             $arrOrder[$i][5] = $productClass->getrackNumber();
  464.             ++$i;
  465.         }
  466.         //if (!$Order->isMultiple()) {
  467.             // =========================================
  468.             // 小計
  469.             // =========================================
  470.         //    $arrOrder[$i][0] = '';
  471.         //    $arrOrder[$i][1] = '';
  472.         //    $arrOrder[$i][2] = '';
  473.         //    $arrOrder[$i][3] = '';
  474.         //    ++$i;
  475.         //    $arrOrder[$i][0] = '';
  476.         //    $arrOrder[$i][1] = '';
  477.         //    $arrOrder[$i][2] = '商品合計';
  478.         //    $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($Order->getSubtotal());
  479.         //    ++$i;
  480.         //    $arrOrder[$i][0] = '';
  481.         //    $arrOrder[$i][1] = '';
  482.         //    $arrOrder[$i][2] = '送料';
  483.         //    $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($Order->getDeliveryFeeTotal());
  484.         //    ++$i;
  485.         //    $arrOrder[$i][0] = '';
  486.         //    $arrOrder[$i][1] = '';
  487.         //    $arrOrder[$i][2] = '手数料';
  488.         //    $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($Order->getCharge());
  489.         //    ++$i;
  490.         //    $arrOrder[$i][0] = '';
  491.         //    $arrOrder[$i][1] = '';
  492.         //    $arrOrder[$i][2] = '値引き';
  493.         //    $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($Order->getTaxableDiscount());
  494.         //    ++$i;
  495.         //    $arrOrder[$i][0] = '';
  496.         //    $arrOrder[$i][1] = '';
  497.         //    $arrOrder[$i][2] = '';
  498.         //    $arrOrder[$i][3] = '';
  499.         //    ++$i;
  500.         //    $arrOrder[$i][0] = '';
  501.         //    $arrOrder[$i][1] = '';
  502.         //    $arrOrder[$i][2] = '合計';
  503.         //    $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($Order->getTaxableTotal());
  504.         //    ++$i;
  505.         //    $arrOrder[$i][0] = '';
  506.         //    $arrOrder[$i][1] = '';
  507.         //    $arrOrder[$i][2] = '';
  508.         //    $arrOrder[$i][3] = '';
  509.         //    foreach ($Order->getTaxFreeDiscountItems() as $Item) {
  510.         //        ++$i;
  511.         //        $arrOrder[$i][0] = '';
  512.         //        $arrOrder[$i][1] = '';
  513.         //        $arrOrder[$i][2] = $Item->getProductName();
  514.         //        $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($Item->getTotalPrice());
  515.         //    }
  516.         //    ++$i;
  517.         //    $arrOrder[$i][0] = '';
  518.         //    $arrOrder[$i][1] = '';
  519.         //    $arrOrder[$i][2] = '請求金額';
  520.         //    $arrOrder[$i][3] = $this->eccubeExtension->getPriceFilter($Order->getPaymentTotal());
  521.         //    if ($isShowReducedTaxMess) {
  522.         //        ++$i;
  523.         //        $arrOrder[$i][0] = '※は軽減税率対象商品です。';
  524.         //        $arrOrder[$i][1] = '';
  525.         //        $arrOrder[$i][2] = '';
  526.         //        $arrOrder[$i][3] = '';
  527.         //    }
  528.         //}
  529.         // PDFに設定する
  530.         $this->setFancyTable($this->labelCell$arrOrder$this->widthCell);
  531.         // インボイス対応
  532.         $this->backupFont();
  533.         $this->SetLineWidth(.3);
  534.         $this->SetFont(self::FONT_SJIS''6);
  535.         $this->Cell(00''01'C'0'');
  536.         // 行頭近くの場合、表示崩れがあるためもう一個字下げする
  537.         if (270 <= $this->GetY()) {
  538.             $this->Cell(00''01'C'0'');
  539.         }
  540.         $width array_reduce($this->widthCell, function ($n$w) {
  541.             return $n $w;
  542.         });
  543.         $this->SetX(20);
  544.         $message '';
  545.         //foreach ($Order->getTotalByTaxRate() as $rate => $total) {
  546.             //$message .= '('.$rate.'%対象: ';
  547.             //$message .= $this->eccubeExtension->getPriceFilter($total);
  548.             //$message .= ' 内消費税: '.$this->eccubeExtension->getPriceFilter($Order->getTaxByTaxRate()[$rate]).')'.PHP_EOL;
  549.         //}
  550.         $this->MultiCell($width4$message0'R'0'');
  551.         $this->restoreFont();
  552.     }
  553.     /**
  554.      * PDFへのテキスト書き込み
  555.      *
  556.      * @param int    $x     X座標
  557.      * @param int    $y     Y座標
  558.      * @param string $text  テキスト
  559.      * @param int    $size  フォントサイズ
  560.      * @param string $style フォントスタイル
  561.      */
  562.     protected function lfText($x$y$text$size 0$style '')
  563.     {
  564.         // 退避
  565.         $bakFontStyle $this->FontStyle;
  566.         $bakFontSize $this->FontSizePt;
  567.         $this->SetFont(''$style$size);
  568.         $this->Text($x $this->baseOffsetX$y $this->baseOffsetY$text);
  569.         // 復元
  570.         $this->SetFont(''$bakFontStyle$bakFontSize);
  571.     }
  572.     /**
  573.      * Colored table.
  574.      *
  575.      * @param array $header 出力するラベル名一覧
  576.      * @param array $data   出力するデータ
  577.      * @param array $w      出力するセル幅一覧
  578.      */
  579.     protected function setFancyTable($header$data$w)
  580.     {
  581.         // フォント情報のバックアップ
  582.         $this->backupFont();
  583.         // 開始座標の設定
  584.         //$this->setBasePosition(0, 149);
  585.         $this->setBasePosition(050);
  586.         // Colors, line width and bold font
  587.         $this->SetFillColor(216216216);
  588.         $this->SetTextColor(0);
  589.         $this->SetDrawColor(000);
  590.         $this->SetLineWidth(.3);
  591.         $this->SetFont(self::FONT_SJIS'B'8);
  592.         $this->SetFont('''B');
  593.         // Header
  594.         $this->Cell(57''00''0'');
  595.         $count count($header);
  596.         for ($i 0$i $count; ++$i) {
  597.             $this->Cell($w[$i], 7$header[$i], 10'C'1);
  598.         }
  599.         $this->Ln();
  600.         // Color and font restoration
  601.         $this->SetFillColor(235235235);
  602.         $this->SetTextColor(0);
  603.         $this->SetFont('');
  604.         // Data
  605.         $fill 0;
  606.         $writeRow = function($row$cellHeight$fill$isBorder) use($w) {
  607.             $i 0;
  608.             $h 0;
  609.             foreach ($row as $col) {
  610.                 // 列の処理
  611.                 // TODO: 汎用的ではない処理。この指定は呼び出し元で行うようにしたい。
  612.                 // テキストの整列を指定する
  613.                 $align = ($i == 0) ? 'L' 'R';
  614.                 // セル高さが最大値を保持する
  615.                 if ($h >= $cellHeight) {
  616.                     $cellHeight $h;
  617.                 }
  618.                 // 最終列の場合は次の行へ移動
  619.                 // (0: 右へ移動(既定)/1: 次の行へ移動/2: 下へ移動)
  620.                 $ln = ($i == (count($row) - 1)) ? 0;
  621.                 $this->MultiCell(
  622.                     $w[$i], // セル幅
  623.                     $cellHeight// セルの最小の高さ
  624.                     !$isBorder $col ''// 文字列
  625.                     $isBorder 0// 境界線の描画方法を指定
  626.                     $align// テキストの整列
  627.                     $fill// 背景の塗つぶし指定
  628.                     $ln // 出力後のカーソルの移動方法
  629.                 );
  630.                 $h $this->getLastH();
  631.                 $i++;
  632.             }
  633.             return $cellHeight;
  634.         };
  635.         $i 0;
  636.         foreach ($data as $row) {
  637.             // 行の処理
  638.             $h 7;
  639.             $this->Cell(5$h''00''0'');
  640.             if ((277 $this->getY()) < ($h 4)) {
  641.                 $this->checkPageBreak($this->PageBreakTrigger 1);
  642.             }
  643.             $x $this->getX();
  644.             $y $this->getY();
  645.             // 1度目は文字だけ出力し、行の高さ最大を取得
  646.             $this->Image($row[0], $x$y45);
  647.             $row[0] = '';
  648.             $h $writeRow($row$h$fillfalse);
  649.             $this->setXY($x$y);
  650.             // 2度目に最大の高さに合わせて、境界線を描画
  651.             $writeRow($row$h$filltrue);
  652.           //  $this->Image($logoFile, 124, 46, 40);
  653.             $fill = !$fill;
  654.             if($i 20){
  655.               break;
  656.             }
  657.             $i++;
  658.         }
  659.         $h 4;
  660.         $this->Cell(5$h''00''0'');
  661.         $this->Cell(array_sum($w), 0'''T');
  662.         $this->SetFillColor(255);
  663.         // フォント情報の復元
  664.         $this->restoreFont();
  665.     }
  666.     /**
  667.      * 基準座標を設定する.
  668.      *
  669.      * @param int $x
  670.      * @param int $y
  671.      */
  672.     protected function setBasePosition($x null$y null)
  673.     {
  674.         // 現在のマージンを取得する
  675.         $result $this->getMargins();
  676.         // 基準座標を指定する
  677.         $actualX is_null($x) ? $result['left'] : $x;
  678.         $this->SetX($actualX);
  679.         $actualY is_null($y) ? $result['top'] : $y;
  680.         $this->SetY($actualY);
  681.     }
  682.     /**
  683.      * Font情報のバックアップ.
  684.      */
  685.     protected function backupFont()
  686.     {
  687.         // フォント情報のバックアップ
  688.         $this->bakFontFamily $this->FontFamily;
  689.         $this->bakFontStyle $this->FontStyle;
  690.         $this->bakFontSize $this->FontSizePt;
  691.     }
  692.     /**
  693.      * Font情報の復元.
  694.      */
  695.     protected function restoreFont()
  696.     {
  697.         $this->SetFont($this->bakFontFamily$this->bakFontStyle$this->bakFontSize);
  698.     }
  699. }