diff --git a/docs/_pages/getting-started.md b/docs/_pages/getting-started.md index ed224d0..1ea17e7 100755 --- a/docs/_pages/getting-started.md +++ b/docs/_pages/getting-started.md @@ -68,6 +68,17 @@ $reader->close(); If there are multiple sheets in the file, the reader will read all of them sequentially. +--- + +In addition to passing a reader type to ```ReaderEntityFactory::createReader```, it is also possible to provide a path to a file and create the reader. + +```php + +use Box\Spout\Reader\Common\Creator\ReaderEntityFactory; + +$reader = ReaderEntityFactory::createReaderFromFile('/path/to/file.xlsx'); +``` + ### Writer As with the reader, there is one common interface to write data to a file: diff --git a/src/Spout/Reader/Common/Creator/ReaderEntityFactory.php b/src/Spout/Reader/Common/Creator/ReaderEntityFactory.php index 8638381..e9e8063 100644 --- a/src/Spout/Reader/Common/Creator/ReaderEntityFactory.php +++ b/src/Spout/Reader/Common/Creator/ReaderEntityFactory.php @@ -21,4 +21,17 @@ class ReaderEntityFactory { return (new ReaderFactory())->create($readerType); } + + /** + * Creates a reader by file extension + * + * @param string The path to the spreadsheet file. Supported extensions are .csv,.ods and .xlsx + * @throws \Box\Spout\Common\Exception\IOException + * @throws \Box\Spout\Common\Exception\UnsupportedTypeException + * @return ReaderInterface + */ + public static function createReaderFromFile(string $path) + { + return (new ReaderFactory())->createFromFile($path); + } } diff --git a/src/Spout/Reader/Common/Creator/ReaderFactory.php b/src/Spout/Reader/Common/Creator/ReaderFactory.php index ffc2d6c..0442974 100644 --- a/src/Spout/Reader/Common/Creator/ReaderFactory.php +++ b/src/Spout/Reader/Common/Creator/ReaderFactory.php @@ -3,6 +3,7 @@ namespace Box\Spout\Reader\Common\Creator; use Box\Spout\Common\Creator\HelperFactory; +use Box\Spout\Common\Exception\IOException; use Box\Spout\Common\Exception\UnsupportedTypeException; use Box\Spout\Common\Type; use Box\Spout\Reader\CSV\Creator\InternalEntityFactory as CSVInternalEntityFactory; @@ -28,6 +29,16 @@ use Box\Spout\Reader\XLSX\Reader as XLSXReader; */ class ReaderFactory { + /** + * Map file extensions to reader types + * @var array + */ + private static $extensionReaderMap = [ + 'csv' => Type::CSV, + 'ods' => Type::ODS, + 'xlsx' => Type::XLSX, + ]; + /** * This creates an instance of the appropriate reader, given the type of the file to be read * @@ -46,6 +57,34 @@ class ReaderFactory } } + /** + * Creates a reader by file extension + * + * @param string The path to the spreadsheet file. Supported extensions are .csv,.ods and .xlsx + * @throws \Box\Spout\Common\Exception\IOException + * @throws \Box\Spout\Common\Exception\UnsupportedTypeException + * @return ReaderInterface + */ + public static function createFromFile(string $path) + { + if (!\is_file($path)) { + throw new IOException( + sprintf('Could not open "%s" for reading! File does not exist.', $path) + ); + } + + $ext = \pathinfo($path, PATHINFO_EXTENSION); + $ext = \strtolower($ext); + $readerType = self::$extensionReaderMap[$ext] ?? null; + if ($readerType === null) { + throw new UnsupportedTypeException( + sprintf('No readers supporting the file extension "%s".', $ext) + ); + } + + return self::create($readerType); + } + /** * @return CSVReader */ diff --git a/tests/Spout/Reader/Common/Creator/ReaderEntityFactoryTest.php b/tests/Spout/Reader/Common/Creator/ReaderEntityFactoryTest.php new file mode 100644 index 0000000..9b978a3 --- /dev/null +++ b/tests/Spout/Reader/Common/Creator/ReaderEntityFactoryTest.php @@ -0,0 +1,73 @@ +getResourcePath('csv_test_create_from_file.csv'); + $reader = ReaderEntityFactory::createReaderFromFile($validCsv); + $this->assertInstanceOf('Box\Spout\Reader\CSV\Reader', $reader); + } + + /** + * @return void + */ + public function testCreateFromFileCSVAllCaps() + { + $validCsv = $this->getResourcePath('csv_test_create_from_file.CSV'); + $reader = ReaderEntityFactory::createReaderFromFile($validCsv); + $this->assertInstanceOf('Box\Spout\Reader\CSV\Reader', $reader); + } + + /** + * @return void + */ + public function testCreateFromFileODS() + { + $validOds = $this->getResourcePath('csv_test_create_from_file.ods'); + $reader = ReaderEntityFactory::createReaderFromFile($validOds); + $this->assertInstanceOf('Box\Spout\Reader\ODS\Reader', $reader); + } + + /** + * @return void + */ + public function testCreateFromFileXLSX() + { + $validXlsx = $this->getResourcePath('csv_test_create_from_file.xlsx'); + $reader = ReaderEntityFactory::createReaderFromFile($validXlsx); + $this->assertInstanceOf('Box\Spout\Reader\XLSX\Reader', $reader); + } + + /** + * @return void + */ + public function testCreateFromFileUnsupported() + { + $this->expectException(UnsupportedTypeException::class); + $invalid = $this->getResourcePath('test_unsupported_file_type.other'); + $reader = ReaderEntityFactory::createReaderFromFile($invalid); + } + + /** + * @return void + */ + public function testCreateFromFileMissing() + { + $this->expectException(IOException::class); + $invalid = 'thereisnosuchfile.ext'; + $reader = ReaderEntityFactory::createReaderFromFile($invalid); + } +} diff --git a/tests/Spout/Reader/Common/Creator/ReaderFactoryTest.php b/tests/Spout/Reader/Common/Creator/ReaderFactoryTest.php index 994bc3c..1efb292 100644 --- a/tests/Spout/Reader/Common/Creator/ReaderFactoryTest.php +++ b/tests/Spout/Reader/Common/Creator/ReaderFactoryTest.php @@ -2,7 +2,9 @@ namespace Box\Spout\Reader\Common\Creator; +use Box\Spout\Common\Exception\IOException; use Box\Spout\Common\Exception\UnsupportedTypeException; +use Box\Spout\TestUsingResource; use PHPUnit\Framework\TestCase; /** @@ -10,6 +12,48 @@ use PHPUnit\Framework\TestCase; */ class ReaderFactoryTest extends TestCase { + use TestUsingResource; + + /** + * @return void + */ + public function testCreateFromFileCSV() + { + $validCsv = $this->getResourcePath('csv_test_create_from_file.csv'); + $reader = ReaderFactory::createFromFile($validCsv); + $this->assertInstanceOf('Box\Spout\Reader\CSV\Reader', $reader); + } + + /** + * @return void + */ + public function testCreateFromFileCSVAllCaps() + { + $validCsv = $this->getResourcePath('csv_test_create_from_file.CSV'); + $reader = ReaderFactory::createFromFile($validCsv); + $this->assertInstanceOf('Box\Spout\Reader\CSV\Reader', $reader); + } + + /** + * @return void + */ + public function testCreateFromFileODS() + { + $validOds = $this->getResourcePath('csv_test_create_from_file.ods'); + $reader = ReaderFactory::createFromFile($validOds); + $this->assertInstanceOf('Box\Spout\Reader\ODS\Reader', $reader); + } + + /** + * @return void + */ + public function testCreateFromFileXLSX() + { + $validXlsx = $this->getResourcePath('csv_test_create_from_file.xlsx'); + $reader = ReaderFactory::createFromFile($validXlsx); + $this->assertInstanceOf('Box\Spout\Reader\XLSX\Reader', $reader); + } + /** * @return void */ @@ -19,4 +63,24 @@ class ReaderFactoryTest extends TestCase ReaderFactory::create('unsupportedType'); } + + /** + * @return void + */ + public function testCreateFromFileUnsupported() + { + $this->expectException(UnsupportedTypeException::class); + $invalid = $this->getResourcePath('test_unsupported_file_type.other'); + $reader = ReaderFactory::createFromFile($invalid); + } + + /** + * @return void + */ + public function testCreateFromFileMissing() + { + $this->expectException(IOException::class); + $invalid = 'thereisnosuchfile.ext'; + $reader = ReaderFactory::createFromFile($invalid); + } } diff --git a/tests/resources/csv/csv_test_create_from_file.CSV b/tests/resources/csv/csv_test_create_from_file.CSV new file mode 100644 index 0000000..30d74d2 --- /dev/null +++ b/tests/resources/csv/csv_test_create_from_file.CSV @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/tests/resources/csv/csv_test_create_from_file.csv b/tests/resources/csv/csv_test_create_from_file.csv new file mode 100644 index 0000000..30d74d2 --- /dev/null +++ b/tests/resources/csv/csv_test_create_from_file.csv @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/tests/resources/ods/csv_test_create_from_file.ods b/tests/resources/ods/csv_test_create_from_file.ods new file mode 100644 index 0000000..c07641a Binary files /dev/null and b/tests/resources/ods/csv_test_create_from_file.ods differ diff --git a/tests/resources/other/test_unsupported_file_type.other b/tests/resources/other/test_unsupported_file_type.other new file mode 100644 index 0000000..e69de29 diff --git a/tests/resources/xlsx/csv_test_create_from_file.xlsx b/tests/resources/xlsx/csv_test_create_from_file.xlsx new file mode 100644 index 0000000..012c3e2 Binary files /dev/null and b/tests/resources/xlsx/csv_test_create_from_file.xlsx differ