mirror of
https://github.com/PHPOffice/PhpSpreadsheet.git
synced 2026-08-17 15:13:42 +00:00
Let Phpstan Run on Samples (#3808)
* Let Phpstan Run on Samples Phpstan currently analyzes all source and test members. We already run phpcs and php-cs-fixer on samples as well. I would expect that samples are often used as templates for code in userland; it behooves us to be at least as careful with those members as for the others which are already being analyzed. Aside from 1300+ messages `Variable $helper might not be defined.`, which will be suppressed in phpstan.neon.dist, there are really only a few changes needed for sample members, so that part of the code base was already in good shape, and is now even better. No annotations were needed. * Scrutinizer 2 out of 3 1 false positive, now suppressed; fix other 2. * Remove Dead Code * Very Minor Changes * Add infra
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
<file>samples</file>
|
||||
<file>src</file>
|
||||
<file>tests</file>
|
||||
<file>infra</file>
|
||||
|
||||
<exclude-pattern>samples/Header.php</exclude-pattern>
|
||||
<exclude-pattern>*/tests/Core/*/*Test\.(inc|css|js)$</exclude-pattern>
|
||||
|
||||
@@ -52,7 +52,7 @@ class DocumentGenerator
|
||||
return rtrim($result, ' ');
|
||||
}
|
||||
|
||||
private static function getPhpSpreadsheetFunctionText($functionCall): string
|
||||
private static function getPhpSpreadsheetFunctionText(mixed $functionCall): string
|
||||
{
|
||||
if (is_string($functionCall)) {
|
||||
return $functionCall;
|
||||
|
||||
+22
-13
@@ -38,32 +38,32 @@ class LocaleGenerator
|
||||
*/
|
||||
protected $translationBaseFolder;
|
||||
|
||||
protected $phpSpreadsheetFunctions;
|
||||
protected array $phpSpreadsheetFunctions;
|
||||
|
||||
/**
|
||||
* @var Spreadsheet
|
||||
*/
|
||||
protected $translationSpreadsheet;
|
||||
|
||||
protected $verbose;
|
||||
protected bool $verbose;
|
||||
|
||||
/**
|
||||
* @var Worksheet
|
||||
*/
|
||||
protected $localeTranslations;
|
||||
|
||||
protected $localeLanguageMap = [];
|
||||
protected array $localeLanguageMap = [];
|
||||
|
||||
protected $errorCodeMap = [];
|
||||
protected array $errorCodeMap = [];
|
||||
|
||||
/**
|
||||
* @var Worksheet
|
||||
*/
|
||||
private $functionNameTranslations;
|
||||
|
||||
protected $functionNameLanguageMap = [];
|
||||
protected array $functionNameLanguageMap = [];
|
||||
|
||||
protected $functionNameMap = [];
|
||||
protected array $functionNameMap = [];
|
||||
|
||||
public function __construct(
|
||||
string $translationBaseFolder,
|
||||
@@ -98,7 +98,7 @@ class LocaleGenerator
|
||||
}
|
||||
}
|
||||
|
||||
protected function buildConfigFileForLocale($column, $locale): void
|
||||
protected function buildConfigFileForLocale(string $column, string $locale): void
|
||||
{
|
||||
$language = $this->localeTranslations->getCell($column . self::ENGLISH_LANGUAGE_NAME_ROW)->getValue();
|
||||
$localeLanguage = $this->localeTranslations->getCell($column . self::LOCALE_LANGUAGE_NAME_ROW)->getValue();
|
||||
@@ -124,7 +124,8 @@ class LocaleGenerator
|
||||
fclose($configFile);
|
||||
}
|
||||
|
||||
protected function writeConfigArgumentSeparator($configFile, $column): void
|
||||
/** @param resource $configFile resource to write to */
|
||||
protected function writeConfigArgumentSeparator($configFile, string $column): void
|
||||
{
|
||||
$translationCell = $this->localeTranslations->getCell($column . self::ARGUMENT_SEPARATOR_ROW);
|
||||
$localeValue = $translationCell->getValue();
|
||||
@@ -136,7 +137,8 @@ class LocaleGenerator
|
||||
}
|
||||
}
|
||||
|
||||
protected function writeConfigCurrencySymbol($configFile, $column): void
|
||||
/** @param resource $configFile resource to write to */
|
||||
protected function writeConfigCurrencySymbol($configFile, string $column): void
|
||||
{
|
||||
$translationCell = $this->localeTranslations->getCell($column . self::CURRENCY_SYMBOL_ROW);
|
||||
$localeValue = $translationCell->getValue();
|
||||
@@ -151,7 +153,7 @@ class LocaleGenerator
|
||||
}
|
||||
}
|
||||
|
||||
protected function buildFunctionsFileForLocale($column, $locale): void
|
||||
protected function buildFunctionsFileForLocale(string $column, string $locale): void
|
||||
{
|
||||
$language = $this->functionNameTranslations->getCell($column . self::ENGLISH_LANGUAGE_NAME_ROW)->getValue();
|
||||
$localeLanguage = $this->functionNameTranslations->getCell($column . self::LOCALE_LANGUAGE_NAME_ROW)
|
||||
@@ -176,6 +178,7 @@ class LocaleGenerator
|
||||
fclose($functionFile);
|
||||
}
|
||||
|
||||
/** @return resource used by other methods in this class */
|
||||
protected function openConfigFile(string $locale, string $language, string $localeLanguage)
|
||||
{
|
||||
$this->log("Building locale {$locale} ($language) configuration");
|
||||
@@ -185,11 +188,15 @@ class LocaleGenerator
|
||||
$this->log("Writing locale configuration to {$configFileName}");
|
||||
|
||||
$configFile = fopen($configFileName, 'wb');
|
||||
if ($configFile === false) {
|
||||
throw new Exception('Unable to open $configFileName for write');
|
||||
}
|
||||
$this->writeFileHeader($configFile, $localeLanguage, $language, 'locale settings');
|
||||
|
||||
return $configFile;
|
||||
}
|
||||
|
||||
/** @return resource used by other methods in this class */
|
||||
protected function openFunctionNameFile(string $locale, string $language, string $localeLanguage)
|
||||
{
|
||||
$this->log("Building locale {$locale} ($language) function names");
|
||||
@@ -199,6 +206,9 @@ class LocaleGenerator
|
||||
$this->log("Writing local function names to {$functionFileName}");
|
||||
|
||||
$functionFile = fopen($functionFileName, 'wb');
|
||||
if ($functionFile === false) {
|
||||
throw new Exception('Unable to open $functionFileName for write');
|
||||
}
|
||||
$this->writeFileHeader($functionFile, $localeLanguage, $language, 'function name translations');
|
||||
|
||||
return $functionFile;
|
||||
@@ -218,6 +228,7 @@ class LocaleGenerator
|
||||
return $localeFolder;
|
||||
}
|
||||
|
||||
/** @param resource $localeFile file being written to */
|
||||
protected function writeFileHeader($localeFile, string $localeLanguage, string $language, string $title): void
|
||||
{
|
||||
fwrite($localeFile, str_repeat('#', 60) . self::EOL);
|
||||
@@ -229,6 +240,7 @@ class LocaleGenerator
|
||||
fwrite($localeFile, str_repeat('#', 60) . self::EOL . self::EOL);
|
||||
}
|
||||
|
||||
/** @param resource $localeFile file being written to */
|
||||
protected function writeFileSectionHeader($localeFile, string $header): void
|
||||
{
|
||||
fwrite($localeFile, self::EOL . '##' . self::EOL);
|
||||
@@ -245,9 +257,6 @@ class LocaleGenerator
|
||||
protected function getTranslationSheet(string $sheetName): Worksheet
|
||||
{
|
||||
$worksheet = $this->translationSpreadsheet->setActiveSheetIndexByName($sheetName);
|
||||
if ($worksheet === null) {
|
||||
throw new Exception("{$sheetName} Worksheet not found");
|
||||
}
|
||||
|
||||
return $worksheet;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ parameters:
|
||||
paths:
|
||||
- src/
|
||||
- tests/
|
||||
- samples/
|
||||
- infra/
|
||||
excludePaths:
|
||||
- src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
|
||||
- src/PhpSpreadsheet/Chart/Renderer/JpGraphRendererBase.php
|
||||
@@ -21,3 +23,4 @@ parameters:
|
||||
ignoreErrors:
|
||||
# Accept a bit anything for assert methods
|
||||
- '~^Parameter \#2 .* of static method PHPUnit\\Framework\\Assert\:\:assert\w+\(\) expects .*, .* given\.$~'
|
||||
- '~^Variable \$helper might not be defined\.$~'
|
||||
|
||||
@@ -126,7 +126,7 @@ $helper->log('Set country code filter (Column C) to "Germany"');
|
||||
$autoFilter->getColumn('D')
|
||||
->setFilterType(Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER)
|
||||
->createRule()
|
||||
->setRule(Rule::AUTOFILTER_COLUMN_RULE_EQUAL, null, Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE)
|
||||
->setRule(Rule::AUTOFILTER_COLUMN_RULE_EQUAL, '', Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE)
|
||||
->setRuleType(Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER);
|
||||
|
||||
$helper->log('Add filter on the Date (Column D) to display year to date');
|
||||
|
||||
@@ -109,9 +109,9 @@ $richText = new RichText();
|
||||
$richText->createText('你好 ');
|
||||
|
||||
$payable = $richText->createTextRun('你 好 吗?');
|
||||
$payable->getFont()->setBold(true);
|
||||
$payable->getFont()->setItalic(true);
|
||||
$payable->getFont()->setColor(new Color(Color::COLOR_DARKGREEN));
|
||||
$payable->getFontOrThrow()->setBold(true);
|
||||
$payable->getFontOrThrow()->setItalic(true);
|
||||
$payable->getFontOrThrow()->setColor(new Color(Color::COLOR_DARKGREEN));
|
||||
|
||||
$richText->createText(', unless specified otherwise on the invoice.');
|
||||
|
||||
@@ -123,7 +123,7 @@ $richText2 = new RichText();
|
||||
$richText2->createText("black text\n");
|
||||
|
||||
$red = $richText2->createTextRun('red text');
|
||||
$red->getFont()->setColor(new Color(Color::COLOR_RED));
|
||||
$red->getFontOrThrow()->setColor(new Color(Color::COLOR_RED));
|
||||
|
||||
$spreadsheet->getActiveSheet()
|
||||
->getCell('C14')
|
||||
|
||||
@@ -36,6 +36,9 @@ $spreadsheet->addNamedRange(new NamedRange('PersonLN', $spreadsheet->getActiveSh
|
||||
|
||||
// Rename named ranges
|
||||
$helper->log('Rename named ranges');
|
||||
if ($spreadsheet->getNamedRange('PersonName') === null) {
|
||||
throw new Exception('named range not found');
|
||||
}
|
||||
$spreadsheet->getNamedRange('PersonName')->setName('PersonFN');
|
||||
|
||||
// Rename worksheet
|
||||
|
||||
@@ -27,12 +27,15 @@ $spreadsheet->getProperties()->setCreator('Maarten Balliauw')
|
||||
|
||||
// Generate an image
|
||||
$helper->log('Generate an image');
|
||||
$gdImage = @imagecreatetruecolor(120, 20);
|
||||
$gdImage = imagecreatetruecolor(120, 20);
|
||||
if (!$gdImage) {
|
||||
exit('Cannot Initialize new GD image stream');
|
||||
throw new Exception('Cannot Initialize new GD image stream');
|
||||
}
|
||||
|
||||
$textColor = imagecolorallocate($gdImage, 255, 255, 255);
|
||||
if ($textColor === false) {
|
||||
throw new Exception('imagecolorallocate failed');
|
||||
}
|
||||
imagestring($gdImage, 1, 5, 5, 'Created with PhpSpreadsheet', $textColor);
|
||||
|
||||
// Add a drawing to the worksheet
|
||||
|
||||
@@ -20,7 +20,8 @@ $spreadsheet->getProperties()
|
||||
->setDescription('Test document for PhpSpreadsheet, generated using PHP classes.')
|
||||
->setKeywords('Office PhpSpreadsheet php')
|
||||
->setCategory('Test result file');
|
||||
function transpose($value)
|
||||
|
||||
function transpose(string $value): array
|
||||
{
|
||||
return [$value];
|
||||
}
|
||||
@@ -30,12 +31,12 @@ $continentColumn = 'D';
|
||||
$column = 'F';
|
||||
|
||||
// Set data for dropdowns
|
||||
$continents = glob(__DIR__ . '/data/continents/*');
|
||||
$continents = glob(__DIR__ . '/data/continents/*') ?: [];
|
||||
foreach ($continents as $key => $filename) {
|
||||
$continent = pathinfo($filename, PATHINFO_FILENAME);
|
||||
$helper->log("Loading $continent");
|
||||
$continent = str_replace(' ', '_', $continent);
|
||||
$countries = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
$countries = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: [];
|
||||
$countryCount = count($countries);
|
||||
|
||||
// Transpose $countries from a row to a column array
|
||||
|
||||
@@ -77,6 +77,7 @@ if (isset($_POST['submit'])) {
|
||||
$quantity = $_POST['quantity'];
|
||||
$fromUnit = $_POST['fromUnit'];
|
||||
$toUnit = $_POST['toUnit'];
|
||||
/** @var float|string */
|
||||
$result = ConvertUOM::CONVERT($quantity, $fromUnit, $toUnit);
|
||||
|
||||
echo "{$quantity} {$units[$_POST['category']][$fromUnit]} is {$result} {$units[$_POST['category']][$toUnit]}", PHP_EOL;
|
||||
|
||||
@@ -13,7 +13,7 @@ if ((isset($argc)) && ($argc > 1)) {
|
||||
$inputFileNames[] = __DIR__ . '/../templates/' . $argv[$i];
|
||||
}
|
||||
} else {
|
||||
$inputFileNames = glob($inputFileNames);
|
||||
$inputFileNames = glob($inputFileNames) ?: [];
|
||||
}
|
||||
foreach ($inputFileNames as $inputFileName) {
|
||||
$inputFileNameShort = basename($inputFileName);
|
||||
@@ -40,7 +40,7 @@ foreach ($inputFileNames as $inputFileName) {
|
||||
} else {
|
||||
natsort($chartNames);
|
||||
foreach ($chartNames as $i => $chartName) {
|
||||
$chart = $worksheet->getChartByName($chartName);
|
||||
$chart = $worksheet->getChartByNameOrThrow($chartName);
|
||||
if ($chart->getTitle() !== null) {
|
||||
$caption = '"' . $chart->getTitle()->getCaptionText($spreadsheet) . '"';
|
||||
} else {
|
||||
@@ -48,15 +48,15 @@ foreach ($inputFileNames as $inputFileName) {
|
||||
}
|
||||
$helper->log(' ' . $chartName . ' - ' . $caption);
|
||||
$indentation = str_repeat(' ', strlen($chartName) + 3);
|
||||
$groupCount = $chart->getPlotArea()->getPlotGroupCount();
|
||||
$groupCount = $chart->getPlotAreaOrThrow()->getPlotGroupCount();
|
||||
if ($groupCount == 1) {
|
||||
$chartType = $chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();
|
||||
$chartType = $chart->getPlotAreaOrThrow()->getPlotGroupByIndex(0)->getPlotType();
|
||||
$helper->log($indentation . ' ' . $chartType);
|
||||
$helper->renderChart($chart, __FILE__);
|
||||
} else {
|
||||
$chartTypes = [];
|
||||
for ($i = 0; $i < $groupCount; ++$i) {
|
||||
$chartTypes[] = $chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();
|
||||
$chartTypes[] = $chart->getPlotAreaOrThrow()->getPlotGroupByIndex($i)->getPlotType();
|
||||
}
|
||||
$chartTypes = array_unique($chartTypes);
|
||||
if (count($chartTypes) == 1) {
|
||||
|
||||
@@ -18,7 +18,7 @@ if ((isset($argc)) && ($argc > 1)) {
|
||||
$inputFileNames[] = __DIR__ . '/../templates/' . $argv[$i];
|
||||
}
|
||||
} else {
|
||||
$inputFileNames = glob($inputFileNames);
|
||||
$inputFileNames = glob($inputFileNames) ?: [];
|
||||
}
|
||||
foreach ($inputFileNames as $inputFileName) {
|
||||
$inputFileNameShort = basename($inputFileName);
|
||||
@@ -46,22 +46,22 @@ foreach ($inputFileNames as $inputFileName) {
|
||||
} else {
|
||||
natsort($chartNames);
|
||||
foreach ($chartNames as $i => $chartName) {
|
||||
$chart = $worksheet->getChartByName($chartName);
|
||||
$chart = $worksheet->getChartByNameOrThrow($chartName);
|
||||
if ($chart->getTitle() !== null) {
|
||||
$caption = '"' . implode(' ', $chart->getTitle()->getCaption()) . '"';
|
||||
$caption = '"' . $chart->getTitle()->getCaptionText($spreadsheet) . '"';
|
||||
} else {
|
||||
$caption = 'Untitled';
|
||||
}
|
||||
$helper->log(' ' . $chartName . ' - ' . $caption);
|
||||
$helper->log(str_repeat(' ', strlen($chartName) + 3));
|
||||
$groupCount = $chart->getPlotArea()->getPlotGroupCount();
|
||||
$groupCount = $chart->getPlotAreaOrThrow()->getPlotGroupCount();
|
||||
if ($groupCount == 1) {
|
||||
$chartType = $chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();
|
||||
$chartType = $chart->getPlotAreaOrThrow()->getPlotGroupByIndex(0)->getPlotType();
|
||||
$helper->log(' ' . $chartType);
|
||||
} else {
|
||||
$chartTypes = [];
|
||||
for ($i = 0; $i < $groupCount; ++$i) {
|
||||
$chartTypes[] = $chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();
|
||||
$chartTypes[] = $chart->getPlotAreaOrThrow()->getPlotGroupByIndex($i)->getPlotType();
|
||||
}
|
||||
$chartTypes = array_unique($chartTypes);
|
||||
if (count($chartTypes) == 1) {
|
||||
|
||||
@@ -20,7 +20,7 @@ if ((isset($argc)) && ($argc > 1)) {
|
||||
$inputFileNames[] = __DIR__ . '/../templates/' . $argv[$i];
|
||||
}
|
||||
} else {
|
||||
$inputFileNames = glob($inputFileNames);
|
||||
$inputFileNames = glob($inputFileNames) ?: [];
|
||||
}
|
||||
foreach ($inputFileNames as $inputFileName) {
|
||||
$inputFileNameShort = basename($inputFileName);
|
||||
@@ -48,22 +48,22 @@ foreach ($inputFileNames as $inputFileName) {
|
||||
} else {
|
||||
natsort($chartNames);
|
||||
foreach ($chartNames as $i => $chartName) {
|
||||
$chart = $worksheet->getChartByName($chartName);
|
||||
$chart = $worksheet->getChartByNameOrThrow($chartName);
|
||||
if ($chart->getTitle() !== null) {
|
||||
$caption = '"' . implode(' ', $chart->getTitle()->getCaption()) . '"';
|
||||
$caption = '"' . $chart->getTitle()->getCaptionText($spreadsheet) . '"';
|
||||
} else {
|
||||
$caption = 'Untitled';
|
||||
}
|
||||
$helper->log(' ' . $chartName . ' - ' . $caption);
|
||||
$helper->log(str_repeat(' ', strlen($chartName) + 3));
|
||||
$groupCount = $chart->getPlotArea()->getPlotGroupCount();
|
||||
$groupCount = $chart->getPlotAreaOrThrow()->getPlotGroupCount();
|
||||
if ($groupCount == 1) {
|
||||
$chartType = $chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();
|
||||
$chartType = $chart->getPlotAreaOrThrow()->getPlotGroupByIndex(0)->getPlotType();
|
||||
$helper->log(' ' . $chartType);
|
||||
} else {
|
||||
$chartTypes = [];
|
||||
for ($i = 0; $i < $groupCount; ++$i) {
|
||||
$chartTypes[] = $chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();
|
||||
$chartTypes[] = $chart->getPlotAreaOrThrow()->getPlotGroupByIndex($i)->getPlotType();
|
||||
}
|
||||
$chartTypes = array_unique($chartTypes);
|
||||
if (count($chartTypes) == 1) {
|
||||
|
||||
@@ -195,7 +195,7 @@ $spreadsheet->createSheet();
|
||||
$chartSheet = $spreadsheet->getSheet(1);
|
||||
$chartSheet->setTitle('Scatter+Line Chart');
|
||||
|
||||
$chartSheet = $spreadsheet->getSheetByName('Scatter+Line Chart');
|
||||
$chartSheet = $spreadsheet->getSheetByNameOrThrow('Scatter+Line Chart');
|
||||
// Add the chart to the worksheet
|
||||
$chartSheet->addChart($chart);
|
||||
|
||||
@@ -340,11 +340,14 @@ $spreadsheet->disconnectWorksheets();
|
||||
|
||||
function dateRange(int $nrows, Spreadsheet $wrkbk): array
|
||||
{
|
||||
$dataSheet = $wrkbk->getSheetByName('Data');
|
||||
$dataSheet = $wrkbk->getSheetByNameOrThrow('Data');
|
||||
|
||||
// start the xaxis at the beginning of the quarter of the first date
|
||||
$startDateStr = $dataSheet->getCell('B2')->getValue(); // yyyy-mm-dd date string
|
||||
$startDate = DateTime::createFromFormat('Y-m-d', $startDateStr); // php date obj
|
||||
if ($startDate === false) {
|
||||
throw new Exception("invalid start date $startDateStr on spreadsheet");
|
||||
}
|
||||
|
||||
// get date of first day of the quarter of the start date
|
||||
$startMonth = (int) $startDate->format('n'); // suppress leading zero
|
||||
@@ -357,12 +360,19 @@ function dateRange(int $nrows, Spreadsheet $wrkbk): array
|
||||
// end the xaxis at the end of the quarter of the last date
|
||||
$lastDateStr = $dataSheet->getCell([2, $nrows + 1])->getValue();
|
||||
$lastDate = DateTime::createFromFormat('Y-m-d', $lastDateStr);
|
||||
if ($lastDate === false) {
|
||||
throw new Exception("invalid last date $lastDateStr on spreadsheet");
|
||||
}
|
||||
$lastMonth = (int) $lastDate->format('n');
|
||||
$lastYr = (int) $lastDate->format('Y');
|
||||
$qtr = intdiv($lastMonth, 3) + (($lastMonth % 3 > 0) ? 1 : 0);
|
||||
$qtrEndMonth = 3 + (($qtr - 1) * 3);
|
||||
$qtrEndMonth = sprintf('%02d', $qtrEndMonth);
|
||||
$lastDOM = DateTime::createFromFormat('Y-m-d', "$lastYr-$qtrEndMonth-01")->format('t');
|
||||
$lastDOMDate = DateTime::createFromFormat('Y-m-d', "$lastYr-$qtrEndMonth-01");
|
||||
if ($lastDOMDate === false) {
|
||||
throw new Exception("invalid last dom date $lastYr-$qtrEndMonth-01 on spreadsheet");
|
||||
}
|
||||
$lastDOM = $lastDOMDate->format('t');
|
||||
$qtrEndStr = "$lastYr-$qtrEndMonth-$lastDOM";
|
||||
$ExcelQtrEndDateVal = SharedDate::convertIsoDate($qtrEndStr);
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ $spreadsheet->createSheet();
|
||||
$chartSheet = $spreadsheet->getSheet(1);
|
||||
$chartSheet->setTitle('Scatter Chart');
|
||||
|
||||
$chartSheet = $spreadsheet->getSheetByName('Scatter Chart');
|
||||
$chartSheet = $spreadsheet->getSheetByNameOrThrow('Scatter Chart');
|
||||
// Add the chart to the worksheet
|
||||
$chartSheet->addChart($chart);
|
||||
|
||||
|
||||
@@ -19,11 +19,13 @@ if ((isset($argc)) && ($argc > 1)) {
|
||||
$inputFileNames[] = __DIR__ . '/../templates/' . $argv[$i];
|
||||
}
|
||||
} else {
|
||||
$inputFileNames = glob($inputFileNames);
|
||||
$inputFileNames = glob($inputFileNames) ?: [];
|
||||
}
|
||||
if (count($inputFileNames) === 1) {
|
||||
/** @var string[] */
|
||||
$unresolvedErrors = [];
|
||||
} else {
|
||||
/** @var string[] */
|
||||
$unresolvedErrors = [
|
||||
// The following spreadsheet was created by 3rd party software,
|
||||
// and doesn't include the data that usually accompanies a chart.
|
||||
@@ -66,9 +68,9 @@ foreach ($inputFileNames as $inputFileName) {
|
||||
natsort($chartNames);
|
||||
foreach ($chartNames as $j => $chartName) {
|
||||
$i = $renderedCharts + $j;
|
||||
$chart = $worksheet->getChartByName($chartName);
|
||||
$chart = $worksheet->getChartByNameOrThrow($chartName);
|
||||
if ($chart->getTitle() !== null) {
|
||||
$caption = '"' . implode(' ', $chart->getTitle()->getCaption()) . '"';
|
||||
$caption = '"' . $chart->getTitle()->getCaptionText($spreadsheet) . '"';
|
||||
} else {
|
||||
$caption = 'Untitled';
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ require __DIR__ . '/../Header.php';
|
||||
Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\MtJpGraphRenderer::class);
|
||||
|
||||
$inputFileType = 'Xlsx';
|
||||
$inputFileNames = $helper->getTemporaryFolder() . '/33_Chart_create_*.xlsx';
|
||||
$inputFileNamesString = $helper->getTemporaryFolder() . '/33_Chart_create_*.xlsx';
|
||||
|
||||
if ((isset($argc)) && ($argc > 1)) {
|
||||
$inputFileNames = [];
|
||||
@@ -18,11 +18,13 @@ if ((isset($argc)) && ($argc > 1)) {
|
||||
$inputFileNames[] = __DIR__ . '/../templates/' . $argv[$i];
|
||||
}
|
||||
} else {
|
||||
$inputFileNames = glob($inputFileNames);
|
||||
$inputFileNames = glob($inputFileNamesString) ?: [];
|
||||
}
|
||||
if (count($inputFileNames) === 1) {
|
||||
/** @var string[] */
|
||||
$unresolvedErrors = [];
|
||||
} else {
|
||||
/** @var string[] */
|
||||
$unresolvedErrors = [
|
||||
//'33_Chart_create_bar_stacked.xlsx', // fixed with mitoteam/jpgraph 10.3
|
||||
];
|
||||
@@ -62,9 +64,9 @@ foreach ($inputFileNames as $inputFileName) {
|
||||
natsort($chartNames);
|
||||
foreach ($chartNames as $j => $chartName) {
|
||||
$i = $renderedCharts + $j;
|
||||
$chart = $worksheet->getChartByName($chartName);
|
||||
$chart = $worksheet->getChartByNameOrThrow($chartName);
|
||||
if ($chart->getTitle() !== null) {
|
||||
$caption = '"' . implode(' ', $chart->getTitle()->getCaption()) . '"';
|
||||
$caption = '"' . $chart->getTitle()->getCaptionText($spreadsheet) . '"';
|
||||
} else {
|
||||
$caption = 'Untitled';
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ foreach ($inputFileNames as $inputFileName) {
|
||||
} else {
|
||||
natsort($chartNames);
|
||||
foreach ($chartNames as $i => $chartName) {
|
||||
$chart = $worksheet->getChartByName($chartName);
|
||||
$chart = $worksheet->getChartByNameOrThrow($chartName);
|
||||
if ($chart->getTitle() !== null) {
|
||||
$caption = '"' . $chart->getTitle()->getCaptionText($spreadsheet) . '"';
|
||||
} else {
|
||||
@@ -45,15 +45,15 @@ foreach ($inputFileNames as $inputFileName) {
|
||||
}
|
||||
$helper->log(' ' . $chartName . ' - ' . $caption);
|
||||
$indentation = str_repeat(' ', strlen($chartName) + 3);
|
||||
$groupCount = $chart->getPlotArea()->getPlotGroupCount();
|
||||
$groupCount = $chart->getPlotAreaOrThrow()->getPlotGroupCount();
|
||||
if ($groupCount == 1) {
|
||||
$chartType = $chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();
|
||||
$chartType = $chart->getPlotAreaOrThrow()->getPlotGroupByIndex(0)->getPlotType();
|
||||
$helper->log($indentation . ' ' . $chartType);
|
||||
$helper->renderChart($chart, __FILE__, $spreadsheet);
|
||||
} else {
|
||||
$chartTypes = [];
|
||||
for ($i = 0; $i < $groupCount; ++$i) {
|
||||
$chartTypes[] = $chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();
|
||||
$chartTypes[] = $chart->getPlotAreaOrThrow()->getPlotGroupByIndex($i)->getPlotType();
|
||||
}
|
||||
$chartTypes = array_unique($chartTypes);
|
||||
if (count($chartTypes) == 1) {
|
||||
|
||||
@@ -40,7 +40,7 @@ setYearlyData($worksheet, '2020', $data2020);
|
||||
$worksheet = $spreadsheet->addSheet(new Worksheet($spreadsheet));
|
||||
setYearlyData($worksheet, '2020', [], 'GROWTH');
|
||||
|
||||
function setYearlyData(Worksheet $worksheet, string $year, $yearlyData, ?string $title = null): void
|
||||
function setYearlyData(Worksheet $worksheet, string $year, array $yearlyData, ?string $title = null): void
|
||||
{
|
||||
// Set up some basic data
|
||||
$worksheetTitle = $title ?: $year;
|
||||
|
||||
@@ -60,12 +60,18 @@ $worksheet
|
||||
->setCellValue("B{$row}", '=SUM(COLUMN_DATA_VALUES)')
|
||||
->setCellValue("C{$row}", '=SUM(COLUMN_DATA_VALUES)');
|
||||
|
||||
$range = $spreadsheet->getNamedRange('CHARGE_RATE');
|
||||
if ($range === null || $range->getWorksheet() === null) {
|
||||
throw new Exception('expected named range not found');
|
||||
}
|
||||
$chargeRateCellValue = $spreadsheet
|
||||
->getSheetByNameOrThrow($range->getWorksheet()->getTitle())
|
||||
->getCell($range->getCellsInRange()[0])->getValue();
|
||||
|
||||
$helper->log(sprintf(
|
||||
'Worked %.2f hours at a rate of %s - Charge to the client is %.2f',
|
||||
$worksheet->getCell("B{$row}")->getCalculatedValue(),
|
||||
$chargeRateCellValue = $spreadsheet
|
||||
->getSheetByName($spreadsheet->getNamedRange('CHARGE_RATE')->getWorksheet()->getTitle())
|
||||
->getCell($spreadsheet->getNamedRange('CHARGE_RATE')->getCellsInRange()[0])->getValue(),
|
||||
$chargeRateCellValue,
|
||||
$worksheet->getCell("C{$row}")->getCalculatedValue()
|
||||
));
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ function replaceBody(string $html): string
|
||||
</body>
|
||||
EOF;
|
||||
|
||||
return preg_replace($bodystring, $bodyrepl, $html);
|
||||
return preg_replace($bodystring, $bodyrepl, $html) ?? '';
|
||||
}
|
||||
|
||||
require __DIR__ . '/../Header.php';
|
||||
|
||||
@@ -16,7 +16,7 @@ function addHeadersFootersMpdf2000(string $html): string
|
||||
odd-footer-name: html_myFooter2;
|
||||
|
||||
EOF;
|
||||
$html = preg_replace('/@page page0 {/', $pagerepl, $html);
|
||||
$html = preg_replace('/@page page0 {/', $pagerepl, $html) ?? '';
|
||||
$bodystring = '/<body>/';
|
||||
$simulatedBodyStart = Mpdf::SIMULATED_BODY_START;
|
||||
$bodyrepl = <<<EOF
|
||||
@@ -40,7 +40,7 @@ function addHeadersFootersMpdf2000(string $html): string
|
||||
|
||||
EOF;
|
||||
|
||||
return preg_replace($bodystring, $bodyrepl, $html);
|
||||
return preg_replace($bodystring, $bodyrepl, $html) ?? '';
|
||||
}
|
||||
|
||||
$spreadsheet = new Spreadsheet();
|
||||
|
||||
@@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf2;
|
||||
|
||||
require __DIR__ . '/../Header.php';
|
||||
require_once __DIR__ . '/mpdf2.inc';
|
||||
require_once __DIR__ . '/Mpdf2.php';
|
||||
|
||||
$spreadsheet = new Spreadsheet();
|
||||
|
||||
|
||||
@@ -34,9 +34,9 @@ class Mpdf2 extends Mpdf
|
||||
$fontFile = 'ShadowsIntoLight-Regular.ttf';
|
||||
$config['fontdata'] = $fontdata + [ // lowercase letters only in font key
|
||||
'shadowsintolight' => [
|
||||
'R' => $fontFile,
|
||||
],
|
||||
];
|
||||
'R' => $fontFile,
|
||||
],
|
||||
];
|
||||
|
||||
return new \Mpdf\Mpdf($config);
|
||||
}
|
||||
@@ -4,9 +4,15 @@ use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
|
||||
require __DIR__ . '/../Header.php';
|
||||
|
||||
/** @return string[] */
|
||||
function getDesiredSheetNames(): array
|
||||
{
|
||||
return ['Data Sheet #1', 'Data Sheet #3'];
|
||||
}
|
||||
|
||||
$inputFileType = 'Xls';
|
||||
$inputFileName = __DIR__ . '/sampleData/example1.xls';
|
||||
$sheetnames = ['Data Sheet #1', 'Data Sheet #3'];
|
||||
$sheetnames = getDesiredSheetNames();
|
||||
|
||||
$helper->log('Loading file ' . pathinfo($inputFileName, PATHINFO_BASENAME) . ' using IOFactory with a defined reader type of ' . $inputFileType);
|
||||
$reader = IOFactory::createReader($inputFileType);
|
||||
|
||||
@@ -13,13 +13,13 @@ $sheetname = 'Data Sheet #3';
|
||||
|
||||
class MyReadFilter implements IReadFilter
|
||||
{
|
||||
private $startRow = 0;
|
||||
private int $startRow = 0;
|
||||
|
||||
private $endRow = 0;
|
||||
private int $endRow = 0;
|
||||
|
||||
private $columns = [];
|
||||
private array $columns = [];
|
||||
|
||||
public function __construct($startRow, $endRow, $columns)
|
||||
public function __construct(int $startRow, int $endRow, array $columns)
|
||||
{
|
||||
$this->startRow = $startRow;
|
||||
$this->endRow = $endRow;
|
||||
|
||||
+3
-6
@@ -13,17 +13,14 @@ $inputFileName = __DIR__ . '/sampleData/example2.xls';
|
||||
/** Define a Read Filter class implementing IReadFilter */
|
||||
class ChunkReadFilter implements IReadFilter
|
||||
{
|
||||
private $startRow = 0;
|
||||
private int $startRow = 0;
|
||||
|
||||
private $endRow = 0;
|
||||
private int $endRow = 0;
|
||||
|
||||
/**
|
||||
* We expect a list of the rows that we want to read to be passed into the constructor.
|
||||
*
|
||||
* @param mixed $startRow
|
||||
* @param mixed $chunkSize
|
||||
*/
|
||||
public function __construct($startRow, $chunkSize)
|
||||
public function __construct(int $startRow, int $chunkSize)
|
||||
{
|
||||
$this->startRow = $startRow;
|
||||
$this->endRow = $startRow + $chunkSize;
|
||||
|
||||
+3
-6
@@ -13,17 +13,14 @@ $inputFileName = __DIR__ . '/sampleData/example2.xls';
|
||||
/** Define a Read Filter class implementing IReadFilter */
|
||||
class ChunkReadFilter implements IReadFilter
|
||||
{
|
||||
private $startRow = 0;
|
||||
private int $startRow = 0;
|
||||
|
||||
private $endRow = 0;
|
||||
private int $endRow = 0;
|
||||
|
||||
/**
|
||||
* Set the list of rows that we want to read.
|
||||
*
|
||||
* @param mixed $startRow
|
||||
* @param mixed $chunkSize
|
||||
*/
|
||||
public function setRows($startRow, $chunkSize): void
|
||||
public function setRows(int $startRow, int $chunkSize): void
|
||||
{
|
||||
$this->startRow = $startRow;
|
||||
$this->endRow = $startRow + $chunkSize;
|
||||
|
||||
+5
-8
@@ -13,17 +13,14 @@ $inputFileName = __DIR__ . '/sampleData/example2.csv';
|
||||
/** Define a Read Filter class implementing IReadFilter */
|
||||
class ChunkReadFilter implements IReadFilter
|
||||
{
|
||||
private $startRow = 0;
|
||||
private int $startRow = 0;
|
||||
|
||||
private $endRow = 0;
|
||||
private int $endRow = 0;
|
||||
|
||||
/**
|
||||
* Set the list of rows that we want to read.
|
||||
*
|
||||
* @param mixed $startRow
|
||||
* @param mixed $chunkSize
|
||||
*/
|
||||
public function setRows($startRow, $chunkSize): void
|
||||
public function setRows(int $startRow, int $chunkSize): void
|
||||
{
|
||||
$this->startRow = $startRow;
|
||||
$this->endRow = $startRow + $chunkSize;
|
||||
@@ -51,8 +48,8 @@ $chunkFilter = new ChunkReadFilter();
|
||||
|
||||
// Tell the Reader that we want to use the Read Filter that we've Instantiated
|
||||
// and that we want to store it in contiguous rows/columns
|
||||
$reader->setReadFilter($chunkFilter)
|
||||
->setContiguous(true);
|
||||
$reader->setReadFilter($chunkFilter);
|
||||
$reader->setContiguous(true);
|
||||
|
||||
// Instantiate a new PhpSpreadsheet object manually
|
||||
$spreadsheet = new Spreadsheet();
|
||||
|
||||
@@ -14,9 +14,12 @@ $aSheet = $spreadsheet->getActiveSheet();
|
||||
|
||||
$gdImage = @imagecreatetruecolor(120, 20);
|
||||
if ($gdImage === false) {
|
||||
throw new \Exception('imagecreatetruecolor failed');
|
||||
throw new Exception('imagecreatetruecolor failed');
|
||||
}
|
||||
$textColor = imagecolorallocate($gdImage, 255, 255, 255);
|
||||
if ($textColor === false) {
|
||||
throw new Exception('imagecolorallocate failed');
|
||||
}
|
||||
imagestring($gdImage, 1, 5, 5, 'Created with PhpSpreadsheet', $textColor);
|
||||
|
||||
$baseUrl = 'https://phpspreadsheet.readthedocs.io';
|
||||
@@ -52,7 +55,7 @@ unlink($filename);
|
||||
$helper->log('reloaded Spreadsheet');
|
||||
|
||||
foreach ($reloadedSpreadsheet->getActiveSheet()->getDrawingCollection() as $pDrawing) {
|
||||
$helper->log('Read link: ' . $pDrawing->getHyperlink()->getUrl());
|
||||
$helper->log('Read link: ' . ($pDrawing->getHyperlink()?->getUrl() ?? 'none'));
|
||||
}
|
||||
|
||||
$helper->log('end');
|
||||
|
||||
@@ -83,11 +83,11 @@ $currencies = [
|
||||
if (isset($_POST['submit'])) {
|
||||
if (!is_numeric($_POST['number'])) {
|
||||
$helper->log('The Sample Number Value must be numeric');
|
||||
} elseif (!is_numeric($_POST['decimals']) || str_contains($_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
|
||||
} elseif (!is_numeric($_POST['decimals']) || str_contains((string) $_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
|
||||
$helper->log('The Decimal Places value must be positive integer');
|
||||
} else {
|
||||
try {
|
||||
$wizard = new Wizard\Accounting($_POST['currency'], $_POST['decimals'], isset($_POST['thousands']), (bool) $_POST['position'], (bool) $_POST['spacing']);
|
||||
$wizard = new Wizard\Accounting($_POST['currency'], (int) $_POST['decimals'], isset($_POST['thousands']), (bool) $_POST['position'], (bool) $_POST['spacing']);
|
||||
$mask = $wizard->format();
|
||||
$example = (string) NumberFormat::toFormattedString((float) $_POST['number'], $mask);
|
||||
$helper->log('<hr /><b>Code:</b><br />');
|
||||
|
||||
@@ -83,11 +83,11 @@ $currencies = [
|
||||
if (isset($_POST['submit'])) {
|
||||
if (!is_numeric($_POST['number'])) {
|
||||
$helper->log('The Sample Number Value must be numeric');
|
||||
} elseif (!is_numeric($_POST['decimals']) || str_contains($_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
|
||||
} elseif (!is_numeric($_POST['decimals']) || str_contains((string) $_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
|
||||
$helper->log('The Decimal Places value must be positive integer');
|
||||
} else {
|
||||
try {
|
||||
$wizard = new Wizard\Currency($_POST['currency'], $_POST['decimals'], isset($_POST['thousands']), (bool) $_POST['position'], (bool) $_POST['spacing']);
|
||||
$wizard = new Wizard\Currency($_POST['currency'], (int) $_POST['decimals'], isset($_POST['thousands']), (bool) $_POST['position'], (bool) $_POST['spacing']);
|
||||
$mask = $wizard->format();
|
||||
$example = (string) NumberFormat::toFormattedString((float) $_POST['number'], $mask);
|
||||
$helper->log('<hr /><b>Code:</b><br />');
|
||||
|
||||
@@ -49,11 +49,11 @@ if ($helper->isCli()) {
|
||||
if (isset($_POST['submit'])) {
|
||||
if (!is_numeric($_POST['number'])) {
|
||||
$helper->log('The Sample Number Value must be numeric');
|
||||
} elseif (!is_numeric($_POST['decimals']) || str_contains($_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
|
||||
} elseif (!is_numeric($_POST['decimals']) || str_contains((string) $_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
|
||||
$helper->log('The Decimal Places value must be positive integer');
|
||||
} else {
|
||||
try {
|
||||
$wizard = new Wizard\Number($_POST['decimals'], isset($_POST['thousands']));
|
||||
$wizard = new Wizard\Number((int) $_POST['decimals'], isset($_POST['thousands']));
|
||||
$mask = $wizard->format();
|
||||
$example = NumberFormat::toFormattedString((float) $_POST['number'], $mask);
|
||||
$helper->log('<hr /><b>Code:</b><br />');
|
||||
|
||||
@@ -43,11 +43,11 @@ if ($helper->isCli()) {
|
||||
if (isset($_POST['submit'])) {
|
||||
if (!is_numeric($_POST['number'])) {
|
||||
$helper->log('The Sample Number Value must be numeric');
|
||||
} elseif (!is_numeric($_POST['decimals']) || str_contains($_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
|
||||
} elseif (!is_numeric($_POST['decimals']) || str_contains((string) $_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
|
||||
$helper->log('The Decimal Places value must be positive integer');
|
||||
} else {
|
||||
try {
|
||||
$wizard = new Wizard\Percentage($_POST['decimals']);
|
||||
$wizard = new Wizard\Percentage((int) $_POST['decimals']);
|
||||
$mask = $wizard->format();
|
||||
$example = (string) NumberFormat::toFormattedString((float) $_POST['number'], $mask);
|
||||
$helper->log('<hr /><b>Code:</b><br />');
|
||||
|
||||
@@ -43,11 +43,11 @@ if ($helper->isCli()) {
|
||||
if (isset($_POST['submit'])) {
|
||||
if (!is_numeric($_POST['number'])) {
|
||||
$helper->log('The Sample Number Value must be numeric');
|
||||
} elseif (!is_numeric($_POST['decimals']) || str_contains($_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
|
||||
} elseif (!is_numeric($_POST['decimals']) || str_contains((string) $_POST['decimals'], '.') || (int) $_POST['decimals'] < 0) {
|
||||
$helper->log('The Decimal Places value must be positive integer');
|
||||
} else {
|
||||
try {
|
||||
$wizard = new Wizard\Scientific($_POST['decimals']);
|
||||
$wizard = new Wizard\Scientific((int) $_POST['decimals']);
|
||||
$mask = $wizard->format();
|
||||
$example = (string) NumberFormat::toFormattedString((float) $_POST['number'], $mask);
|
||||
$helper->log('<hr /><b>Code:</b><br />');
|
||||
|
||||
@@ -74,19 +74,19 @@ $helper->log('Add comments');
|
||||
|
||||
$spreadsheet->getActiveSheet()->getComment('E11')->setAuthor('PhpSpreadsheet');
|
||||
$commentRichText = $spreadsheet->getActiveSheet()->getComment('E11')->getText()->createTextRun('PhpSpreadsheet:');
|
||||
$commentRichText->getFont()->setBold(true);
|
||||
$commentRichText->getFontOrThrow()->setBold(true);
|
||||
$spreadsheet->getActiveSheet()->getComment('E11')->getText()->createTextRun("\r\n");
|
||||
$spreadsheet->getActiveSheet()->getComment('E11')->getText()->createTextRun('Total amount on the current invoice, excluding VAT.');
|
||||
|
||||
$spreadsheet->getActiveSheet()->getComment('E12')->setAuthor('PhpSpreadsheet');
|
||||
$commentRichText = $spreadsheet->getActiveSheet()->getComment('E12')->getText()->createTextRun('PhpSpreadsheet:');
|
||||
$commentRichText->getFont()->setBold(true);
|
||||
$commentRichText->getFontOrThrow()->setBold(true);
|
||||
$spreadsheet->getActiveSheet()->getComment('E12')->getText()->createTextRun("\r\n");
|
||||
$spreadsheet->getActiveSheet()->getComment('E12')->getText()->createTextRun('Total amount of VAT on the current invoice.');
|
||||
|
||||
$spreadsheet->getActiveSheet()->getComment('E13')->setAuthor('PhpSpreadsheet');
|
||||
$commentRichText = $spreadsheet->getActiveSheet()->getComment('E13')->getText()->createTextRun('PhpSpreadsheet:');
|
||||
$commentRichText->getFont()->setBold(true);
|
||||
$commentRichText->getFontOrThrow()->setBold(true);
|
||||
$spreadsheet->getActiveSheet()->getComment('E13')->getText()->createTextRun("\r\n");
|
||||
$spreadsheet->getActiveSheet()->getComment('E13')->getText()->createTextRun('Total amount on the current invoice, including VAT.');
|
||||
$spreadsheet->getActiveSheet()->getComment('E13')->setWidth('100pt');
|
||||
@@ -100,9 +100,9 @@ $richText = new RichText();
|
||||
$richText->createText('This invoice is ');
|
||||
|
||||
$payable = $richText->createTextRun('payable within thirty days after the end of the month');
|
||||
$payable->getFont()->setBold(true);
|
||||
$payable->getFont()->setItalic(true);
|
||||
$payable->getFont()->setColor(new Color(Color::COLOR_DARKGREEN));
|
||||
$payable->getFontOrThrow()->setBold(true);
|
||||
$payable->getFontOrThrow()->setItalic(true);
|
||||
$payable->getFontOrThrow()->setColor(new Color(Color::COLOR_DARKGREEN));
|
||||
|
||||
$richText->createText(', unless specified otherwise on the invoice.');
|
||||
|
||||
|
||||
@@ -74,19 +74,19 @@ $helper->log('Add comments');
|
||||
|
||||
$spreadsheet->getActiveSheet()->getComment('E11')->setAuthor('PhpSpreadsheet');
|
||||
$commentRichText = $spreadsheet->getActiveSheet()->getComment('E11')->getText()->createTextRun('PhpSpreadsheet:');
|
||||
$commentRichText->getFont()->setBold(true);
|
||||
$commentRichText->getFontOrThrow()->setBold(true);
|
||||
$spreadsheet->getActiveSheet()->getComment('E11')->getText()->createTextRun("\r\n");
|
||||
$spreadsheet->getActiveSheet()->getComment('E11')->getText()->createTextRun('Total amount on the current invoice, excluding VAT.');
|
||||
|
||||
$spreadsheet->getActiveSheet()->getComment('E12')->setAuthor('PhpSpreadsheet');
|
||||
$commentRichText = $spreadsheet->getActiveSheet()->getComment('E12')->getText()->createTextRun('PhpSpreadsheet:');
|
||||
$commentRichText->getFont()->setBold(true);
|
||||
$commentRichText->getFontOrThrow()->setBold(true);
|
||||
$spreadsheet->getActiveSheet()->getComment('E12')->getText()->createTextRun("\r\n");
|
||||
$spreadsheet->getActiveSheet()->getComment('E12')->getText()->createTextRun('Total amount of VAT on the current invoice.');
|
||||
|
||||
$spreadsheet->getActiveSheet()->getComment('E13')->setAuthor('PhpSpreadsheet');
|
||||
$commentRichText = $spreadsheet->getActiveSheet()->getComment('E13')->getText()->createTextRun('PhpSpreadsheet:');
|
||||
$commentRichText->getFont()->setBold(true);
|
||||
$commentRichText->getFontOrThrow()->setBold(true);
|
||||
$spreadsheet->getActiveSheet()->getComment('E13')->getText()->createTextRun("\r\n");
|
||||
$spreadsheet->getActiveSheet()->getComment('E13')->getText()->createTextRun('Total amount on the current invoice, including VAT.');
|
||||
$spreadsheet->getActiveSheet()->getComment('E13')->setWidth('100pt');
|
||||
@@ -100,9 +100,9 @@ $richText = new RichText();
|
||||
$richText->createText('This invoice is ');
|
||||
|
||||
$payable = $richText->createTextRun('payable within thirty days after the end of the month');
|
||||
$payable->getFont()->setBold(true);
|
||||
$payable->getFont()->setItalic(true);
|
||||
$payable->getFont()->setColor(new Color(Color::COLOR_DARKGREEN));
|
||||
$payable->getFontOrThrow()->setBold(true);
|
||||
$payable->getFontOrThrow()->setItalic(true);
|
||||
$payable->getFontOrThrow()->setColor(new Color(Color::COLOR_DARKGREEN));
|
||||
|
||||
$richText->createText(', unless specified otherwise on the invoice.');
|
||||
|
||||
|
||||
@@ -140,13 +140,13 @@ class DataValidation
|
||||
/**
|
||||
* Set Formula 1.
|
||||
*
|
||||
* @param string $formula
|
||||
* @param float|int|string $formula usually string, but can be number (test for equal)
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFormula1($formula): static
|
||||
{
|
||||
$this->formula1 = $formula;
|
||||
$this->formula1 = (string) $formula;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -164,13 +164,13 @@ class DataValidation
|
||||
/**
|
||||
* Set Formula 2.
|
||||
*
|
||||
* @param string $formula
|
||||
* @param float|int|string $formula usually string, but can be number (test for equal)
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFormula2($formula): static
|
||||
{
|
||||
$this->formula2 = $formula;
|
||||
$this->formula2 = (string) $formula;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -124,10 +124,10 @@ class Axis extends Properties
|
||||
return $this->axisType === self::AXIS_TYPE_DATE || (bool) $this->axisNumber['numeric'];
|
||||
}
|
||||
|
||||
public function setAxisOption(string $key, ?string $value): void
|
||||
public function setAxisOption(string $key, null|float|int|string $value): void
|
||||
{
|
||||
if ($value !== null && $value !== '') {
|
||||
$this->axisOptions[$key] = $value;
|
||||
$this->axisOptions[$key] = (string) $value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,11 +141,11 @@ class Axis extends Properties
|
||||
?string $axisOrientation = null,
|
||||
?string $majorTmt = null,
|
||||
?string $minorTmt = null,
|
||||
?string $minimum = null,
|
||||
?string $maximum = null,
|
||||
?string $majorUnit = null,
|
||||
?string $minorUnit = null,
|
||||
?string $textRotation = null,
|
||||
null|float|int|string $minimum = null,
|
||||
null|float|int|string $maximum = null,
|
||||
null|float|int|string $majorUnit = null,
|
||||
null|float|int|string $minorUnit = null,
|
||||
null|float|int|string $textRotation = null,
|
||||
?string $hidden = null,
|
||||
?string $baseTimeUnit = null,
|
||||
?string $majorTimeUnit = null,
|
||||
|
||||
@@ -285,6 +285,16 @@ class Chart
|
||||
return $this->plotArea;
|
||||
}
|
||||
|
||||
public function getPlotAreaOrThrow(): PlotArea
|
||||
{
|
||||
$plotArea = $this->getPlotArea();
|
||||
if ($plotArea !== null) {
|
||||
return $plotArea;
|
||||
}
|
||||
|
||||
throw new Exception('Chart has no PlotArea');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Plot Area.
|
||||
*/
|
||||
|
||||
@@ -124,7 +124,7 @@ class DataSeries
|
||||
* @param DataSeriesValues[] $plotCategory
|
||||
* @param DataSeriesValues[] $plotValues
|
||||
* @param null|string $plotDirection
|
||||
* @param bool $smoothLine
|
||||
* @param null|bool $smoothLine null treated as false
|
||||
* @param null|string $plotStyle
|
||||
*/
|
||||
public function __construct($plotType = null, $plotGrouping = null, array $plotOrder = [], array $plotLabel = [], array $plotCategory = [], array $plotValues = [], $plotDirection = null, $smoothLine = false, $plotStyle = null)
|
||||
@@ -144,7 +144,7 @@ class DataSeries
|
||||
}
|
||||
$this->plotCategory = $plotCategory;
|
||||
|
||||
$this->smoothLine = $smoothLine;
|
||||
$this->smoothLine = (bool) $smoothLine;
|
||||
$this->plotStyle = $plotStyle;
|
||||
|
||||
if ($plotDirection === null) {
|
||||
|
||||
@@ -98,7 +98,7 @@ class DataSeriesValues extends Properties
|
||||
* @param mixed $dataValues
|
||||
* @param null|mixed $marker
|
||||
* @param null|ChartColor|ChartColor[]|string|string[] $fillColor
|
||||
* @param string $pointSize
|
||||
* @param int|string $pointSize point size
|
||||
*/
|
||||
public function __construct($dataType = self::DATASERIES_TYPE_NUMBER, $dataSource = null, $formatCode = null, $pointCount = 0, $dataValues = [], $marker = null, $fillColor = null, $pointSize = '3')
|
||||
{
|
||||
|
||||
@@ -795,9 +795,9 @@ abstract class Properties
|
||||
* @param string $capType
|
||||
* @param string $joinType
|
||||
* @param string $headArrowType
|
||||
* @param string $headArrowSize
|
||||
* @param null|int|string $headArrowSize index into ARROW_SIZES array
|
||||
* @param string $endArrowType
|
||||
* @param string $endArrowSize
|
||||
* @param null|int|string $endArrowSize index into ARROW_SIZES array
|
||||
* @param string $headArrowWidth
|
||||
* @param string $headArrowLength
|
||||
* @param string $endArrowWidth
|
||||
@@ -824,7 +824,7 @@ abstract class Properties
|
||||
if ($headArrowType !== '') {
|
||||
$this->lineStyleProperties['arrow']['head']['type'] = $headArrowType;
|
||||
}
|
||||
if (array_key_exists($headArrowSize, self::ARROW_SIZES)) {
|
||||
if (isset(self::ARROW_SIZES[$headArrowSize])) {
|
||||
$this->lineStyleProperties['arrow']['head']['size'] = $headArrowSize;
|
||||
$this->lineStyleProperties['arrow']['head']['w'] = self::ARROW_SIZES[$headArrowSize]['w'];
|
||||
$this->lineStyleProperties['arrow']['head']['len'] = self::ARROW_SIZES[$headArrowSize]['len'];
|
||||
@@ -832,7 +832,7 @@ abstract class Properties
|
||||
if ($endArrowType !== '') {
|
||||
$this->lineStyleProperties['arrow']['end']['type'] = $endArrowType;
|
||||
}
|
||||
if (array_key_exists($endArrowSize, self::ARROW_SIZES)) {
|
||||
if (isset(self::ARROW_SIZES[$endArrowSize])) {
|
||||
$this->lineStyleProperties['arrow']['end']['size'] = $endArrowSize;
|
||||
$this->lineStyleProperties['arrow']['end']['w'] = self::ARROW_SIZES[$endArrowSize]['w'];
|
||||
$this->lineStyleProperties['arrow']['end']['len'] = self::ARROW_SIZES[$endArrowSize]['len'];
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\RichText;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Font;
|
||||
|
||||
class Run extends TextElement implements ITextElement
|
||||
@@ -35,6 +36,15 @@ class Run extends TextElement implements ITextElement
|
||||
return $this->font;
|
||||
}
|
||||
|
||||
public function getFontOrThrow(): Font
|
||||
{
|
||||
if ($this->font === null) {
|
||||
throw new SpreadsheetException('unexpected null font');
|
||||
}
|
||||
|
||||
return $this->font;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set font.
|
||||
*
|
||||
|
||||
@@ -662,6 +662,16 @@ class Worksheet implements IComparable
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getChartByNameOrThrow(string $chartName): Chart
|
||||
{
|
||||
$chart = $this->getChartByName($chartName);
|
||||
if ($chart !== false) {
|
||||
return $chart;
|
||||
}
|
||||
|
||||
throw new Exception("Sheet does not have a chart named $chartName.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh column dimensions.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Chart;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Chart\Chart;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\PlotArea;
|
||||
use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ChartsByNameTest extends TestCase
|
||||
{
|
||||
public function testChartByName(): void
|
||||
{
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$sheet->setTitle('Only Sheet');
|
||||
$sheet->fromArray(
|
||||
[
|
||||
['Some Title'],
|
||||
[],
|
||||
[null, null, 'Data'],
|
||||
[null, 'L1', 1.3],
|
||||
[null, 'L2', 1.3],
|
||||
[null, 'L3', 2.3],
|
||||
[null, 'L4', 1.6],
|
||||
[null, 'L5', 1.5],
|
||||
[null, 'L6', 1.4],
|
||||
[null, 'L7', 2.2],
|
||||
[null, 'L8', 1.8],
|
||||
[null, 'L9', 1.1],
|
||||
[null, 'L10', 1.8],
|
||||
[null, 'L11', 1.6],
|
||||
[null, 'L12', 2.7],
|
||||
[null, 'L13', 2.2],
|
||||
[null, 'L14', 1.3],
|
||||
]
|
||||
);
|
||||
|
||||
$dataSeriesLabels = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, '\'Only Sheet\'!$B$4', null, 1), // 2010
|
||||
];
|
||||
// Set the X-Axis Labels
|
||||
$xAxisTickValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, '\'Only Sheet\'!$B$4:$B$17'),
|
||||
];
|
||||
// Set the Data values for each data series we want to plot
|
||||
$dataSeriesValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, '\'Only Sheet\'!$C$4:$C$17'),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
$series = new DataSeries(
|
||||
DataSeries::TYPE_BARCHART, // plotType
|
||||
DataSeries::GROUPING_STANDARD, // plotGrouping
|
||||
range(0, count($dataSeriesValues) - 1), // plotOrder
|
||||
$dataSeriesLabels, // plotLabel
|
||||
$xAxisTickValues, // plotCategory
|
||||
$dataSeriesValues, // plotValues
|
||||
);
|
||||
|
||||
// Set the series in the plot area
|
||||
$plotArea = new PlotArea(null, [$series]);
|
||||
|
||||
// Create the chart
|
||||
$chart = new Chart(
|
||||
name: 'namedchart1',
|
||||
plotArea: $plotArea,
|
||||
);
|
||||
|
||||
// Set the position where the chart should appear in the worksheet
|
||||
$chart->setTopLeftPosition('G7');
|
||||
$chart->setBottomRightPosition('N21');
|
||||
// Add the chart to the worksheet
|
||||
$sheet->addChart($chart);
|
||||
$sheet->setSelectedCells('D1');
|
||||
self::assertSame($chart, $sheet->getChartByName('namedchart1'));
|
||||
self::assertSame($chart, $sheet->getChartByNameOrThrow('namedchart1'));
|
||||
self::assertFalse($sheet->getChartByName('namedchart2'));
|
||||
|
||||
try {
|
||||
$sheet->getChartByNameOrThrow('namedchart2');
|
||||
$exceptionRaised = false;
|
||||
} catch (SpreadsheetException $e) {
|
||||
self::assertSame('Sheet does not have a chart named namedchart2.', $e->getMessage());
|
||||
$exceptionRaised = true;
|
||||
}
|
||||
|
||||
self::assertTrue($exceptionRaised);
|
||||
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Chart;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Chart\Chart;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\DataSeries;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\Exception as ChartException;
|
||||
use PhpOffice\PhpSpreadsheet\Chart\PlotArea;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PlotAreaTest extends TestCase
|
||||
{
|
||||
public function testPlotArea(): void
|
||||
{
|
||||
$dataSeriesValues = [
|
||||
new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, null, null, 4, [1, 2, 3, 4]),
|
||||
];
|
||||
|
||||
// Build the dataseries
|
||||
$series = new DataSeries(
|
||||
plotType: DataSeries::TYPE_AREACHART,
|
||||
plotGrouping: DataSeries::GROUPING_PERCENT_STACKED,
|
||||
plotOrder: range(0, count($dataSeriesValues) - 1),
|
||||
plotValues: $dataSeriesValues
|
||||
);
|
||||
|
||||
// Set the series in the plot area
|
||||
$plotArea = new PlotArea(null, [$series]);
|
||||
|
||||
// Create the chart
|
||||
$chart = new Chart(
|
||||
'chart1', // name
|
||||
plotArea: $plotArea,
|
||||
);
|
||||
self::assertNotNull($chart->getPlotAreaOrThrow());
|
||||
}
|
||||
|
||||
public function testNoPlotArea(): void
|
||||
{
|
||||
$chart = new Chart('chart1');
|
||||
$this->expectException(ChartException::class);
|
||||
$this->expectExceptionMessage('Chart has no PlotArea');
|
||||
$chart->getPlotAreaOrThrow();
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException;
|
||||
use PhpOffice\PhpSpreadsheet\RichText\RichText;
|
||||
use PhpOffice\PhpSpreadsheet\RichText\TextElement;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
@@ -48,4 +49,20 @@ class RichTextTest extends TestCase
|
||||
self::assertSame([['ABC', '-3.5']], $sheet->toArray());
|
||||
$spreadsheet->disconnectWorksheets();
|
||||
}
|
||||
|
||||
public function testNullFont(): void
|
||||
{
|
||||
$richText = new RichText();
|
||||
$textRun = $richText->createTextRun('hello');
|
||||
self::assertNotNull($textRun->getFontOrThrow());
|
||||
$textRun->setFont(null);
|
||||
|
||||
try {
|
||||
$textRun->getFontOrThrow();
|
||||
$foundFont = true;
|
||||
} catch (SpreadsheetException $e) {
|
||||
$foundFont = false;
|
||||
}
|
||||
self::assertFalse($foundFont, 'expected exception not received');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user