From 8ef8f78df8351e6d2e65e03ef235e432d269ca96 Mon Sep 17 00:00:00 2001 From: Kartik Visweswaran Date: Fri, 12 Oct 2018 02:30:27 +0530 Subject: [PATCH] Fix #273: Enhanced PDF Writer `ExportWriterPdf` --- CHANGE.md | 3 +- src/ExportMenu.php | 79 ++++++--------------------- src/ExportWriterPdf.php | 115 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 65 deletions(-) create mode 100644 src/ExportWriterPdf.php diff --git a/CHANGE.md b/CHANGE.md index b607e27..61b0a3f 100755 --- a/CHANGE.md +++ b/CHANGE.md @@ -3,8 +3,9 @@ Change Log: `yii2-export` ## version 1.3.4 -**Date:** _under development_ +**Date:** 12-Oct-2018 +- (enh #273): Enhanced PDF Writer `ExportWriterPdf`. - (enh #272): UTF-8 encoding for HTML, CSV, TEXT formats. - (enh #271): Locale specific validation messages and code enhancements. - (enh #270): Add iframe as default target for export form download. diff --git a/src/ExportMenu.php b/src/ExportMenu.php index 37ea5c1..48275c2 100644 --- a/src/ExportMenu.php +++ b/src/ExportMenu.php @@ -14,7 +14,6 @@ use kartik\dialog\Dialog; use kartik\dynagrid\Dynagrid; use kartik\grid\GridView; -use kartik\mpdf\Pdf; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\DataValidation; use PhpOffice\PhpSpreadsheet\IOFactory; @@ -22,11 +21,9 @@ use PhpOffice\PhpSpreadsheet\Style\Border; use PhpOffice\PhpSpreadsheet\Style\Color; use PhpOffice\PhpSpreadsheet\Style\Fill; -use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use PhpOffice\PhpSpreadsheet\Writer\BaseWriter; use PhpOffice\PhpSpreadsheet\Writer\Csv as WriterCsv; -use PhpOffice\PhpSpreadsheet\Writer\Html as WriterHtml; use Yii; use yii\base\InvalidConfigException; use yii\base\Model; @@ -801,20 +798,13 @@ public function run() if ($this->stream) { $this->clearOutputBuffers(); $this->setHttpHeaders(); - if ($this->_exportType === self::FORMAT_PDF) { - $this->renderPDF($file); - } else { - readfile($file); - } + readfile($file); $this->cleanup($file, $config); exit(); } else { $this->registerAssets(); echo $this->renderExportMenu(); if ($this->_triggerDownload && $this->afterSaveView !== false) { - if ($this->_exportType === self::FORMAT_PDF) { - $this->renderPDF($file); - } $config = ArrayHelper::getValue($this->exportConfig, $this->_exportType, []); if (!empty($config)) { $l = $this->linkFileName; @@ -1117,11 +1107,22 @@ public function initPhpSpreadsheet() */ public function initPhpSpreadsheetWriter($type) { + $t = $this->_exportType; + if ($t === self::FORMAT_PDF) { + IOFactory::registerWriter($type, ExportWriterPdf::class); + } + $writer = $this->_objWriter = IOFactory::createWriter($this->_objSpreadsheet, $type); + if ($t === self::FORMAT_PDF && !empty($this->exportConfig[$t])) { + $cfg = $this->exportConfig[$t]; + /** + * @var ExportWriterPdf $writer + */ + $writer->filename = $this->filename . '.' . ArrayHelper::getValue($cfg, 'extension', 'pdf'); + $writer->pdfConfig = ArrayHelper::getValue($cfg, 'pdfConfig', []); + } /** * @var WriterCsv $writer */ - $writer = $this->_objWriter = IOFactory::createWriter($this->_objSpreadsheet, $type); - $t = $this->_exportType; if ($t === self::FORMAT_TEXT) { $delimiter = $this->getSetting('delimiter', "\t"); $writer->setDelimiter($delimiter); @@ -1641,56 +1642,6 @@ protected function getSetting($key, $default = null) return ArrayHelper::getValue($settings, $key, $default); } - /** - * Parse PDF - * - * @param string $file the output filename on server with path - * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception - * @throws InvalidConfigException - */ - protected function renderPDF($file) - { - // Default PDF paper size - $spreadsheet = $this->_objSpreadsheet; - $sheet = $this->_objWorksheet; - /** - * @var WriterHtml $w - */ - $w = $this->_objWriter; - $page = $sheet->getPageSetup(); - $orientation = $page->getOrientation() == PageSetup::ORIENTATION_LANDSCAPE ? 'L' : 'P'; - $properties = $spreadsheet->getProperties(); - $settings = ArrayHelper::getValue($this->exportConfig, $this->_exportType, []); - $useInlineCss = ArrayHelper::getValue($settings, 'useInlineCss', false); - $config = ArrayHelper::getValue($settings, 'pdfConfig', []); - $w->setUseInlineCss($useInlineCss); - $config = array_replace_recursive( - [ - 'orientation' => strtoupper($orientation), - 'methods' => [ - 'SetTitle' => $properties->getTitle(), - 'SetAuthor' => $properties->getCreator(), - 'SetCreator' => $properties->getCreator(), - 'SetSubject' => $properties->getSubject(), - 'SetKeywords' => $properties->getKeywords(), - ], - 'cssFile' => '', - 'content' => $w->generateHTMLHeader(false) . $w->generateSheetData() . $w->generateHTMLFooter(), - ], - $config - ); - if (!$this->stream) { - $config['destination'] = Pdf::DEST_FILE; - $config['filename'] = $file; - } else { - $config['destination'] = Pdf::DEST_DOWNLOAD; - $extension = ArrayHelper::getValue($settings, 'extension', 'pdf'); - $config['filename'] = $this->filename . '.' . $extension; - } - $pdf = new Pdf($config); - echo $pdf->render(); - } - /** * Initialize columns selected for export */ @@ -1865,7 +1816,7 @@ protected function setDefaultExportConfig() 'alertMsg' => Yii::t('kvexport', 'The PDF export file will be generated for download.'), 'mime' => 'application/pdf', 'extension' => 'pdf', - 'writer' => self::FORMAT_HTML, + 'writer' => 'KrajeePdf', // custom Krajee PDF writer using MPdf library 'useInlineCss' => true, 'pdfConfig' => [], ], diff --git a/src/ExportWriterPdf.php b/src/ExportWriterPdf.php new file mode 100644 index 0000000..75cc8eb --- /dev/null +++ b/src/ExportWriterPdf.php @@ -0,0 +1,115 @@ + + * @since 1.0 + */ +class ExportWriterPdf extends Mpdf +{ + /** + * @var string the exported output file name. Defaults to 'grid-export'; + */ + public $filename; + + /** + * @var array kartik\mpdf\Pdf component configuration settings + */ + public $pdfConfig = []; + + /** + * @inheritdoc + */ + protected function createExternalWriterInstance($config = []) + { + $config = array_replace_recursive($config, $this->pdfConfig); + return new Pdf($config); + } + + /** + * Save Spreadsheet to file. + * + * @param string $pFilename Name of the file to save as + * + * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception + * @throws PhpSpreadsheetException + */ + public function save($pFilename) + { + $fileHandle = parent::prepareForSave($pFilename); + + // Default PDF paper size + $paperSize = 'LETTER'; // Letter (8.5 in. by 11 in.) + + // Check for paper size and page orientation + if (null === $this->getSheetIndex()) { + $orientation = ($this->spreadsheet->getSheet(0)->getPageSetup()->getOrientation() + == PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; + $printPaperSize = $this->spreadsheet->getSheet(0)->getPageSetup()->getPaperSize(); + } else { + $orientation = ($this->spreadsheet->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation() + == PageSetup::ORIENTATION_LANDSCAPE) ? 'L' : 'P'; + $printPaperSize = $this->spreadsheet->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize(); + } + $this->setOrientation($orientation); + + // Override Page Orientation + if (null !== $this->getOrientation()) { + $orientation = ($this->getOrientation() == PageSetup::ORIENTATION_DEFAULT) + ? PageSetup::ORIENTATION_PORTRAIT + : $this->getOrientation(); + } + $orientation = strtoupper($orientation); + + // Override Paper Size + if (null !== $this->getPaperSize()) { + $printPaperSize = $this->getPaperSize(); + } + + if (isset(self::$paperSizes[$printPaperSize])) { + $paperSize = self::$paperSizes[$printPaperSize]; + } + + $properties = $this->spreadsheet->getProperties(); + + // Create PDF + $pdf = $this->createExternalWriterInstance([ + 'orientation' => $orientation, + 'methods' => [ + 'SetTitle' => $properties->getTitle(), + 'SetAuthor' => $properties->getCreator(), + 'SetSubject' => $properties->getSubject(), + 'SetKeywords' => $properties->getKeywords(), + 'SetCreator' => $properties->getCreator(), + ], + ]); + $ortmp = $orientation; + $lib = $pdf->getApi(); + /** @noinspection PhpUndefinedMethodInspection */ + $lib->_setPageSize(strtoupper($paperSize), $ortmp); + $lib->DefOrientation = $orientation; + /** @noinspection PhpUndefinedMethodInspection */ + $lib->AddPage($orientation); + $content = strtr($this->generateHTMLHeader(false) . $this->generateSheetData() . $this->generateHTMLFooter(), [ + '@page { margin-left: 0.7in; margin-right: 0.7in; margin-top: 0.75in; margin-bottom: 0.75in; }' => '', + 'body { margin-left: 0.7in; margin-right: 0.7in; margin-top: 0.75in; margin-bottom: 0.75in; }' => '', + ]); + // Write to file + fwrite($fileHandle, $pdf->Output($content, $this->filename, Pdf::DEST_STRING)); + parent::restoreStateAfterSave($fileHandle); + } +} \ No newline at end of file