diff --git a/samples/Basic/17_Html.php b/samples/Basic/17_Html.php index b90b7212d..54f031ece 100644 --- a/samples/Basic/17_Html.php +++ b/samples/Basic/17_Html.php @@ -1,13 +1,7 @@ getProperties()->setTitle('Non-embedded images'); -$filename = $helper->getFilename(__FILE__, 'html'); -$writer = IOFactory::createWriter($spreadsheet, 'Html'); - -$callStartTime = microtime(true); -$writer->save($filename); -$helper->logWrite($writer, $filename, $callStartTime); +$helper->write($spreadsheet, __FILE__, ['Html']); diff --git a/samples/Basic/17a_Html.php b/samples/Basic/17a_Html.php index 20578fbe3..5804c77c7 100644 --- a/samples/Basic/17a_Html.php +++ b/samples/Basic/17a_Html.php @@ -4,11 +4,14 @@ use PhpOffice\PhpSpreadsheet\Writer\Html; require __DIR__ . '/../Header.php'; $spreadsheet = require __DIR__ . '/../templates/sampleSpreadsheet.php'; +$spreadsheet->getProperties()->setTitle('Embedded images'); -$filename = $helper->getFilename(__FILE__, 'html'); -$writer = new Html($spreadsheet); - -$callStartTime = microtime(true); -$writer->setEmbedImages(true); -$writer->save($filename); -$helper->logWrite($writer, $filename, $callStartTime); +$helper->write( + $spreadsheet, + __FILE__, + ['Html'], + false, + function (Html $writer): void { + $writer->setEmbedImages(true); + } +); diff --git a/samples/Basic/17b_Html.php b/samples/Basic/17b_Html.php index 97bb29a33..0e677e3ed 100644 --- a/samples/Basic/17b_Html.php +++ b/samples/Basic/17b_Html.php @@ -5,16 +5,18 @@ use PhpOffice\PhpSpreadsheet\Writer\Html; require __DIR__ . '/../Header.php'; $spreadsheet = require __DIR__ . '/../templates/sampleSpreadsheet.php'; -$filename = $helper->getFilename(__FILE__, 'html'); -$writer = new Html($spreadsheet); - function changeGridlines(string $html): string { return str_replace('{border: 1px solid black;}', '{border: 2px dashed red;}', $html); } -$callStartTime = microtime(true); -$writer->setEmbedImages(true); -$writer->setEditHtmlCallback('changeGridlines'); -$writer->save($filename); -$helper->logWrite($writer, $filename, $callStartTime); +$helper->write( + $spreadsheet, + __FILE__, + ['Html'], + false, + function (Html $writer): void { + $writer->setEmbedImages(true); + $writer->setEditHtmlCallback('changeGridlines'); + } +); diff --git a/samples/Basic/26_Utf8.php b/samples/Basic/26_Utf8.php index 52a64509b..2eeca067b 100644 --- a/samples/Basic/26_Utf8.php +++ b/samples/Basic/26_Utf8.php @@ -1,6 +1,8 @@ log('Load Xlsx template file'); $reader = IOFactory::createReader('Xlsx'); $spreadsheet = $reader->load(__DIR__ . '/../templates/26template.xlsx'); +$spreadsheet->getActiveSheet()->setPrintGridlines(true); // at this point, we could do some manipulations with the template, but we skip this step $helper->write($spreadsheet, __FILE__, ['Xlsx', 'Xls', 'Html']); -// Export to PDF (.pdf) -$helper->log('Write to PDF format'); -IOFactory::registerWriter('Pdf', \PhpOffice\PhpSpreadsheet\Writer\Pdf\Dompdf::class); -$helper->write($spreadsheet, __FILE__, ['Pdf']); +// Export to PDF (mpdf) +function mpdfCjkWriter(Mpdf $writer): void +{ + /** @var callable */ + $callback = 'mpdfCjk'; + $writer->setEditHtmlCallback($callback); +} + +function mpdfCjk(string $html): string +{ + $html = str_replace("'Calibri'", "'Calibri',Sun-ExtA", $html); + + return str_replace("'Times New Roman'", "'Times New Roman',Sun-ExtA", $html); +} + +$helper->log('Write to Mpdf'); +IOFactory::registerWriter('Pdf', Mpdf::class); +/** @var callable */ +$callback = 'mpdfCjkWriter'; +$filename = __FILE__; +//$filename = str_replace('.php', '.mdpf.php', __FILE__); +$helper->write($spreadsheet, $filename, ['Pdf'], false, $callback); // Remove first two rows with field headers before exporting to CSV $helper->log('Removing first two heading rows for CSV export'); @@ -25,16 +46,17 @@ $worksheet->removeRow(1, 2); // Export to CSV (.csv) $helper->log('Write to CSV format'); /** @var \PhpOffice\PhpSpreadsheet\Writer\Csv $writer */ -$writer = IOFactory::createWriter($spreadsheet, 'Csv'); -$filename = $helper->getFilename(__FILE__, 'csv'); -$callStartTime = microtime(true); -$writer->save($filename); -$helper->logWrite($writer, $filename, $callStartTime); +$helper->write($spreadsheet, __FILE__, ['Csv']); // Export to CSV with BOM (.csv) -$filename = str_replace('.csv', '-bom.csv', $filename); +$filename = str_replace('.php', '-bom.php', __FILE__); $helper->log('Write to CSV format (with BOM)'); -$writer->setUseBOM(true); -$callStartTime = microtime(true); -$writer->save($filename); -$helper->logWrite($writer, $filename, $callStartTime); +$helper->write( + $spreadsheet, + $filename, + ['Csv'], + false, + function (Csv $writer): void { + $writer->setUseBOM(true); + } +); diff --git a/samples/Chart/32_Chart_read_write_HTML.php b/samples/Chart/32_Chart_read_write_HTML.php index 90d61c5d5..3cb377873 100644 --- a/samples/Chart/32_Chart_read_write_HTML.php +++ b/samples/Chart/32_Chart_read_write_HTML.php @@ -79,11 +79,7 @@ foreach ($inputFileNames as $inputFileName) { // Save $filename = $helper->getFilename($inputFileName, 'html'); - $writer = IOFactory::createWriter($spreadsheet, 'Html'); - $writer->setIncludeCharts(true); - $callStartTime = microtime(true); - $writer->save($filename); - $helper->logWrite($writer, $filename, $callStartTime); + $helper->write($spreadsheet, $filename, ['Html'], true); $spreadsheet->disconnectWorksheets(); unset($spreadsheet); diff --git a/samples/Chart/32_Chart_read_write_PDF.php b/samples/Chart/32_Chart_read_write_PDF.php index 214c3d380..e3d702a9d 100644 --- a/samples/Chart/32_Chart_read_write_PDF.php +++ b/samples/Chart/32_Chart_read_write_PDF.php @@ -81,11 +81,7 @@ foreach ($inputFileNames as $inputFileName) { // Save $filename = $helper->getFilename($inputFileName, 'pdf'); - $writer = IOFactory::createWriter($spreadsheet, 'Pdf'); - $writer->setIncludeCharts(true); - $callStartTime = microtime(true); - $writer->save($filename); - $helper->logWrite($writer, $filename, $callStartTime); + $helper->write($spreadsheet, $filename, ['Pdf'], true); $spreadsheet->disconnectWorksheets(); unset($spreadsheet); diff --git a/samples/Chart/33_Chart_create_stock2.php b/samples/Chart/33_Chart_create_stock2.php index 0d5ebf2c0..bc9faf3db 100644 --- a/samples/Chart/33_Chart_create_stock2.php +++ b/samples/Chart/33_Chart_create_stock2.php @@ -8,7 +8,6 @@ use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues; use PhpOffice\PhpSpreadsheet\Chart\Legend as ChartLegend; use PhpOffice\PhpSpreadsheet\Chart\PlotArea; use PhpOffice\PhpSpreadsheet\Chart\Title; -use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; @@ -116,12 +115,8 @@ $chart->setBottomRightPosition('H20'); // Add the chart to the worksheet $worksheet->addChart($chart); +$helper->renderChart($chart, __FILE__); $worksheet->setSelectedCells('G2'); // Save Excel 2007 file -$filename = $helper->getFilename(__FILE__); -$writer = IOFactory::createWriter($spreadsheet, 'Xlsx'); -$writer->setIncludeCharts(true); -$callStartTime = microtime(true); -$writer->save($filename); -$helper->logWrite($writer, $filename, $callStartTime); +$helper->write($spreadsheet, __FILE__, ['Xlsx'], true); diff --git a/samples/Chart/35_Chart_render.php b/samples/Chart/35_Chart_render.php index 7b1e4ed97..4c403d993 100644 --- a/samples/Chart/35_Chart_render.php +++ b/samples/Chart/35_Chart_render.php @@ -54,6 +54,7 @@ foreach ($inputFileNames as $inputFileName) { $spreadsheet = $reader->load($inputFileName); $helper->log('Iterate worksheets looking at the charts'); + $renderedCharts = 0; foreach ($spreadsheet->getWorksheetIterator() as $worksheet) { $sheetName = $worksheet->getTitle(); $helper->log('Worksheet: ' . $sheetName); @@ -63,7 +64,8 @@ foreach ($inputFileNames as $inputFileName) { $helper->log(' There are no charts in this worksheet'); } else { natsort($chartNames); - foreach ($chartNames as $i => $chartName) { + foreach ($chartNames as $j => $chartName) { + $i = $renderedCharts + $j; $chart = $worksheet->getChartByName($chartName); if ($chart->getTitle() !== null) { $caption = '"' . implode(' ', $chart->getTitle()->getCaption()) . '"'; @@ -86,6 +88,8 @@ foreach ($inputFileNames as $inputFileName) { } catch (Exception $e) { $helper->log('Error rendering chart: ' . $e->getMessage()); } + + ++$renderedCharts; } } } diff --git a/samples/Chart/35_Chart_render33.php b/samples/Chart/35_Chart_render33.php new file mode 100644 index 000000000..bd8075de4 --- /dev/null +++ b/samples/Chart/35_Chart_render33.php @@ -0,0 +1,101 @@ +getTemporaryFolder() . '/33_Chart_create_*.xlsx'; + +if ((isset($argc)) && ($argc > 1)) { + $inputFileNames = []; + for ($i = 1; $i < $argc; ++$i) { + $inputFileNames[] = __DIR__ . '/../templates/' . $argv[$i]; + } +} else { + $inputFileNames = glob($inputFileNames); +} +if (count($inputFileNames) === 1) { + $unresolvedErrors = []; +} else { + $unresolvedErrors = [ + // The following spreadsheet was created by 3rd party software, + // and doesn't include the data that usually accompanies a chart. + // That is good enough for Excel, but not for JpGraph. + '33_Chart_create_bar_stacked.xlsx', + ]; +} +foreach ($inputFileNames as $inputFileName) { + $inputFileNameShort = basename($inputFileName); + + if (!file_exists($inputFileName)) { + $helper->log('File ' . $inputFileNameShort . ' does not exist'); + + continue; + } + if (in_array($inputFileNameShort, $unresolvedErrors, true)) { + $helper->log('*****'); + $helper->log('***** File ' . $inputFileNameShort . ' does not yet work with this script'); + $helper->log('*****'); + + continue; + } + + $helper->log("Load Test from $inputFileType file " . $inputFileNameShort); + + $reader = IOFactory::createReader($inputFileType); + $reader->setIncludeCharts(true); + $spreadsheet = $reader->load($inputFileName); + + $helper->log('Iterate worksheets looking at the charts'); + $renderedCharts = 0; + foreach ($spreadsheet->getWorksheetIterator() as $worksheet) { + $sheetName = $worksheet->getTitle(); + $helper->log('Worksheet: ' . $sheetName); + + $chartNames = $worksheet->getChartNames(); + if (empty($chartNames)) { + $helper->log(' There are no charts in this worksheet'); + } else { + natsort($chartNames); + foreach ($chartNames as $j => $chartName) { + $i = $renderedCharts + $j; + $chart = $worksheet->getChartByName($chartName); + if ($chart->getTitle() !== null) { + $caption = '"' . implode(' ', $chart->getTitle()->getCaption()) . '"'; + } else { + $caption = 'Untitled'; + } + $helper->log(' ' . $chartName . ' - ' . $caption); + + $pngFile = $helper->getFilename('35-' . $inputFileNameShort, 'png'); + if ($i !== 0) { + $pngFile = substr($pngFile, 0, -3) . "$i.png"; + } + if (file_exists($pngFile)) { + unlink($pngFile); + } + + try { + $chart->render($pngFile); + $helper->log('Rendered image: ' . $pngFile); + } catch (Exception $e) { + $helper->log('Error rendering chart: ' . $e->getMessage()); + } + + ++$renderedCharts; + } + } + } + + $spreadsheet->disconnectWorksheets(); + unset($spreadsheet); + gc_collect_cycles(); +} + +$helper->log('Done rendering charts as images'); diff --git a/samples/Header.php b/samples/Header.php index eb0766be5..670776851 100644 --- a/samples/Header.php +++ b/samples/Header.php @@ -1,7 +1,9 @@ isCli()) { diff --git a/samples/Pdf/21a_Pdf.php b/samples/Pdf/21a_Pdf.php index 33b61c9f5..377f59287 100644 --- a/samples/Pdf/21a_Pdf.php +++ b/samples/Pdf/21a_Pdf.php @@ -1,5 +1,6 @@ log('Write to Mpdf'); -$writer = new Mpdf($spreadsheet); -$filename = $helper->getFileName('21a_Pdf_mpdf.xlsx', 'pdf'); -$writer->setEditHtmlCallback('changeGridlines'); -$writer->save($filename); +IOFactory::registerWriter('Pdf', Mpdf::class); +$helper->write( + $spreadsheet, + __FILE__, + ['Pdf'], + false, + function (Mpdf $writer): void { + $writer->setEmbedImages(true); + $writer->setEditHtmlCallback('changeGridlines'); + } +); diff --git a/samples/Pdf/21b_Pdf.php b/samples/Pdf/21b_Pdf.php index 421e0867e..d7a1cb51e 100644 --- a/samples/Pdf/21b_Pdf.php +++ b/samples/Pdf/21b_Pdf.php @@ -1,9 +1,10 @@ log('Set orientation to landscape'); $spreadsheet->getActiveSheet()->getPageSetup()->setOrientation(PageSetup::ORIENTATION_LANDSCAPE); $helper->log('Write to Dompdf'); -$writer = new Dompdf($spreadsheet); -$filename = $helper->getFileName('21b_Pdf_dompdf.xlsx', 'pdf'); -$writer->setEditHtmlCallback('replaceBody'); -$writer->save($filename); +IOFactory::registerWriter('Pdf', Dompdf::class); +$filename = str_replace('.php', '_dompdf.php', __FILE__); +$helper->write( + $spreadsheet, + $filename, + ['Pdf'], + false, + function (Dompdf $writer): void { + $writer->setEditHtmlCallback('replaceBody'); + } +); $helper->log('Write to Mpdf'); -$writer = new Mpdf($spreadsheet); -$filename = $helper->getFileName('21b_Pdf_mpdf.xlsx', 'pdf'); -$writer->setEditHtmlCallback('replaceBody'); -$writer->save($filename); +IOFactory::registerWriter('Pdf', Mpdf::class); +$filename = str_replace('.php', '_mpdf.php', __FILE__); +$helper->write( + $spreadsheet, + $filename, + ['Pdf'], + false, + function (Mpdf $writer): void { + $writer->setEditHtmlCallback('replaceBody'); + } +); $helper->log('Write to Tcpdf'); -$writer = new Tcpdf($spreadsheet); -$filename = $helper->getFileName('21b_Pdf_tcpdf.xlsx', 'pdf'); -$writer->setEditHtmlCallback('replaceBody'); -$writer->save($filename); +IOFactory::registerWriter('Pdf', TcpdfClass::class); +$filename = str_replace('.php', '_tcpdf.php', __FILE__); +$helper->write( + $spreadsheet, + $filename, + ['Pdf'], + false, + function (TcpdfClass $writer): void { + $writer->setEditHtmlCallback('replaceBody'); + } +); diff --git a/samples/Pdf/21c_Pdf.php b/samples/Pdf/21c_Pdf.php index 6fe12664b..211f8be9a 100644 --- a/samples/Pdf/21c_Pdf.php +++ b/samples/Pdf/21c_Pdf.php @@ -1,7 +1,7 @@ log('Write to Mpdf'); -$writer = new Mpdf($spreadsheet); -$filename = $helper->getFileName('21c_Pdf_mpdf.xlsx', 'pdf'); -$writer->save($filename); -$helper->log("Saved $filename"); +IOFactory::registerWriter('Pdf', \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class); +$helper->write($spreadsheet, __FILE__, ['Pdf']); +$spreadsheet->disconnectWorksheets(); diff --git a/samples/Pdf/21d_FitToHeightPdf.php b/samples/Pdf/21d_FitToHeightPdf.php index 1b02d9d53..577eac0c4 100644 --- a/samples/Pdf/21d_FitToHeightPdf.php +++ b/samples/Pdf/21d_FitToHeightPdf.php @@ -1,7 +1,7 @@ load($fileWithPath); $sheet = $spreadsheet->getActiveSheet(); $helper->log('Write to Mpdf'); -$writer = new Mpdf($spreadsheet); -$filename = $helper->getfilename($filename, 'pdf'); -$writer->save($filename); -$helper->log("Saved $filename"); +IOFactory::registerWriter('Pdf', \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class); +$helper->write($spreadsheet, __FILE__, ['Pdf']); $spreadsheet->disconnectWorksheets(); diff --git a/src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php b/src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php index cb9b544b8..d676f1d33 100644 --- a/src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php +++ b/src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php @@ -434,12 +434,33 @@ abstract class JpGraphRendererBase implements IRenderer // Loop through each data series in turn for ($i = 0; $i < $seriesCount; ++$i) { - $dataValuesY = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues(); + $plotCategoryByIndex = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i); + if ($plotCategoryByIndex === false) { + $plotCategoryByIndex = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0); + } + $dataValuesY = $plotCategoryByIndex->getDataValues(); $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); - foreach ($dataValuesY as $k => $dataValueY) { - $dataValuesY[$k] = $k; + $redoDataValuesY = true; + if ($bubble) { + if (!$bubbleSize) { + $bubbleSize = '10'; + } + $redoDataValuesY = false; + foreach ($dataValuesY as $dataValueY) { + if (!is_int($dataValueY) && !is_float($dataValueY)) { + $redoDataValuesY = true; + + break; + } + } } + if ($redoDataValuesY) { + foreach ($dataValuesY as $k => $dataValueY) { + $dataValuesY[$k] = $k; + } + } + //var_dump($dataValuesY, $dataValuesX, $bubbleSize); $seriesPlot = new ScatterPlot($dataValuesX, $dataValuesY); if ($scatterStyle == 'lineMarker') { @@ -483,7 +504,7 @@ abstract class JpGraphRendererBase implements IRenderer $dataValues = []; foreach ($dataValuesY as $k => $dataValueY) { - $dataValues[$k] = implode(' ', array_reverse($dataValueY)); + $dataValues[$k] = is_array($dataValueY) ? implode(' ', array_reverse($dataValueY)) : $dataValueY; } $tmp = array_shift($dataValues); $dataValues[] = $tmp; diff --git a/src/PhpSpreadsheet/Helper/Downloader.php b/src/PhpSpreadsheet/Helper/Downloader.php index a45c358f6..e66ae4258 100644 --- a/src/PhpSpreadsheet/Helper/Downloader.php +++ b/src/PhpSpreadsheet/Helper/Downloader.php @@ -17,6 +17,7 @@ class Downloader 'xls' => 'application/vnd.ms-excel', 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', 'csv' => 'text/csv', + 'html' => 'text/html', 'pdf' => 'application/pdf', ]; diff --git a/src/PhpSpreadsheet/Helper/Sample.php b/src/PhpSpreadsheet/Helper/Sample.php index 0e6a427d1..6244375fe 100644 --- a/src/PhpSpreadsheet/Helper/Sample.php +++ b/src/PhpSpreadsheet/Helper/Sample.php @@ -123,7 +123,7 @@ class Sample * @param string $filename * @param string[] $writers */ - public function write(Spreadsheet $spreadsheet, $filename, array $writers = ['Xlsx', 'Xls'], bool $withCharts = false): void + public function write(Spreadsheet $spreadsheet, $filename, array $writers = ['Xlsx', 'Xls'], bool $withCharts = false, ?callable $writerCallback = null): void { // Set active sheet index to the first sheet, so Excel opens this as the first sheet $spreadsheet->setActiveSheetIndex(0); @@ -132,8 +132,9 @@ class Sample foreach ($writers as $writerType) { $path = $this->getFilename($filename, mb_strtolower($writerType)); $writer = IOFactory::createWriter($spreadsheet, $writerType); - if ($writerType === 'Xlsx' && $withCharts === true) { - $writer->setIncludeCharts(true); + $writer->setIncludeCharts($withCharts); + if ($writerCallback !== null) { + $writerCallback($writer); } $callStartTime = microtime(true); $writer->save($path);