Merge branch 'master' into Issue-3005_Extract-CellReferences-in-Range-with-Worksheet-Reference

This commit is contained in:
Mark Baker 2022-08-15 00:25:03 +02:00 committed by GitHub
commit dfa6f803fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 191 additions and 140 deletions

View File

@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
- Implementation of the `ARRAYTOTEXT()` Excel Function - Implementation of the `ARRAYTOTEXT()` Excel Function
- Support for [mitoteam/jpgraph](https://packagist.org/packages/mitoteam/jpgraph) implementation of - Support for [mitoteam/jpgraph](https://packagist.org/packages/mitoteam/jpgraph) implementation of
JpGraph library to render charts added. JpGraph library to render charts added.
- Charts: Add Gradients, Transparency, Hidden Axes, Rounded Corners, Trendlines.
### Changed ### Changed
@ -20,7 +21,12 @@ and this project adheres to [Semantic Versioning](https://semver.org).
### Deprecated ### Deprecated
- Nothing - Axis getLineProperty deprecated in favor of getLineColorProperty.
- Moved majorGridlines and minorGridlines from Chart to Axis. Setting either in Chart constructor or through Chart methods, or getting either using Chart methods is deprecated.
- Chart::EXCEL_COLOR_TYPE_* copied from Properties to ChartColor; use in Properties is deprecated.
- ChartColor::EXCEL_COLOR_TYPE_ARGB deprecated in favor of EXCEL_COLOR_TYPE_RGB ("A" component was never allowed).
- Misspelled Properties::LINE_STYLE_DASH_SQUERE_DOT deprecated in favor of LINE_STYLE_DASH_SQUARE_DOT.
- Clone not permitted for Spreadsheet. Spreadsheet->copy() can be used instead.
### Removed ### Removed
@ -30,6 +36,14 @@ and this project adheres to [Semantic Versioning](https://semver.org).
- Fully flatten an array [Issue #2955](https://github.com/PHPOffice/PhpSpreadsheet/issues/2955) [PR #2956](https://github.com/PHPOffice/PhpSpreadsheet/pull/2956) - Fully flatten an array [Issue #2955](https://github.com/PHPOffice/PhpSpreadsheet/issues/2955) [PR #2956](https://github.com/PHPOffice/PhpSpreadsheet/pull/2956)
- cellExists() and getCell() methods should support UTF-8 named cells [Issue #2987](https://github.com/PHPOffice/PhpSpreadsheet/issues/2987) [PR #2988](https://github.com/PHPOffice/PhpSpreadsheet/pull/2988) - cellExists() and getCell() methods should support UTF-8 named cells [Issue #2987](https://github.com/PHPOffice/PhpSpreadsheet/issues/2987) [PR #2988](https://github.com/PHPOffice/PhpSpreadsheet/pull/2988)
- Spreadsheet copy fixed, clone disabled. [PR #2951](https://github.com/PHPOffice/PhpSpreadsheet/pull/2951)
- Fix PDF problems with text rotation and paper size. [Issue #1747](https://github.com/PHPOffice/PhpSpreadsheet/issues/1747) [Issue #1713](https://github.com/PHPOffice/PhpSpreadsheet/issues/1713) [PR #2960](https://github.com/PHPOffice/PhpSpreadsheet/pull/2960)
- Limited support for chart titles as formulas [Issue #2965](https://github.com/PHPOffice/PhpSpreadsheet/issues/2965) [Issue #749](https://github.com/PHPOffice/PhpSpreadsheet/issues/749) [PR #2971](https://github.com/PHPOffice/PhpSpreadsheet/pull/2971)
- Add Gradients, Transparency, and Hidden Axes to Chart [Issue #2257](https://github.com/PHPOffice/PhpSpreadsheet/issues/2257) [Issue #2229](https://github.com/PHPOffice/PhpSpreadsheet/issues/2929) [Issue #2935](https://github.com/PHPOffice/PhpSpreadsheet/issues/2935) [PR #2950](https://github.com/PHPOffice/PhpSpreadsheet/pull/2950)
- Chart Support for Rounded Corners and Trendlines [Issue #2968](https://github.com/PHPOffice/PhpSpreadsheet/issues/2968) [Issue #2815](https://github.com/PHPOffice/PhpSpreadsheet/issues/2815) [PR #2976](https://github.com/PHPOffice/PhpSpreadsheet/pull/2976)
- Add setName Method for Chart [Issue #2991](https://github.com/PHPOffice/PhpSpreadsheet/issues/2991) [PR #3001](https://github.com/PHPOffice/PhpSpreadsheet/pull/3001)
- Eliminate partial dependency on php-intl in StringHelper [Issue #2982](https://github.com/PHPOffice/PhpSpreadsheet/issues/2982) [PR #2994](https://github.com/PHPOffice/PhpSpreadsheet/pull/2994)
- Minor changes for Pdf [Issue #2999](https://github.com/PHPOffice/PhpSpreadsheet/issues/2999) [PR #3002](https://github.com/PHPOffice/PhpSpreadsheet/pull/3002) [PR #3006](https://github.com/PHPOffice/PhpSpreadsheet/pull/3006)
## 1.24.1 - 2022-07-18 ## 1.24.1 - 2022-07-18

View File

@ -81,20 +81,21 @@
"dealerdirect/phpcodesniffer-composer-installer": "dev-master", "dealerdirect/phpcodesniffer-composer-installer": "dev-master",
"dompdf/dompdf": "^1.0 || ^2.0", "dompdf/dompdf": "^1.0 || ^2.0",
"friendsofphp/php-cs-fixer": "^3.2", "friendsofphp/php-cs-fixer": "^3.2",
"jpgraph/jpgraph": "^4.0", "mitoteam/jpgraph": "^10.1",
"mpdf/mpdf": "8.1.1", "mpdf/mpdf": "8.1.1",
"phpcompatibility/php-compatibility": "^9.3", "phpcompatibility/php-compatibility": "^9.3",
"phpstan/phpstan": "^1.1", "phpstan/phpstan": "^1.1",
"phpstan/phpstan-phpunit": "^1.0", "phpstan/phpstan-phpunit": "^1.0",
"phpunit/phpunit": "^8.5 || ^9.0", "phpunit/phpunit": "^8.5 || ^9.0",
"squizlabs/php_codesniffer": "^3.7", "squizlabs/php_codesniffer": "^3.7",
"tecnickcom/tcpdf": "^6.4" "tecnickcom/tcpdf": "6.5"
}, },
"suggest": { "suggest": {
"ext-intl": "PHP Internationalization Functions",
"mpdf/mpdf": "Option for rendering PDF with PDF Writer", "mpdf/mpdf": "Option for rendering PDF with PDF Writer",
"dompdf/dompdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)", "dompdf/dompdf": "Option for rendering PDF with PDF Writer",
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)", "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer",
"jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers" "mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {

102
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "6cbb20f8d8f2daae0aeb72431cda0980", "content-hash": "05bd955232ea7ceab5b849e990f593bd",
"packages": [ "packages": [
{ {
"name": "ezyang/htmlpurifier", "name": "ezyang/htmlpurifier",
@ -1192,47 +1192,6 @@
], ],
"time": "2021-12-11T16:25:08+00:00" "time": "2021-12-11T16:25:08+00:00"
}, },
{
"name": "jpgraph/jpgraph",
"version": "4.0.2",
"source": {
"type": "git",
"url": "https://github.com/ztec/JpGraph.git",
"reference": "e82db7da6a546d3926c24c9a346226da7aa49094"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ztec/JpGraph/zipball/e82db7da6a546d3926c24c9a346226da7aa49094",
"reference": "e82db7da6a546d3926c24c9a346226da7aa49094",
"shasum": ""
},
"type": "library",
"autoload": {
"classmap": [
"lib/JpGraph.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"QPL 1.0"
],
"authors": [
{
"name": "JpGraph team"
}
],
"description": "jpGraph, library to make graphs and charts",
"homepage": "http://jpgraph.net/",
"keywords": [
"chart",
"data",
"graph",
"jpgraph",
"pie"
],
"abandoned": true,
"time": "2017-02-23T09:44:15+00:00"
},
{ {
"name": "masterminds/html5", "name": "masterminds/html5",
"version": "2.7.5", "version": "2.7.5",
@ -1298,6 +1257,49 @@
], ],
"time": "2021-07-01T14:25:37+00:00" "time": "2021-07-01T14:25:37+00:00"
}, },
{
"name": "mitoteam/jpgraph",
"version": "10.1.3",
"source": {
"type": "git",
"url": "https://github.com/mitoteam/jpgraph.git",
"reference": "425a2a0f0c97a28fe0aca60a4384ce85880e438a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mitoteam/jpgraph/zipball/425a2a0f0c97a28fe0aca60a4384ce85880e438a",
"reference": "425a2a0f0c97a28fe0aca60a4384ce85880e438a",
"shasum": ""
},
"require": {
"php": ">=5.5"
},
"type": "library",
"autoload": {
"classmap": [
"src/MtJpGraph.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"QPL-1.0"
],
"authors": [
{
"name": "JpGraph team"
}
],
"description": "Composer compatible version of JpGraph library with PHP 8.1 support",
"homepage": "https://github.com/mitoteam/jpgraph",
"keywords": [
"jpgraph"
],
"support": {
"issues": "https://github.com/mitoteam/jpgraph/issues",
"source": "https://github.com/mitoteam/jpgraph/tree/10.1.3"
},
"time": "2022-07-05T16:46:34+00:00"
},
{ {
"name": "mpdf/mpdf", "name": "mpdf/mpdf",
"version": "v8.1.1", "version": "v8.1.1",
@ -5082,16 +5084,16 @@
}, },
{ {
"name": "tecnickcom/tcpdf", "name": "tecnickcom/tcpdf",
"version": "6.4.4", "version": "6.5.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/tecnickcom/TCPDF.git", "url": "https://github.com/tecnickcom/TCPDF.git",
"reference": "42cd0f9786af7e5db4fcedaa66f717b0d0032320" "reference": "cc54c1503685e618b23922f53635f46e87653662"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/42cd0f9786af7e5db4fcedaa66f717b0d0032320", "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/cc54c1503685e618b23922f53635f46e87653662",
"reference": "42cd0f9786af7e5db4fcedaa66f717b0d0032320", "reference": "cc54c1503685e618b23922f53635f46e87653662",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5140,13 +5142,17 @@
"pdf417", "pdf417",
"qrcode" "qrcode"
], ],
"support": {
"issues": "https://github.com/tecnickcom/TCPDF/issues",
"source": "https://github.com/tecnickcom/TCPDF/tree/6.5.0"
},
"funding": [ "funding": [
{ {
"url": "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&currency_code=GBP&business=paypal@tecnick.com&item_name=donation%20for%20tcpdf%20project", "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&currency_code=GBP&business=paypal@tecnick.com&item_name=donation%20for%20tcpdf%20project",
"type": "custom" "type": "custom"
} }
], ],
"time": "2021-12-31T08:39:24+00:00" "time": "2022-08-12T07:50:54+00:00"
}, },
{ {
"name": "theseer/tokenizer", "name": "theseer/tokenizer",
@ -5273,5 +5279,5 @@
"ext-zlib": "*" "ext-zlib": "*"
}, },
"platform-dev": [], "platform-dev": [],
"plugin-api-version": "1.1.0" "plugin-api-version": "2.2.0"
} }

View File

@ -12,7 +12,6 @@ parameters:
excludePaths: excludePaths:
- src/PhpSpreadsheet/Chart/Renderer/JpGraph.php - src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
- src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php - src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php
- src/PhpSpreadsheet/Chart/Renderer/MtJpGraphRenderer.php
parallel: parallel:
processTimeout: 300.0 processTimeout: 300.0
checkMissingIterableValueType: false checkMissingIterableValueType: false

View File

@ -6,7 +6,8 @@ use PhpOffice\PhpSpreadsheet\Settings;
require __DIR__ . '/../Header.php'; require __DIR__ . '/../Header.php';
// Change these values to select the Rendering library that you wish to use // Change these values to select the Rendering library that you wish to use
Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class); //Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class);
Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\MtJpGraphRenderer::class);
$inputFileType = 'Xlsx'; $inputFileType = 'Xlsx';
$inputFileNames = __DIR__ . '/../templates/36write*.xlsx'; $inputFileNames = __DIR__ . '/../templates/36write*.xlsx';

View File

@ -8,7 +8,8 @@ require __DIR__ . '/../Header.php';
IOFactory::registerWriter('Pdf', \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class); IOFactory::registerWriter('Pdf', \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class);
// Change these values to select the Rendering library that you wish to use // Change these values to select the Rendering library that you wish to use
Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class); //Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class);
Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\MtJpGraphRenderer::class);
$inputFileType = 'Xlsx'; $inputFileType = 'Xlsx';
$inputFileNames = __DIR__ . '/../templates/36write*.xlsx'; $inputFileNames = __DIR__ . '/../templates/36write*.xlsx';

View File

@ -5,16 +5,13 @@ use PhpOffice\PhpSpreadsheet\Settings;
require __DIR__ . '/../Header.php'; require __DIR__ . '/../Header.php';
if (PHP_VERSION_ID >= 80000) {
$helper->log('Jpgraph no longer runs against PHP8');
exit;
}
// Change these values to select the Rendering library that you wish to use // Change these values to select the Rendering library that you wish to use
Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class); //Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class);
Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\MtJpGraphRenderer::class);
$inputFileType = 'Xlsx'; $inputFileType = 'Xlsx';
$inputFileNames = __DIR__ . '/../templates/32readwrite*[0-9].xlsx'; $inputFileNames = __DIR__ . '/../templates/32readwrite*[0-9].xlsx';
//$inputFileNames = __DIR__ . '/../templates/32readwriteStockChart5.xlsx';
if ((isset($argc)) && ($argc > 1)) { if ((isset($argc)) && ($argc > 1)) {
$inputFileNames = []; $inputFileNames = [];
@ -24,6 +21,18 @@ if ((isset($argc)) && ($argc > 1)) {
} else { } else {
$inputFileNames = glob($inputFileNames); $inputFileNames = glob($inputFileNames);
} }
if (count($inputFileNames) === 1) {
$unresolvedErrors = [];
} else {
$unresolvedErrors = [
'32readwriteBubbleChart2.xlsx',
'32readwritePieChart3.xlsx',
'32readwritePieChart4.xlsx',
'32readwritePieChart3D1.xlsx',
'32readwritePieChartExploded1.xlsx',
'32readwritePieChartExploded3D1.xlsx',
];
}
foreach ($inputFileNames as $inputFileName) { foreach ($inputFileNames as $inputFileName) {
$inputFileNameShort = basename($inputFileName); $inputFileNameShort = basename($inputFileName);
@ -32,6 +41,11 @@ foreach ($inputFileNames as $inputFileName) {
continue; continue;
} }
if (in_array($inputFileNameShort, $unresolvedErrors, true)) {
$helper->log('File ' . $inputFileNameShort . ' does not yet work with this script');
continue;
}
$helper->log("Load Test from $inputFileType file " . $inputFileNameShort); $helper->log("Load Test from $inputFileType file " . $inputFileNameShort);

View File

@ -12,6 +12,8 @@ $spreadsheet->getActiveSheet()->setShowGridLines(false);
$helper->log('Set orientation to landscape'); $helper->log('Set orientation to landscape');
$spreadsheet->getActiveSheet()->getPageSetup()->setOrientation(PageSetup::ORIENTATION_LANDSCAPE); $spreadsheet->getActiveSheet()->getPageSetup()->setOrientation(PageSetup::ORIENTATION_LANDSCAPE);
$spreadsheet->setActiveSheetIndex(0)->setPrintGridlines(true); $spreadsheet->setActiveSheetIndex(0)->setPrintGridlines(true);
// Issue 2299 - mpdf can't handle hide rows without kludge
$spreadsheet->getActiveSheet()->getRowDimension(2)->setVisible(false);
function changeGridlines(string $html): string function changeGridlines(string $html): string
{ {

View File

@ -188,6 +188,13 @@ class Chart
return $this->name; return $this->name;
} }
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/** /**
* Get Worksheet. * Get Worksheet.
*/ */
@ -654,14 +661,10 @@ class Chart
/** /**
* Render the chart to given file (or stream). * Render the chart to given file (or stream).
* Unable to cover code until a usable current version of JpGraph
* is made available through Composer.
* *
* @param string $outputDestination Name of the file render to * @param string $outputDestination Name of the file render to
* *
* @return bool true on success * @return bool true on success
*
* @codeCoverageIgnore
*/ */
public function render($outputDestination = null) public function render($outputDestination = null)
{ {

View File

@ -277,7 +277,8 @@ abstract class JpGraphRendererBase implements IRenderer
{ {
$grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping();
$labelCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount(); $index = array_keys($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder())[0];
$labelCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($index)->getPointCount();
if ($labelCount > 0) { if ($labelCount > 0) {
$datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues();
$datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount); $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount);
@ -294,8 +295,9 @@ abstract class JpGraphRendererBase implements IRenderer
// Loop through each data series in turn // Loop through each data series in turn
for ($i = 0; $i < $seriesCount; ++$i) { for ($i = 0; $i < $seriesCount; ++$i) {
$dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues(); $index = array_keys($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder())[$i];
$marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker(); $dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($index)->getDataValues();
$marker = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($index)->getPointMarker();
if ($grouping == 'percentStacked') { if ($grouping == 'percentStacked') {
$dataValues = $this->percentageAdjustValues($dataValues, $sumValues); $dataValues = $this->percentageAdjustValues($dataValues, $sumValues);
@ -324,7 +326,7 @@ abstract class JpGraphRendererBase implements IRenderer
// Set the appropriate plot marker // Set the appropriate plot marker
$this->formatPointMarker($seriesPlot, $marker); $this->formatPointMarker($seriesPlot, $marker);
} }
$dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue(); $dataLabel = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($index)->getDataValue();
$seriesPlot->SetLegend($dataLabel); $seriesPlot->SetLegend($dataLabel);
$seriesPlots[] = $seriesPlot; $seriesPlots[] = $seriesPlot;
@ -347,7 +349,8 @@ abstract class JpGraphRendererBase implements IRenderer
} }
$grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping(); $grouping = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping();
$labelCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount(); $index = array_keys($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder())[0];
$labelCount = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($index)->getPointCount();
if ($labelCount > 0) { if ($labelCount > 0) {
$datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues(); $datasetLabels = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues();
$datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation); $datasetLabels = $this->formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation);
@ -371,7 +374,8 @@ abstract class JpGraphRendererBase implements IRenderer
// Loop through each data series in turn // Loop through each data series in turn
for ($j = 0; $j < $seriesCount; ++$j) { for ($j = 0; $j < $seriesCount; ++$j) {
$dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues(); $index = array_keys($this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder())[$j];
$dataValues = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($index)->getDataValues();
if ($grouping == 'percentStacked') { if ($grouping == 'percentStacked') {
$dataValues = $this->percentageAdjustValues($dataValues, $sumValues); $dataValues = $this->percentageAdjustValues($dataValues, $sumValues);
} }
@ -535,6 +539,10 @@ abstract class JpGraphRendererBase implements IRenderer
$dataValues = []; $dataValues = [];
// Loop through each data series in turn and build the plot arrays // Loop through each data series in turn and build the plot arrays
foreach ($plotOrder as $i => $v) { foreach ($plotOrder as $i => $v) {
$dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v);
if ($dataValuesX === false) {
continue;
}
$dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues(); $dataValuesX = $this->chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues();
foreach ($dataValuesX as $j => $dataValueX) { foreach ($dataValuesX as $j => $dataValueX) {
$dataValues[$plotOrder[$i]][$j] = $dataValueX; $dataValues[$plotOrder[$i]][$j] = $dataValueX;
@ -549,7 +557,7 @@ abstract class JpGraphRendererBase implements IRenderer
$jMax = count($dataValues[0]); $jMax = count($dataValues[0]);
for ($j = 0; $j < $jMax; ++$j) { for ($j = 0; $j < $jMax; ++$j) {
for ($i = 0; $i < $seriesCount; ++$i) { for ($i = 0; $i < $seriesCount; ++$i) {
$dataValuesPlot[] = $dataValues[$i][$j]; $dataValuesPlot[] = $dataValues[$i][$j] ?? null;
} }
} }

View File

@ -9,8 +9,6 @@ namespace PhpOffice\PhpSpreadsheet\Chart\Renderer;
* https://packagist.org/packages/mitoteam/jpgraph * https://packagist.org/packages/mitoteam/jpgraph
* *
* This package is up to date for August 2022 and has PHP 8.1 support. * This package is up to date for August 2022 and has PHP 8.1 support.
*
* @codeCoverageIgnore
*/ */
class MtJpGraphRenderer extends JpGraphRendererBase class MtJpGraphRenderer extends JpGraphRendererBase
{ {

View File

@ -3,7 +3,6 @@
namespace PhpOffice\PhpSpreadsheet\Shared; namespace PhpOffice\PhpSpreadsheet\Shared;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use UConverter;
class StringHelper class StringHelper
{ {
@ -334,26 +333,13 @@ class StringHelper
public static function sanitizeUTF8(string $textValue): string public static function sanitizeUTF8(string $textValue): string
{ {
$textValue = str_replace(["\xef\xbf\xbe", "\xef\xbf\xbf"], "\xef\xbf\xbd", $textValue); $textValue = str_replace(["\xef\xbf\xbe", "\xef\xbf\xbf"], "\xef\xbf\xbd", $textValue);
if (class_exists(UConverter::class)) { $subst = mb_substitute_character(); // default is question mark
$returnValue = UConverter::transcode($textValue, 'UTF-8', 'UTF-8'); mb_substitute_character(65533); // Unicode substitution character
if ($returnValue !== false) {
return $returnValue;
}
}
// @codeCoverageIgnoreStart
// I don't think any of the code below should ever be executed.
if (self::getIsIconvEnabled()) {
$returnValue = @iconv('UTF-8', 'UTF-8', $textValue);
if ($returnValue !== false) {
return $returnValue;
}
}
// Phpstan does not think this can return false. // Phpstan does not think this can return false.
$returnValue = mb_convert_encoding($textValue, 'UTF-8', 'UTF-8'); $returnValue = mb_convert_encoding($textValue, 'UTF-8', 'UTF-8');
mb_substitute_character($subst);
return $returnValue; return $returnValue;
// @codeCoverageIgnoreEnd
} }
/** /**

View File

@ -54,7 +54,7 @@ class Html extends BaseWriter
* *
* @var bool * @var bool
*/ */
private $embedImages = false; protected $embedImages = false;
/** /**
* Use inline CSS? * Use inline CSS?
@ -551,15 +551,10 @@ class Html extends BaseWriter
* Extend Row if chart is placed after nominal end of row. * Extend Row if chart is placed after nominal end of row.
* This code should be exercised by sample: * This code should be exercised by sample:
* Chart/32_Chart_read_write_PDF.php. * Chart/32_Chart_read_write_PDF.php.
* However, that test is suppressed due to out-of-date
* Jpgraph code issuing warnings. So, don't measure
* code coverage for this function till that is fixed.
* *
* @param int $row Row to check for charts * @param int $row Row to check for charts
* *
* @return array * @return array
*
* @codeCoverageIgnore
*/ */
private function extendRowsForCharts(Worksheet $worksheet, int $row) private function extendRowsForCharts(Worksheet $worksheet, int $row)
{ {
@ -635,11 +630,12 @@ class Html extends BaseWriter
* *
* @return string * @return string
*/ */
public static function winFileToUrl($filename) public static function winFileToUrl($filename, bool $mpdf = false)
{ {
// Windows filename // Windows filename
if (substr($filename, 1, 2) === ':\\') { if (substr($filename, 1, 2) === ':\\') {
$filename = 'file:///' . str_replace('\\', '/', $filename); $protocol = $mpdf ? '' : 'file:///';
$filename = $protocol . str_replace('\\', '/', $filename);
} }
return $filename; return $filename;
@ -681,9 +677,9 @@ class Html extends BaseWriter
$filename = htmlspecialchars($filename, Settings::htmlEntityFlags()); $filename = htmlspecialchars($filename, Settings::htmlEntityFlags());
$html .= PHP_EOL; $html .= PHP_EOL;
$imageData = self::winFileToUrl($filename); $imageData = self::winFileToUrl($filename, $this->isMPdf);
if (($this->embedImages && !$this->isPdf) || substr($imageData, 0, 6) === 'zip://') { if ($this->embedImages || substr($imageData, 0, 6) === 'zip://') {
$picture = @file_get_contents($filename); $picture = @file_get_contents($filename);
if ($picture !== false) { if ($picture !== false) {
$imageDetails = getimagesize($filename); $imageDetails = getimagesize($filename);
@ -725,11 +721,6 @@ class Html extends BaseWriter
* Generate chart tag in cell. * Generate chart tag in cell.
* This code should be exercised by sample: * This code should be exercised by sample:
* Chart/32_Chart_read_write_PDF.php. * Chart/32_Chart_read_write_PDF.php.
* However, that test is suppressed due to out-of-date
* Jpgraph code issuing warnings. So, don't measure
* code coverage for this function till that is fixed.
*
* @codeCoverageIgnore
*/ */
private function writeChartInCell(Worksheet $worksheet, string $coordinates): string private function writeChartInCell(Worksheet $worksheet, string $coordinates): string
{ {
@ -1170,9 +1161,9 @@ class Html extends BaseWriter
$html = ''; $html = '';
$id = $showid ? "id='sheet$sheetIndex'" : ''; $id = $showid ? "id='sheet$sheetIndex'" : '';
if ($showid) { if ($showid) {
$html .= "<div style='page: page$sheetIndex'>\n"; $html .= "<div style='page: page$sheetIndex'>" . PHP_EOL;
} else { } else {
$html .= "<div style='page: page$sheetIndex' class='scrpgbrk'>\n"; $html .= "<div style='page: page$sheetIndex' class='scrpgbrk'>" . PHP_EOL;
} }
$this->generateTableTag($worksheet, $id, $html, $sheetIndex); $this->generateTableTag($worksheet, $id, $html, $sheetIndex);
@ -1467,6 +1458,10 @@ class Html extends BaseWriter
// Sheet index // Sheet index
$sheetIndex = $worksheet->getParent()->getIndex($worksheet); $sheetIndex = $worksheet->getParent()->getIndex($worksheet);
$html = $this->generateRowStart($worksheet, $sheetIndex, $row); $html = $this->generateRowStart($worksheet, $sheetIndex, $row);
$generateDiv = $this->isMPdf && $worksheet->getRowDimension($row + 1)->getVisible() === false;
if ($generateDiv) {
$html .= '<div style="visibility:hidden; display:none;">' . PHP_EOL;
}
// Write cells // Write cells
$colNum = 0; $colNum = 0;
@ -1514,6 +1509,9 @@ class Html extends BaseWriter
} }
// Write row end // Write row end
if ($generateDiv) {
$html .= '</div>' . PHP_EOL;
}
$html .= ' </tr>' . PHP_EOL; $html .= ' </tr>' . PHP_EOL;
// Return // Return
@ -1844,26 +1842,26 @@ class Html extends BaseWriter
} elseif ($orientation === \PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_PORTRAIT) { } elseif ($orientation === \PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_PORTRAIT) {
$htmlPage .= 'size: portrait; '; $htmlPage .= 'size: portrait; ';
} }
$htmlPage .= "}\n"; $htmlPage .= '}' . PHP_EOL;
++$sheetId; ++$sheetId;
} }
$htmlPage .= <<<EOF $htmlPage .= implode(PHP_EOL, [
.navigation {page-break-after: always;} '.navigation {page-break-after: always;}',
.scrpgbrk, div + div {page-break-before: always;} '.scrpgbrk, div + div {page-break-before: always;}',
@media screen { '@media screen {',
.gridlines td {border: 1px solid black;} ' .gridlines td {border: 1px solid black;}',
.gridlines th {border: 1px solid black;} ' .gridlines th {border: 1px solid black;}',
body>div {margin-top: 5px;} ' body>div {margin-top: 5px;}',
body>div:first-child {margin-top: 0;} ' body>div:first-child {margin-top: 0;}',
.scrpgbrk {margin-top: 1px;} ' .scrpgbrk {margin-top: 1px;}',
} '}',
@media print { '@media print {',
.gridlinesp td {border: 1px solid black;} ' .gridlinesp td {border: 1px solid black;}',
.gridlinesp th {border: 1px solid black;} ' .gridlinesp th {border: 1px solid black;}',
.navigation {display: none;} ' .navigation {display: none;}',
} '}',
'',
EOF; ]);
$htmlPage .= $generateSurroundingHTML ? ('</style>' . PHP_EOL) : ''; $htmlPage .= $generateSurroundingHTML ? ('</style>' . PHP_EOL) : '';
return $htmlPage; return $htmlPage;

View File

@ -7,6 +7,13 @@ use PhpOffice\PhpSpreadsheet\Writer\Pdf;
class Dompdf extends Pdf class Dompdf extends Pdf
{ {
/**
* embed images, or link to images.
*
* @var bool
*/
protected $embedImages = true;
/** /**
* Gets the implementation of external PDF library that should be used. * Gets the implementation of external PDF library that should be used.
* *

View File

@ -77,7 +77,7 @@ class Tcpdf extends Pdf
$pdf->SetCreator($this->spreadsheet->getProperties()->getCreator()); $pdf->SetCreator($this->spreadsheet->getProperties()->getCreator());
// Write to file // Write to file
fwrite($fileHandle, $pdf->output($filename, 'S')); fwrite($fileHandle, $pdf->output('', 'S'));
parent::restoreStateAfterSave(); parent::restoreStateAfterSave();
} }

View File

@ -93,8 +93,9 @@ class ChartMethodTest extends TestCase
$xAxis, // xAxis $xAxis, // xAxis
$yAxis // yAxis $yAxis // yAxis
); );
$chart2 = new Chart('chart1'); $chart2 = new Chart('xyz');
$chart2 $chart2
->setName('chart1')
->setLegend($legend) ->setLegend($legend)
->setPlotArea($plotArea) ->setPlotArea($plotArea)
->setPlotVisibleOnly(true) ->setPlotVisibleOnly(true)

View File

@ -0,0 +1,15 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Chart\Chart;
use PHPUnit\Framework\TestCase;
class RenderTest extends TestCase
{
public function testNoRenderer(): void
{
$chart = new Chart('Chart1');
self::assertFalse($chart->render());
}
}

View File

@ -18,15 +18,9 @@ class StreamTest extends TestCase
['Html'], ['Html'],
['Mpdf'], ['Mpdf'],
['Dompdf'], ['Dompdf'],
['Tcpdf'],
]; ];
if (\PHP_VERSION_ID < 80000) {
$providerFormats = array_merge(
$providerFormats,
[['Tcpdf']]
);
}
return $providerFormats; return $providerFormats;
} }

View File

@ -26,10 +26,13 @@ class SampleTest extends TestCase
public function providerSample(): array public function providerSample(): array
{ {
$skipped = [ $skipped = [
'Chart/32_Chart_read_write_PDF.php', // Unfortunately JpGraph is not up to date for latest PHP and raise many warnings
'Chart/32_Chart_read_write_HTML.php', // idem
'Chart/35_Chart_render.php', // idem
]; ];
if (PHP_VERSION_ID >= 80200) {
// Hopefully temporary. Continue to try
// 32_chart_read_write_PDF/HTML
// so as not to lose track of the problem.
$skipped[] = 'Chart/35_Chart_render.php';
}
// Unfortunately some tests are too long to run with code-coverage // Unfortunately some tests are too long to run with code-coverage
// analysis on GitHub Actions, so we need to exclude them // analysis on GitHub Actions, so we need to exclude them