Simplify IOFactory to rely on autoloading

This commit is contained in:
Adrien Crivelli 2017-10-22 01:54:14 +09:00
parent 3e6a419b6d
commit 25ff914aa6
No known key found for this signature in database
GPG Key ID: B182FD79DC6DE92E
18 changed files with 328 additions and 262 deletions

View File

@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### BREAKING CHANGE ### BREAKING CHANGE
- Standardization of array keys used for style, see the [migration guide](./docs/topics/migration-from-PHPExcel.md). - Standardization of array keys used for style, see the [migration guide](./docs/topics/migration-from-PHPExcel.md).
- Easier usage of PDF writers, and other custom readers and writers, see the [migration guide](./docs/topics/migration-from-PHPExcel.md).
## [1.0.0-beta] - 2017-08-17 ## [1.0.0-beta] - 2017-08-17

View File

@ -19,7 +19,7 @@ spreadsheet file formats, like Excel and LibreOffice Calc.
|HTML | ✓ | ✓ | |HTML | ✓ | ✓ |
|SYLK | ✓ | | |SYLK | ✓ | |
|CSV | ✓ | ✓ | |CSV | ✓ | ✓ |
|PDF (using either the tcPDF, DomPDF or mPDF libraries, which need to be installed separately)| | ✓ | |PDF (using either the TCPDF, Dompdf or mPDF libraries, which need to be installed separately)| | ✓ |
# Getting started # Getting started

View File

@ -43,6 +43,28 @@ Before | After
`'PDF'` | `'Pdf'` `'PDF'` | `'Pdf'`
`'SYLK'` | `'Slk'` `'SYLK'` | `'Slk'`
### Simplified IOFactory
The following methods :
- `PHPExcel_IOFactory::getSearchLocations()`
- `PHPExcel_IOFactory::setSearchLocations()`
- `PHPExcel_IOFactory::addSearchLocation()`
were replaced by `IOFactory::registerReader()` and `IOFactory::registerWriter()`. That means
IOFactory now relies on classes autoloading.
Before:
```php
\PHPExcel_IOFactory::addSearchLocation($type, $location, $classname);
```
After:
```php
\PhpOffice\PhpSpreadsheet\IOFactory::registerReader($type, $classname);
```
### Removed deprecated things ### Removed deprecated things
@ -148,15 +170,33 @@ autoloading mechanism.
### Writing PDF ### Writing PDF
`PHPExcel_Settings::getPdfRenderer()` and `PHPExcel_Settings::setPdfRenderer()` PDF libraries must be installed via composer. And the following methods were removed
were removed. `PHPExcel_Settings::getPdfRendererName()` and and are replaced by `IOFactory::registerWriter()` instead:
`PHPExcel_Settings::setPdfRendererName()` were renamed as `setDefaultPdfWriter()`
and `setDefaultPdfWriter()` respectively. And PDF libraries must be installed via - `PHPExcel_Settings::getPdfRenderer()`
composer. So the only thing to do is to specify a default writer class like so: - `PHPExcel_Settings::setPdfRenderer()`
- `PHPExcel_Settings::getPdfRendererName()`
- `PHPExcel_Settings::setPdfRendererName()` were renamed as `setDefaultPdfWriter()`
Before:
```php ```php
$rendererName = \PhpOffice\PhpSpreadsheet\Writer\Pdf\MPDF::class; \PHPExcel_Settings::setPdfRendererName(PHPExcel_Settings::PDF_RENDERER_MPDF);
\PhpOffice\PhpSpreadsheet\Settings::setDefaultPdfWriter($rendererName); \PHPExcel_Settings::setPdfRenderer($somePath);
$writer = \PHPExcel_IOFactory::createWriter($spreadsheet, 'PDF');
```
After:
```php
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Mpdf');
// Or alternatively
\PhpOffice\PhpSpreadsheet\IOFactory::registerWriter('Pdf', \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class);
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Pdf');
// Or alternatively
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
``` ```
### PclZip and ZipArchive ### PclZip and ZipArchive

View File

@ -739,7 +739,7 @@ regarding to styling cells, number formatting, ...
### \PhpOffice\PhpSpreadsheet\Writer\Pdf ### \PhpOffice\PhpSpreadsheet\Writer\Pdf
PhpSpreadsheets PDF Writer is a wrapper for a 3rd-Party PDF Rendering PhpSpreadsheets PDF Writer is a wrapper for a 3rd-Party PDF Rendering
library such as tcPDF, mPDF or DomPDF. You must now install a PDF library such as TCPDF, mPDF or Dompdf. You must now install a PDF
rendering library yourself; but PhpSpreadsheet will work with a number rendering library yourself; but PhpSpreadsheet will work with a number
of different libraries. of different libraries.
@ -747,9 +747,9 @@ Currently, the following libraries are supported:
Library | Downloadable from | PhpSpreadsheet writer Library | Downloadable from | PhpSpreadsheet writer
--------|-------------------------------------|---------------------- --------|-------------------------------------|----------------------
tcPDF | https://github.com/tecnickcom/tcpdf | TcPdf TCPDF | https://github.com/tecnickcom/tcpdf | Tcpdf
mPDF | https://github.com/mpdf/mpdf | MPDF mPDF | https://github.com/mpdf/mpdf | Mpdf
domPDF | https://github.com/dompdf/dompdf | DomPDF Dompdf | https://github.com/dompdf/dompdf | Dompdf
The different libraries have different strengths and weaknesses. Some The different libraries have different strengths and weaknesses. Some
generate better formatted output than others, some are faster or use generate better formatted output than others, some are faster or use
@ -757,19 +757,26 @@ less memory than others, while some generate smaller .pdf files. It is
the developers choice which one they wish to use, appropriate to their the developers choice which one they wish to use, appropriate to their
own circumstances. own circumstances.
Before instantiating a Writer via `IOFactory` to generate PDF output, You can instantiate a writer with its specific name, like so:
you will need to indicate which writer you are using:
``` php ``` php
$rendererName = \PhpOffice\PhpSpreadsheet\Writer\Pdf\MPDF::class; $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Mpdf');
\PhpOffice\PhpSpreadsheet\Settings::setDefaultPdfWriter($rendererName); ```
$writer = \PhpOffice\PhpSpreadsheet\IOFactory\IOFactory::createWriter($spreadsheet, 'Pdf');
Or you can register which writer you are using with a more generic name,
so you don't need to remember which library you chose, only that you want
to write PDF files:
``` php
$class = \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class;
\PhpOffice\PhpSpreadsheet\IOFactory::registerWriter('Pdf', $class);
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Pdf');
``` ```
Or you can instantiate directly the writer of your choice like so: Or you can instantiate directly the writer of your choice like so:
``` php ``` php
$writer = \PhpOffice\PhpSpreadsheet\Writer\Pdf\MPDF($spreadsheet); $writer = \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
``` ```
#### Writing a spreadsheet #### Writing a spreadsheet
@ -778,7 +785,7 @@ Once you have identified the Renderer that you wish to use for PDF
generation, you can write a .pdf file using the following code: generation, you can write a .pdf file using the following code:
``` php ``` php
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\MPDF($spreadsheet); $writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
$writer->save("05featuredemo.pdf"); $writer->save("05featuredemo.pdf");
``` ```
@ -810,7 +817,7 @@ This can be slow on large spreadsheets, and maybe even unwanted. You can
however disable formula pre-calculation: however disable formula pre-calculation:
``` php ``` php
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\MPDF($spreadsheet); $writer = new \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf($spreadsheet);
$writer->setPreCalculateFormulas(false); $writer->setPreCalculateFormulas(false);
$writer->save("05featuredemo.pdf"); $writer->save("05featuredemo.pdf");

View File

@ -2,7 +2,6 @@
use PhpOffice\PhpSpreadsheet\Helper\Sample; use PhpOffice\PhpSpreadsheet\Helper\Sample;
use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Settings;
use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Spreadsheet;
require_once __DIR__ . '/../../src/Bootstrap.php'; require_once __DIR__ . '/../../src/Bootstrap.php';
@ -14,10 +13,6 @@ if ($helper->isCli()) {
return; return;
} }
// Change these values to select the Rendering library that you wish to use
// and its directory location on your server
$rendererName = \PhpOffice\PhpSpreadsheet\Writer\Pdf\MPDF::class;
// Create new Spreadsheet object // Create new Spreadsheet object
$spreadsheet = new Spreadsheet(); $spreadsheet = new Spreadsheet();
@ -49,7 +44,7 @@ $spreadsheet->getActiveSheet()->setShowGridLines(false);
// Set active sheet index to the first sheet, so Excel opens this as the first sheet // Set active sheet index to the first sheet, so Excel opens this as the first sheet
$spreadsheet->setActiveSheetIndex(0); $spreadsheet->setActiveSheetIndex(0);
Settings::setDefaultPdfWriter($rendererName); IOFactory::registerWriter('Pdf', \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class);
// Redirect output to a clients web browser (PDF) // Redirect output to a clients web browser (PDF)
header('Content-Type: application/pdf'); header('Content-Type: application/pdf');

View File

@ -1,14 +1,9 @@
<?php <?php
use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Settings;
require __DIR__ . '/../Header.php'; require __DIR__ . '/../Header.php';
// Change these values to select the PDF Rendering library that you wish to use
// and its directory location on your server
$rendererName = \PhpOffice\PhpSpreadsheet\Writer\Pdf\DomPDF::class;
// Read from Xlsx (.xlsx) template // Read from Xlsx (.xlsx) template
$helper->log('Load Xlsx template file'); $helper->log('Load Xlsx template file');
$reader = IOFactory::createReader('Xlsx'); $reader = IOFactory::createReader('Xlsx');
@ -19,7 +14,7 @@ $helper->write($spreadsheet, __FILE__, ['Xlsx', 'Xls', 'Html']);
// Export to PDF (.pdf) // Export to PDF (.pdf)
$helper->log('Write to PDF format'); $helper->log('Write to PDF format');
Settings::setDefaultPdfWriter($rendererName); IOFactory::registerWriter('Pdf', \PhpOffice\PhpSpreadsheet\Writer\Pdf\Dompdf::class);
$helper->write($spreadsheet, __FILE__, ['Pdf']); $helper->write($spreadsheet, __FILE__, ['Pdf']);
// Remove first two rows with field headers before exporting to CSV // Remove first two rows with field headers before exporting to CSV

View File

@ -5,11 +5,7 @@ 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 IOFactory::registerWriter('Pdf', \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class);
// for PDF files, and its directory location on your server
$rendererName = \PhpOffice\PhpSpreadsheet\Writer\Pdf\MPDF::class;
Settings::setDefaultPdfWriter($rendererName);
// 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
// for Chart images, and its directory location on your server // for Chart images, and its directory location on your server

View File

@ -1,6 +1,6 @@
<?php <?php
use PhpOffice\PhpSpreadsheet\Settings; use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup; use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
require __DIR__ . '/../Header.php'; require __DIR__ . '/../Header.php';
@ -12,9 +12,9 @@ $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);
$rendererName = \PhpOffice\PhpSpreadsheet\Writer\Pdf\DomPDF::class; $className = \PhpOffice\PhpSpreadsheet\Writer\Pdf\Dompdf::class;
$helper->log("Write to PDF format using {$rendererName}"); $helper->log("Write to PDF format using {$className}");
Settings::setDefaultPdfWriter($rendererName); IOFactory::registerWriter('Pdf', $className);
// Save // Save
$helper->write($spreadsheet, __FILE__, ['Pdf']); $helper->write($spreadsheet, __FILE__, ['Pdf']);

View File

@ -1,6 +1,6 @@
<?php <?php
use PhpOffice\PhpSpreadsheet\Settings; use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup; use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
require __DIR__ . '/../Header.php'; require __DIR__ . '/../Header.php';
@ -12,9 +12,9 @@ $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);
$rendererName = \PhpOffice\PhpSpreadsheet\Writer\Pdf\TcPDF::class; $className = \PhpOffice\PhpSpreadsheet\Writer\Pdf\Tcpdf::class;
$helper->log("Write to PDF format using {$rendererName}"); $helper->log("Write to PDF format using {$className}");
Settings::setDefaultPdfWriter($rendererName); IOFactory::registerWriter('Pdf', $className);
// Save // Save
$helper->write($spreadsheet, __FILE__, ['Pdf']); $helper->write($spreadsheet, __FILE__, ['Pdf']);

View File

@ -1,6 +1,6 @@
<?php <?php
use PhpOffice\PhpSpreadsheet\Settings; use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup; use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
require __DIR__ . '/../Header.php'; require __DIR__ . '/../Header.php';
@ -12,9 +12,9 @@ $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);
$rendererName = \PhpOffice\PhpSpreadsheet\Writer\Pdf\MPDF::class; $className = \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class;
$helper->log("Write to PDF format using {$rendererName}"); $helper->log("Write to PDF format using {$className}");
Settings::setDefaultPdfWriter($rendererName); IOFactory::registerWriter('Pdf', $className);
// Save // Save
$helper->write($spreadsheet, __FILE__, ['Pdf']); $helper->write($spreadsheet, __FILE__, ['Pdf']);

View File

@ -60,9 +60,9 @@ class Migrator
'PHPExcel_Writer_OpenDocument_Thumbnails' => \PhpOffice\PhpSpreadsheet\Writer\Ods\Thumbnails::class, 'PHPExcel_Writer_OpenDocument_Thumbnails' => \PhpOffice\PhpSpreadsheet\Writer\Ods\Thumbnails::class,
'PHPExcel_Writer_OpenDocument_WriterPart' => \PhpOffice\PhpSpreadsheet\Writer\Ods\WriterPart::class, 'PHPExcel_Writer_OpenDocument_WriterPart' => \PhpOffice\PhpSpreadsheet\Writer\Ods\WriterPart::class,
'PHPExcel_Writer_PDF_Core' => \PhpOffice\PhpSpreadsheet\Writer\Pdf::class, 'PHPExcel_Writer_PDF_Core' => \PhpOffice\PhpSpreadsheet\Writer\Pdf::class,
'PHPExcel_Writer_PDF_DomPDF' => \PhpOffice\PhpSpreadsheet\Writer\Pdf\DomPDF::class, 'PHPExcel_Writer_PDF_DomPDF' => \PhpOffice\PhpSpreadsheet\Writer\Pdf\Dompdf::class,
'PHPExcel_Writer_PDF_mPDF' => \PhpOffice\PhpSpreadsheet\Writer\Pdf\MPDF::class, 'PHPExcel_Writer_PDF_mPDF' => \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class,
'PHPExcel_Writer_PDF_tcPDF' => \PhpOffice\PhpSpreadsheet\Writer\Pdf\TcPDF::class, 'PHPExcel_Writer_PDF_tcPDF' => \PhpOffice\PhpSpreadsheet\Writer\Pdf\Tcpdf::class,
'PHPExcel_Writer_Excel5_BIFFwriter' => \PhpOffice\PhpSpreadsheet\Writer\Xls\BIFFwriter::class, 'PHPExcel_Writer_Excel5_BIFFwriter' => \PhpOffice\PhpSpreadsheet\Writer\Xls\BIFFwriter::class,
'PHPExcel_Writer_Excel5_Escher' => \PhpOffice\PhpSpreadsheet\Writer\Xls\Escher::class, 'PHPExcel_Writer_Excel5_Escher' => \PhpOffice\PhpSpreadsheet\Writer\Xls\Escher::class,
'PHPExcel_Writer_Excel5_Font' => \PhpOffice\PhpSpreadsheet\Writer\Xls\Font::class, 'PHPExcel_Writer_Excel5_Font' => \PhpOffice\PhpSpreadsheet\Writer\Xls\Font::class,

View File

@ -4,75 +4,36 @@ namespace PhpOffice\PhpSpreadsheet;
use PhpOffice\PhpSpreadsheet\Shared\File; use PhpOffice\PhpSpreadsheet\Shared\File;
class IOFactory /**
* Factory to create readers and writers easily.
*
* It is not required to use this class, but it should make it easier to read and write files.
* Especially for reading files with an unknown format.
*/
abstract class IOFactory
{ {
/** private static $readers = [
* Search locations. 'Xlsx' => Reader\Xlsx::class,
* 'Xls' => Reader\Xls::class,
* @var array 'Xml' => Reader\Xml::class,
*/ 'Ods' => Reader\Ods::class,
private static $searchLocations = [ 'Slk' => Reader\Slk::class,
['type' => 'IWriter', 'path' => 'PhpSpreadsheet/Writer/{0}.php', 'class' => '\\PhpOffice\\PhpSpreadsheet\\Writer\\{0}'], 'Gnumeric' => Reader\Gnumeric::class,
['type' => 'IReader', 'path' => 'PhpSpreadsheet/Reader/{0}.php', 'class' => '\\PhpOffice\\PhpSpreadsheet\\Reader\\{0}'], 'Html' => Reader\Html::class,
'Csv' => Reader\Csv::class,
]; ];
/** private static $writers = [
* Autoresolve classes. 'Xls' => Writer\Xls::class,
* 'Xlsx' => Writer\Xlsx::class,
* @var array 'Ods' => Writer\Ods::class,
*/ 'Csv' => Writer\Csv::class,
private static $autoResolveClasses = [ 'Html' => Writer\Html::class,
'Xlsx', 'Tcpdf' => Writer\Pdf\Tcpdf::class,
'Xls', 'Dompdf' => Writer\Pdf\Dompdf::class,
'Xml', 'Mpdf' => Writer\Pdf\Mpdf::class,
'Ods',
'Slk',
'Gnumeric',
'Html',
'Csv',
]; ];
/**
* Private constructor for IOFactory.
*/
private function __construct()
{
}
/**
* Get search locations.
*
* @return array
*/
public static function getSearchLocations()
{
return self::$searchLocations;
}
/**
* Set search locations.
*
* @param array $value
*
* @throws Reader\Exception
*/
public static function setSearchLocations(array $value)
{
self::$searchLocations = $value;
}
/**
* Add search location.
*
* @param string $type Example: IWriter
* @param string $location Example: PhpSpreadsheet/Writer/{0}.php
* @param string $classname Example: Writer\{0}
*/
public static function addSearchLocation($type, $location, $classname)
{
self::$searchLocations[] = ['type' => $type, 'path' => $location, 'class' => $classname];
}
/** /**
* Create Writer\IWriter. * Create Writer\IWriter.
* *
@ -85,32 +46,15 @@ class IOFactory
*/ */
public static function createWriter(Spreadsheet $spreadsheet, $writerType) public static function createWriter(Spreadsheet $spreadsheet, $writerType)
{ {
// Search type if (!isset(self::$writers[$writerType])) {
$searchType = 'IWriter'; throw new Writer\Exception("No writer found for type $writerType");
if ($writerType === 'Pdf') {
$pdfWriter = Settings::getDefaultPdfWriter();
if ($pdfWriter === null) {
throw new Exception('PDF default writer has not been defined.');
}
return new $pdfWriter($spreadsheet);
} }
// Include class // Instantiate writer
foreach (self::$searchLocations as $searchLocation) { $className = self::$writers[$writerType];
if ($searchLocation['type'] == $searchType) { $writer = new $className($spreadsheet);
$className = str_replace('{0}', $writerType, $searchLocation['class']);
$instance = new $className($spreadsheet); return $writer;
if ($instance !== null) {
return $instance;
}
}
}
// Nothing found...
throw new Writer\Exception("No $searchType found for type $writerType");
} }
/** /**
@ -124,23 +68,15 @@ class IOFactory
*/ */
public static function createReader($readerType) public static function createReader($readerType)
{ {
// Search type if (!isset(self::$readers[$readerType])) {
$searchType = 'IReader'; throw new Reader\Exception("No reader found for type $readerType");
// Include class
foreach (self::$searchLocations as $searchLocation) {
if ($searchLocation['type'] == $searchType) {
$className = str_replace('{0}', $readerType, $searchLocation['class']);
$instance = new $className();
if ($instance !== null) {
return $instance;
}
}
} }
// Nothing found... // Instantiate reader
throw new Reader\Exception("No $searchType found for type $readerType"); $className = self::$readers[$readerType];
$reader = new $className();
return $reader;
} }
/** /**
@ -181,81 +117,34 @@ class IOFactory
/** /**
* Create Reader\IReader for file using automatic Reader\IReader resolution. * Create Reader\IReader for file using automatic Reader\IReader resolution.
* *
* @param string $pFilename The name of the spreadsheet file * @param string $filename The name of the spreadsheet file
* *
* @throws Reader\Exception * @throws Reader\Exception
* *
* @return Reader\IReader * @return Reader\IReader
*/ */
public static function createReaderForFile($pFilename) public static function createReaderForFile($filename)
{ {
File::assertFile($pFilename); File::assertFile($filename);
// First, lucky guess by inspecting file extension // First, lucky guess by inspecting file extension
$pathinfo = pathinfo($pFilename); $guessedReader = self::getReaderTypeFromExtension($filename);
if ($guessedReader !== null) {
$reader = self::createReader($guessedReader);
$extensionType = null; // Let's see if we are lucky
if (isset($pathinfo['extension'])) { if (isset($reader) && $reader->canRead($filename)) {
switch (strtolower($pathinfo['extension'])) { return $reader;
case 'xlsx': // Excel (OfficeOpenXML) Spreadsheet
case 'xlsm': // Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded)
case 'xltx': // Excel (OfficeOpenXML) Template
case 'xltm': // Excel (OfficeOpenXML) Macro Template (macros will be discarded)
$extensionType = 'Xlsx';
break;
case 'xls': // Excel (BIFF) Spreadsheet
case 'xlt': // Excel (BIFF) Template
$extensionType = 'Xls';
break;
case 'ods': // Open/Libre Offic Calc
case 'ots': // Open/Libre Offic Calc Template
$extensionType = 'Ods';
break;
case 'slk':
$extensionType = 'Slk';
break;
case 'xml': // Excel 2003 SpreadSheetML
$extensionType = 'Xml';
break;
case 'gnumeric':
$extensionType = 'Gnumeric';
break;
case 'htm':
case 'html':
$extensionType = 'Html';
break;
case 'csv':
// Do nothing
// We must not try to use CSV reader since it loads
// all files including Excel files etc.
break;
default:
break;
}
if ($extensionType !== null) {
$reader = self::createReader($extensionType);
// Let's see if we are lucky
if (isset($reader) && $reader->canRead($pFilename)) {
return $reader;
}
} }
} }
// If we reach here then "lucky guess" didn't give any result // If we reach here then "lucky guess" didn't give any result
// Try walking through all the options in self::$autoResolveClasses // Try walking through all the options in self::$autoResolveClasses
foreach (self::$autoResolveClasses as $autoResolveClass) { foreach (self::$readers as $type => $class) {
// Ignore our original guess, we know that won't work // Ignore our original guess, we know that won't work
if ($autoResolveClass !== $extensionType) { if ($type !== $guessedReader) {
$reader = self::createReader($autoResolveClass); $reader = self::createReader($type);
if ($reader->canRead($pFilename)) { if ($reader->canRead($filename)) {
return $reader; return $reader;
} }
} }
@ -263,4 +152,79 @@ class IOFactory
throw new Reader\Exception('Unable to identify a reader for this file'); throw new Reader\Exception('Unable to identify a reader for this file');
} }
/**
* Guess a reader type from the file extension, if any.
*
* @param string $filename
*
* @return null|string
*/
private static function getReaderTypeFromExtension($filename)
{
$pathinfo = pathinfo($filename);
if (!isset($pathinfo['extension'])) {
return null;
}
switch (strtolower($pathinfo['extension'])) {
case 'xlsx': // Excel (OfficeOpenXML) Spreadsheet
case 'xlsm': // Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded)
case 'xltx': // Excel (OfficeOpenXML) Template
case 'xltm': // Excel (OfficeOpenXML) Macro Template (macros will be discarded)
return 'Xlsx';
case 'xls': // Excel (BIFF) Spreadsheet
case 'xlt': // Excel (BIFF) Template
return 'Xls';
case 'ods': // Open/Libre Offic Calc
case 'ots': // Open/Libre Offic Calc Template
return 'Ods';
case 'slk':
return 'Slk';
case 'xml': // Excel 2003 SpreadSheetML
return 'Xml';
case 'gnumeric':
return 'Gnumeric';
case 'htm':
case 'html':
return 'Html';
case 'csv':
// Do nothing
// We must not try to use CSV reader since it loads
// all files including Excel files etc.
return null;
default:
return null;
}
}
/**
* Register a writer with its type and class name.
*
* @param string $writerType
* @param string $writerClass
*/
public static function registerWriter($writerType, $writerClass)
{
if (!is_a($writerClass, Writer\IWriter::class, true)) {
throw new Writer\Exception('Registered writers must implement ' . Writer\IWriter::class);
}
self::$writers[$writerType] = $writerClass;
}
/**
* Register a reader with its type and class name.
*
* @param string $readerType
* @param string $readerClass
*/
public static function registerReader($readerType, $readerClass)
{
if (!is_a($readerClass, Reader\IReader::class, true)) {
throw new Reader\Exception('Registered readers must implement ' . Reader\IReader::class);
}
self::$readers[$readerType] = $readerClass;
}
} }

View File

@ -3,7 +3,6 @@
namespace PhpOffice\PhpSpreadsheet; namespace PhpOffice\PhpSpreadsheet;
use PhpOffice\PhpSpreadsheet\Collection\Memory; use PhpOffice\PhpSpreadsheet\Collection\Memory;
use PhpOffice\PhpSpreadsheet\Writer\Pdf;
use Psr\SimpleCache\CacheInterface; use Psr\SimpleCache\CacheInterface;
class Settings class Settings
@ -31,15 +30,6 @@ class Settings
*/ */
private static $chartRendererPath; private static $chartRendererPath;
/**
* Name of the external Library used for rendering PDF files
* e.g.
* mPDF.
*
* @var string
*/
private static $defaultPdfWriter;
/** /**
* Default options for libxml loader. * Default options for libxml loader.
* *
@ -142,30 +132,6 @@ class Settings
return self::$chartRendererPath; return self::$chartRendererPath;
} }
/**
* Identify to PhpSpreadsheet the default writer to use for PDF.
*
* @param string $writerClassName Internal reference name of the library
*/
public static function setDefaultPdfWriter($writerClassName)
{
if (!is_a($writerClassName, Pdf::class, true)) {
throw new Exception('"' . $writerClassName . '" is not a valid PDF writer class name');
}
self::$defaultPdfWriter = $writerClassName;
}
/**
* Return the default PDF writer that PhpSpreadsheet is currently configured to use (e.g. dompdf).
*
* @return null|string Internal reference name of the PDF Rendering Library that PhpSpreadsheet is
* currently configured to use
*/
public static function getDefaultPdfWriter()
{
return self::$defaultPdfWriter;
}
/** /**
* Set default options for libxml loader. * Set default options for libxml loader.
* *

View File

@ -1177,7 +1177,7 @@ class Html extends BaseWriter implements IWriter
// Sheet index // Sheet index
$sheetIndex = $pSheet->getParent()->getIndex($pSheet); $sheetIndex = $pSheet->getParent()->getIndex($pSheet);
// DomPDF and breaks // Dompdf and breaks
if ($this->isPdf && count($pSheet->getBreaks()) > 0) { if ($this->isPdf && count($pSheet->getBreaks()) > 0) {
$breaks = $pSheet->getBreaks(); $breaks = $pSheet->getBreaks();

View File

@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
use PhpOffice\PhpSpreadsheet\Writer\IWriter; use PhpOffice\PhpSpreadsheet\Writer\IWriter;
use PhpOffice\PhpSpreadsheet\Writer\Pdf; use PhpOffice\PhpSpreadsheet\Writer\Pdf;
class DomPDF extends Pdf implements IWriter class Dompdf extends Pdf implements IWriter
{ {
/** /**
* Save Spreadsheet to file. * Save Spreadsheet to file.

View File

@ -7,7 +7,7 @@ use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
use PhpOffice\PhpSpreadsheet\Writer\IWriter; use PhpOffice\PhpSpreadsheet\Writer\IWriter;
use PhpOffice\PhpSpreadsheet\Writer\Pdf; use PhpOffice\PhpSpreadsheet\Writer\Pdf;
class MPDF extends Pdf implements IWriter class Mpdf extends Pdf implements IWriter
{ {
/** /**
* Save Spreadsheet to file. * Save Spreadsheet to file.

View File

@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
use PhpOffice\PhpSpreadsheet\Writer\IWriter; use PhpOffice\PhpSpreadsheet\Writer\IWriter;
use PhpOffice\PhpSpreadsheet\Writer\Pdf; use PhpOffice\PhpSpreadsheet\Writer\Pdf;
class TcPDF extends Pdf implements IWriter class Tcpdf extends Pdf implements IWriter
{ {
/** /**
* Save Spreadsheet to file. * Save Spreadsheet to file.

View File

@ -3,31 +3,117 @@
namespace PhpOffice\PhpSpreadsheetTests; namespace PhpOffice\PhpSpreadsheetTests;
use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Reader;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer;
use PHPUnit_Framework_TestCase; use PHPUnit_Framework_TestCase;
class IOFactoryTest extends PHPUnit_Framework_TestCase class IOFactoryTest extends PHPUnit_Framework_TestCase
{ {
/**
* @dataProvider providerCreateWriter
*
* @param string $name
* @param string $expected
*/
public function testCreateWriter($name, $expected)
{
$spreadsheet = new Spreadsheet();
$actual = IOFactory::createWriter($spreadsheet, $name);
self::assertInstanceOf($expected, $actual);
}
public function providerCreateWriter()
{
return [
['Xls', Writer\Xls::class],
['Xlsx', Writer\Xlsx::class],
['Ods', Writer\Ods::class],
['Csv', Writer\Csv::class],
['Html', Writer\Html::class],
['Mpdf', Writer\Pdf\Mpdf::class],
['Tcpdf', Writer\Pdf\Tcpdf::class],
['Dompdf', Writer\Pdf\Dompdf::class],
];
}
public function testRegisterWriter()
{
IOFactory::registerWriter('Pdf', Writer\Pdf\Mpdf::class);
$spreadsheet = new Spreadsheet();
$actual = IOFactory::createWriter($spreadsheet, 'Pdf');
self::assertInstanceOf(Writer\Pdf\Mpdf::class, $actual);
}
/**
* @dataProvider providerCreateReader
*
* @param string $name
* @param string $expected
*/
public function testCreateReader($name, $expected)
{
$actual = IOFactory::createReader($name);
self::assertInstanceOf($expected, $actual);
}
public function providerCreateReader()
{
return [
['Xls', Reader\Xls::class],
['Xlsx', Reader\Xlsx::class],
['Xml', Reader\Xml::class],
['Ods', Reader\Ods::class],
['Gnumeric', Reader\Gnumeric::class],
['Csv', Reader\Csv::class],
['Slk', Reader\Slk::class],
['Html', Reader\Html::class],
];
}
public function testRegisterReader()
{
IOFactory::registerReader('Custom', Reader\Html::class);
$actual = IOFactory::createReader('Custom');
self::assertInstanceOf(Reader\Html::class, $actual);
}
/** /**
* @dataProvider providerIdentify * @dataProvider providerIdentify
* *
* @param mixed $file * @param string $file
* @param mixed $expected * @param string $expectedName
* @param string $expectedClass
*/ */
public function testIdentify($file, $expected) public function testIdentify($file, $expectedName, $expectedClass)
{ {
$actual = IOFactory::identify($file); $actual = IOFactory::identify($file);
self::assertSame($expected, $actual); self::assertSame($expectedName, $actual);
}
/**
* @dataProvider providerIdentify
*
* @param string $file
* @param string $expectedName
* @param string $expectedClass
*/
public function testCreateReaderForFile($file, $expectedName, $expectedClass)
{
$actual = IOFactory::createReaderForFile($file);
self::assertInstanceOf($expectedClass, $actual);
} }
public function providerIdentify() public function providerIdentify()
{ {
return [ return [
['../samples/templates/26template.xlsx', 'Xlsx'], ['../samples/templates/26template.xlsx', 'Xlsx', Reader\Xlsx::class],
['../samples/templates/GnumericTest.gnumeric', 'Gnumeric'], ['../samples/templates/GnumericTest.gnumeric', 'Gnumeric', Reader\Gnumeric::class],
['../samples/templates/30template.xls', 'Xls'], ['../samples/templates/30template.xls', 'Xls', Reader\Xls::class],
['../samples/templates/OOCalcTest.ods', 'Ods'], ['../samples/templates/OOCalcTest.ods', 'Ods', Reader\Ods::class],
['../samples/templates/SylkTest.slk', 'Slk'], ['../samples/templates/SylkTest.slk', 'Slk', Reader\Slk::class],
['../samples/templates/Excel2003XMLTest.xml', 'Xml'], ['../samples/templates/Excel2003XMLTest.xml', 'Xml', Reader\Xml::class],
['../samples/templates/46readHtml.html', 'Html', Reader\Html::class],
]; ];
} }
@ -46,4 +132,20 @@ class IOFactoryTest extends PHPUnit_Framework_TestCase
{ {
IOFactory::identify('.'); IOFactory::identify('.');
} }
/**
* @expectedException \PhpOffice\PhpSpreadsheet\Writer\Exception
*/
public function testRegisterInvalidWriter()
{
IOFactory::registerWriter('foo', 'bar');
}
/**
* @expectedException \PhpOffice\PhpSpreadsheet\Reader\Exception
*/
public function testRegisterInvalidReader()
{
IOFactory::registerReader('foo', 'bar');
}
} }