Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reader writer flags #2136

Merged
merged 13 commits into from
Jun 4, 2021
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org).

### Added

- Support for passing flags in the Reader `load()` and Writer `save()`methods, and through the IOFactory, to set behaviours. [PR #2136](https://github.com/PHPOffice/PhpSpreadsheet/pull/2136)
- See [documentation](https://phpspreadsheet.readthedocs.io/en/latest/topics/reading-and-writing-to-file/) for details
- More flexibility in the StringValueBinder to determine what datatypes should be treated as strings [PR #2138](https://github.com/PHPOffice/PhpSpreadsheet/pull/2138)

### Changed
Expand Down
70 changes: 64 additions & 6 deletions docs/topics/reading-and-writing-to-file.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# Reading and writing to file

As you already know from the [architecture](./architecture.md#readers-and-writers),
reading and writing to a
persisted storage is not possible using the base PhpSpreadsheet classes.
reading and writing to a persisted storage is not possible using the base PhpSpreadsheet classes.
For this purpose, PhpSpreadsheet provides readers and writers, which are
implementations of `\PhpOffice\PhpSpreadsheet\Reader\IReader` and
`\PhpOffice\PhpSpreadsheet\Writer\IWriter`.
Expand Down Expand Up @@ -892,8 +891,7 @@ class My_Custom_TCPDF_Writer extends \PhpOffice\PhpSpreadsheet\Writer\Pdf\Tcpdf

#### Writing a spreadsheet

Once you have identified the Renderer that you wish to use for PDF
generation, you can write a .pdf file using the following code:
Once you have identified the Renderer that you wish to use for PDF generation, you can write a .pdf file using the following code:

```php
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
Expand All @@ -905,8 +903,7 @@ first worksheet by default.

#### Write all worksheets

PDF files can contain one or more worksheets. If you want to write all
sheets into a single PDF file, use the following code:
PDF files can contain one or more worksheets. If you want to write all sheets into a single PDF file, use the following code:

```php
$writer->writeAllSheets();
Expand Down Expand Up @@ -1020,3 +1017,64 @@ $spreadhseet = $reader->loadFromString($secondHtmlString, $spreadsheet);
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xls');
$writer->save('write.xls');
```

## Reader/Writer Flags

Some Readers and Writers support special "Feature Flags" that need to be explicitly enabled.
An example of this is Charts in a spreadsheet. By default, when you load a spreadsheet that contains Charts, the charts will not be loaded. If all you want to do is read the data in the spreadsheet, then loading charts is an overhead for both speed of loading and memory usage.
However, there are times when you may want to load any charts in the spreadsheet as well as the data. To do so, you need to tell the Reader explicitly to include Charts.

```php
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReaderForFile("05featuredemo.xlsx");
$reader->setIncludeCharts(true);
$reader->load("spreadsheetWithCharts.xlsx");
```
Alternatively, you can specify this in the call to load the spreadsheet:
```php
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReaderForFile("spreadsheetWithCharts.xlsx");
$reader->load("spreadsheetWithCharts.xlsx", $reader::LOAD_WITH_CHARTS);
```

If you wish to use the IOFactory `load()` method rather than instantiating a specific Reader, then you can still pass these flags.

```php
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load("spreadsheetWithCharts.xlsx", \PhpOffice\PhpSpreadsheet\Reader\IReader::LOAD_WITH_CHARTS);
```

Likewise, when saving a file using a Writer, loaded charts wil not be saved unless you explicitly tell the Writer to include them:

```php
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->setIncludeCharts(true);
$writer->save('mySavedFileWithCharts.xlsx');
```

As with the `load()` method, you can also pass flags in the `save()` method:
```php
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save('mySavedFileWithCharts.xlsx', \PhpOffice\PhpSpreadsheet\Writer\IWriter::SAVE_WITH_CHARTS);
```

Currently, the only special "Feature Flag" that is supported in this way is the inclusion of Charts, and only for certain formats.

Readers | LOAD_WITH_CHARTS |
---------|------------------|
Xlsx | YES |
Xls | NO |
Xml | NO |
Ods | NO |
Gnumeric | NO |
Html | N/A |
Slk | N/A |
Csv | N/A |


Writers | SAVE_WITH_CHARTS |
--------|------------------|
Xlsx | YES |
Xls | NO |
Ods | NO |
Html | YES |
Pdf | YES |
Csv | N/A |

5 changes: 0 additions & 5 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -6245,11 +6245,6 @@ parameters:
count: 1
path: src/PhpSpreadsheet/Writer/Html.php

-
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\IWriter\\:\\:save\\(\\) has no return typehint specified\\.$#"
count: 1
path: src/PhpSpreadsheet/Writer/IWriter.php

-
message: "#^Negated boolean expression is always false\\.$#"
count: 1
Expand Down
8 changes: 4 additions & 4 deletions src/PhpSpreadsheet/IOFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ public static function createReader($readerType)
/**
* Loads Spreadsheet from file using automatic Reader\IReader resolution.
*
* @param string $pFilename The name of the spreadsheet file
* @param string $filename The name of the spreadsheet file
*
* @return Spreadsheet
*/
public static function load($pFilename)
public static function load(string $filename, int $flags = 0)
{
$reader = self::createReaderForFile($pFilename);
$reader = self::createReaderForFile($filename);

return $reader->load($pFilename);
return $reader->load($filename, $flags);
}

/**
Expand Down
7 changes: 7 additions & 0 deletions src/PhpSpreadsheet/Reader/BaseReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@ public function getSecurityScanner()
return $this->securityScanner;
}

protected function processFlags(int $flags): void
{
if (((bool) ($flags & self::LOAD_WITH_CHARTS)) === true) {
$this->setIncludeCharts(true);
}
}

/**
* Open file for reading.
*
Expand Down
6 changes: 3 additions & 3 deletions src/PhpSpreadsheet/Reader/Csv.php
Original file line number Diff line number Diff line change
Expand Up @@ -236,12 +236,12 @@ public function listWorksheetInfo(string $pFilename): array
/**
* Loads Spreadsheet from file.
*
* @param string $pFilename
*
* @return Spreadsheet
*/
public function load($pFilename)
public function load(string $pFilename, int $flags = 0)
{
$this->processFlags($flags);

// Create new Spreadsheet
$spreadsheet = new Spreadsheet();

Expand Down
6 changes: 3 additions & 3 deletions src/PhpSpreadsheet/Reader/Gnumeric.php
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,12 @@ private static function testSimpleXml($value): SimpleXMLElement
/**
* Loads Spreadsheet from file.
*
* @param string $pFilename
*
* @return Spreadsheet
*/
public function load($pFilename)
public function load(string $pFilename, int $flags = 0)
{
$this->processFlags($flags);

// Create new Spreadsheet
$spreadsheet = new Spreadsheet();
$spreadsheet->removeSheetByIndex(0);
Expand Down
6 changes: 3 additions & 3 deletions src/PhpSpreadsheet/Reader/Html.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,12 @@ private static function containsTags($data)
/**
* Loads Spreadsheet from file.
*
* @param string $pFilename
*
* @return Spreadsheet
*/
public function load($pFilename)
public function load(string $pFilename, int $flags = 0)
{
$this->processFlags($flags);

// Create new Spreadsheet
$spreadsheet = new Spreadsheet();

Expand Down
6 changes: 3 additions & 3 deletions src/PhpSpreadsheet/Reader/IReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

interface IReader
{
public const LOAD_WITH_CHARTS = 1;

/**
* IReader constructor.
*/
Expand Down Expand Up @@ -125,9 +127,7 @@ public function setReadFilter(IReadFilter $pValue);
/**
* Loads PhpSpreadsheet from file.
*
* @param string $pFilename
*
* @return \PhpOffice\PhpSpreadsheet\Spreadsheet
*/
public function load($pFilename);
public function load(string $pFilename, int $flags = 0);
}
6 changes: 3 additions & 3 deletions src/PhpSpreadsheet/Reader/Ods.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,12 @@ public function listWorksheetInfo($pFilename)
/**
* Loads PhpSpreadsheet from file.
*
* @param string $pFilename
*
* @return Spreadsheet
*/
public function load($pFilename)
public function load(string $pFilename, int $flags = 0)
{
$this->processFlags($flags);

// Create new Spreadsheet
$spreadsheet = new Spreadsheet();

Expand Down
6 changes: 3 additions & 3 deletions src/PhpSpreadsheet/Reader/Slk.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,12 @@ public function listWorksheetInfo($pFilename)
/**
* Loads PhpSpreadsheet from file.
*
* @param string $pFilename
*
* @return Spreadsheet
*/
public function load($pFilename)
public function load(string $pFilename, int $flags = 0)
{
$this->processFlags($flags);

// Create new Spreadsheet
$spreadsheet = new Spreadsheet();

Expand Down
6 changes: 3 additions & 3 deletions src/PhpSpreadsheet/Reader/Xls.php
Original file line number Diff line number Diff line change
Expand Up @@ -622,12 +622,12 @@ public function listWorksheetInfo($pFilename)
/**
* Loads PhpSpreadsheet from file.
*
* @param string $pFilename
*
* @return Spreadsheet
*/
public function load($pFilename)
public function load(string $pFilename, int $flags = 0)
{
$this->processFlags($flags);

// Read the OLE file
$this->loadOLE($pFilename);

Expand Down
5 changes: 2 additions & 3 deletions src/PhpSpreadsheet/Reader/Xlsx.php
Original file line number Diff line number Diff line change
Expand Up @@ -310,13 +310,12 @@ private function getFromZipArchive(ZipArchive $archive, $fileName = '')
/**
* Loads Spreadsheet from file.
*
* @param string $pFilename
*
* @return Spreadsheet
*/
public function load($pFilename)
public function load(string $pFilename, int $flags = 0)
{
File::assertFile($pFilename);
$this->processFlags($flags);

// Initialisations
$excel = new Spreadsheet();
Expand Down
8 changes: 4 additions & 4 deletions src/PhpSpreadsheet/Reader/Xml.php
Original file line number Diff line number Diff line change
Expand Up @@ -236,18 +236,18 @@ public function listWorksheetInfo($filename)
/**
* Loads Spreadsheet from file.
*
* @param string $filename
*
* @return Spreadsheet
*/
public function load($filename)
public function load(string $pFilename, int $flags = 0)
{
$this->processFlags($flags);

// Create new Spreadsheet
$spreadsheet = new Spreadsheet();
$spreadsheet->removeSheetByIndex(0);

// Load into this instance
return $this->loadIntoExisting($filename, $spreadsheet);
return $this->loadIntoExisting($pFilename, $spreadsheet);
}

/**
Expand Down
9 changes: 8 additions & 1 deletion src/PhpSpreadsheet/Writer/BaseWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ abstract class BaseWriter implements IWriter
{
/**
* Write charts that are defined in the workbook?
* Identifies whether the Writer should write definitions for any charts that exist in the PhpSpreadsheet object;.
* Identifies whether the Writer should write definitions for any charts that exist in the PhpSpreadsheet object.
*
* @var bool
*/
Expand Down Expand Up @@ -94,6 +94,13 @@ public function getDiskCachingDirectory()
return $this->diskCachingDirectory;
}

protected function processFlags(int $flags): void
{
if (((bool) ($flags & self::SAVE_WITH_CHARTS)) === true) {
$this->setIncludeCharts(true);
}
}

/**
* Open file handle.
*
Expand Down
4 changes: 3 additions & 1 deletion src/PhpSpreadsheet/Writer/Csv.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,10 @@ public function __construct(Spreadsheet $spreadsheet)
*
* @param resource|string $pFilename
*/
public function save($pFilename): void
public function save($pFilename, int $flags = 0): void
{
$this->processFlags($flags);

// Fetch sheet
$sheet = $this->spreadsheet->getSheet($this->sheetIndex);

Expand Down
4 changes: 3 additions & 1 deletion src/PhpSpreadsheet/Writer/Html.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,10 @@ public function __construct(Spreadsheet $spreadsheet)
*
* @param resource|string $pFilename
*/
public function save($pFilename): void
public function save($pFilename, int $flags = 0): void
{
$this->processFlags($flags);

// Open file
$this->openFileHandle($pFilename);

Expand Down
4 changes: 3 additions & 1 deletion src/PhpSpreadsheet/Writer/IWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

interface IWriter
{
public const SAVE_WITH_CHARTS = 1;

/**
* IWriter constructor.
*/
Expand Down Expand Up @@ -59,7 +61,7 @@ public function setPreCalculateFormulas($pValue);
*
* @param resource|string $pFilename Name of the file to save
*/
public function save($pFilename);
public function save($pFilename, int $flags = 0): void;

/**
* Get use disk caching where possible?
Expand Down
4 changes: 3 additions & 1 deletion src/PhpSpreadsheet/Writer/Ods.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,14 @@ public function getWriterPartThumbnails(): Thumbnails
*
* @param resource|string $pFilename
*/
public function save($pFilename): void
public function save($pFilename, int $flags = 0): void
{
if (!$this->spreadSheet) {
throw new WriterException('PhpSpreadsheet object unassigned.');
}

$this->processFlags($flags);

// garbage collect
$this->spreadSheet->garbageCollect();

Expand Down
2 changes: 1 addition & 1 deletion src/PhpSpreadsheet/Writer/Pdf/Dompdf.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ protected function createExternalWriterInstance()
*
* @param string $pFilename Name of the file to save as
*/
public function save($pFilename): void
public function save($pFilename, int $flags = 0): void
{
$fileHandle = parent::prepareForSave($pFilename);

Expand Down
Loading