Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4ace972e7 | ||
|
|
c428daff5a | ||
|
|
5908443583 | ||
|
|
050672755d | ||
|
|
e1928eb68a | ||
|
|
9467b5a810 | ||
|
|
2699ffbcae | ||
|
|
3559bc8834 | ||
|
|
506d682e74 | ||
|
|
7efab5576d | ||
|
|
366f121eb0 | ||
|
|
f8d0ac2682 | ||
|
|
82377403ff | ||
|
|
e0c84f77b1 | ||
|
|
b78227c370 |
No files matched your search
@@ -7,6 +7,10 @@ php:
|
|||||||
- 7.0
|
- 7.0
|
||||||
- hhvm
|
- hhvm
|
||||||
|
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- $HOME/.composer/cache
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- composer install --no-interaction --prefer-source
|
- composer install --no-interaction --prefer-source
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
Spout is a PHP library to read and write CSV and XLSX files, in a fast and scalable way.
|
Spout is a PHP library to read and write CSV and XLSX files, in a fast and scalable way.
|
||||||
Contrary to other file readers or writers, it is capable of processing very large files while keeping the memory usage really low (less than 10MB).
|
Contrary to other file readers or writers, it is capable of processing very large files while keeping the memory usage really low (less than 10MB).
|
||||||
|
|
||||||
|
Join the community and come discuss about Spout: [](https://gitter.im/box/spout?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
@@ -153,10 +154,12 @@ It is possible to apply some formatting options to a row. Spout supports fonts a
|
|||||||
use Box\Spout\Common\Type;
|
use Box\Spout\Common\Type;
|
||||||
use Box\Spout\Writer\WriterFactory;
|
use Box\Spout\Writer\WriterFactory;
|
||||||
use Box\Spout\Writer\Style\StyleBuilder;
|
use Box\Spout\Writer\Style\StyleBuilder;
|
||||||
|
use Box\Spout\Writer\Style\Color;
|
||||||
|
|
||||||
$style = (new StyleBuilder())
|
$style = (new StyleBuilder())
|
||||||
->setFontBold()
|
->setFontBold()
|
||||||
->setFontSize(15)
|
->setFontSize(15)
|
||||||
|
->setFontColor(Color::BLUE)
|
||||||
->setShouldWrapText()
|
->setShouldWrapText()
|
||||||
->build();
|
->build();
|
||||||
|
|
||||||
@@ -180,6 +183,7 @@ Font | Bold | `StyleBuilder::setFontBold()`
|
|||||||
| Strikethrough | `StyleBuilder::setFontStrikethrough()`
|
| Strikethrough | `StyleBuilder::setFontStrikethrough()`
|
||||||
| Font name | `StyleBuilder::setFontName('Arial')`
|
| Font name | `StyleBuilder::setFontName('Arial')`
|
||||||
| Font size | `StyleBuilder::setFontSize(14)`
|
| Font size | `StyleBuilder::setFontSize(14)`
|
||||||
|
| Font color | `StyleBuilder::setFontSize(Color::BLUE)`<br>`StyleBuilder::setFontSize(Color::rgb(0, 128, 255))`
|
||||||
Alignment | Wrap text | `StyleBuilder::setShouldWrapText()`
|
Alignment | Wrap text | `StyleBuilder::setShouldWrapText()`
|
||||||
|
|
||||||
|
|
||||||
@@ -199,6 +203,11 @@ $writer->setShouldUseInlineStrings(true); // default (and recommended) value
|
|||||||
$writer->setShouldUseInlineStrings(false); // will use shared strings
|
$writer->setShouldUseInlineStrings(false); // will use shared strings
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> ##### Note on Apple Numbers and iOS support
|
||||||
|
>
|
||||||
|
> Apple's products (Numbers and the iOS previewer) don't support inline strings and display empty cells instead. Therefore, if these platforms need to be supported, make sure to use shared strings!
|
||||||
|
|
||||||
|
|
||||||
#### New sheet creation
|
#### New sheet creation
|
||||||
|
|
||||||
It is also possible to change the behavior of the writer when the maximum number of rows (1,048,576) have been written in the current sheet:
|
It is also possible to change the behavior of the writer when the maximum number of rows (1,048,576) have been written in the current sheet:
|
||||||
@@ -258,6 +267,16 @@ $sheet = $writer->getCurrentSheet();
|
|||||||
$sheetName = $sheet->setName('My custom name');
|
$sheetName = $sheet->setName('My custom name');
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Please note that Excel has some restrictions on the sheet's name:
|
||||||
|
> * it must not be blank
|
||||||
|
> * it must not exceed 31 characters
|
||||||
|
> * it must not contain these characters: \ / ? * : [ or ]
|
||||||
|
> * it must not start or end with a single quote
|
||||||
|
> * it must be unique
|
||||||
|
>
|
||||||
|
> Handling these restrictions is the developer's responsibility. Spout does not try to automatically change the sheet's name, as one may rely on this name to be exactly what was passed in.
|
||||||
|
|
||||||
|
|
||||||
### Fluent interface
|
### Fluent interface
|
||||||
|
|
||||||
Because fluent interfaces are great, you can use them with Spout:
|
Because fluent interfaces are great, you can use them with Spout:
|
||||||
@@ -319,6 +338,8 @@ So the larger the file would be, the more memory would be consumed, preventing y
|
|||||||
|
|
||||||
Need to contact us directly? Email oss@box.com and be sure to include the name of this project in the subject.
|
Need to contact us directly? Email oss@box.com and be sure to include the name of this project in the subject.
|
||||||
|
|
||||||
|
You can also ask questions, submit new features ideas or discuss about Spout in the chat room:<br>
|
||||||
|
[](https://gitter.im/box/spout?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||||
|
|
||||||
## Copyright and License
|
## Copyright and License
|
||||||
|
|
||||||
|
|||||||
Generated
+49
-49
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"hash": "3c0d36250693792d14bc19f14250fec6",
|
"hash": "0866be323931eaa6e9431b3bbf0a817a",
|
||||||
"packages": [],
|
"packages": [],
|
||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
{
|
{
|
||||||
@@ -585,16 +585,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpspec/prophecy",
|
"name": "phpspec/prophecy",
|
||||||
"version": "v1.4.1",
|
"version": "v1.5.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/phpspec/prophecy.git",
|
"url": "https://github.com/phpspec/prophecy.git",
|
||||||
"reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373"
|
"reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373",
|
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7",
|
||||||
"reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373",
|
"reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -641,20 +641,20 @@
|
|||||||
"spy",
|
"spy",
|
||||||
"stub"
|
"stub"
|
||||||
],
|
],
|
||||||
"time": "2015-04-27 22:15:08"
|
"time": "2015-08-13 10:07:40"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-code-coverage",
|
"name": "phpunit/php-code-coverage",
|
||||||
"version": "2.1.9",
|
"version": "2.2.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||||
"reference": "5bd48b86cd282da411bb80baac1398ce3fefac41"
|
"reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5bd48b86cd282da411bb80baac1398ce3fefac41",
|
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2d7c03c0e4e080901b8f33b2897b0577be18a13c",
|
||||||
"reference": "5bd48b86cd282da411bb80baac1398ce3fefac41",
|
"reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -662,7 +662,7 @@
|
|||||||
"phpunit/php-file-iterator": "~1.3",
|
"phpunit/php-file-iterator": "~1.3",
|
||||||
"phpunit/php-text-template": "~1.2",
|
"phpunit/php-text-template": "~1.2",
|
||||||
"phpunit/php-token-stream": "~1.3",
|
"phpunit/php-token-stream": "~1.3",
|
||||||
"sebastian/environment": "~1.0",
|
"sebastian/environment": "^1.3.2",
|
||||||
"sebastian/version": "~1.0"
|
"sebastian/version": "~1.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
@@ -677,7 +677,7 @@
|
|||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "2.1.x-dev"
|
"dev-master": "2.2.x-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@@ -703,7 +703,7 @@
|
|||||||
"testing",
|
"testing",
|
||||||
"xunit"
|
"xunit"
|
||||||
],
|
],
|
||||||
"time": "2015-07-26 12:54:47"
|
"time": "2015-08-04 03:42:39"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-file-iterator",
|
"name": "phpunit/php-file-iterator",
|
||||||
@@ -836,16 +836,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-token-stream",
|
"name": "phpunit/php-token-stream",
|
||||||
"version": "1.4.3",
|
"version": "1.4.6",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
||||||
"reference": "7a9b0969488c3c54fd62b4d504b3ec758fd005d9"
|
"reference": "3ab72c62e550370a6cd5dc873e1a04ab57562f5b"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/7a9b0969488c3c54fd62b4d504b3ec758fd005d9",
|
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3ab72c62e550370a6cd5dc873e1a04ab57562f5b",
|
||||||
"reference": "7a9b0969488c3c54fd62b4d504b3ec758fd005d9",
|
"reference": "3ab72c62e550370a6cd5dc873e1a04ab57562f5b",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -881,20 +881,20 @@
|
|||||||
"keywords": [
|
"keywords": [
|
||||||
"tokenizer"
|
"tokenizer"
|
||||||
],
|
],
|
||||||
"time": "2015-06-19 03:43:16"
|
"time": "2015-08-16 08:51:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/phpunit",
|
"name": "phpunit/phpunit",
|
||||||
"version": "4.7.7",
|
"version": "4.8.5",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||||
"reference": "9b97f9d807b862c2de2a36e86690000801c85724"
|
"reference": "9b7417edaf28059ea63d86be941e6004dbfcc0cc"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9b97f9d807b862c2de2a36e86690000801c85724",
|
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9b7417edaf28059ea63d86be941e6004dbfcc0cc",
|
||||||
"reference": "9b97f9d807b862c2de2a36e86690000801c85724",
|
"reference": "9b7417edaf28059ea63d86be941e6004dbfcc0cc",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -904,7 +904,7 @@
|
|||||||
"ext-reflection": "*",
|
"ext-reflection": "*",
|
||||||
"ext-spl": "*",
|
"ext-spl": "*",
|
||||||
"php": ">=5.3.3",
|
"php": ">=5.3.3",
|
||||||
"phpspec/prophecy": "~1.3,>=1.3.1",
|
"phpspec/prophecy": "^1.3.1",
|
||||||
"phpunit/php-code-coverage": "~2.1",
|
"phpunit/php-code-coverage": "~2.1",
|
||||||
"phpunit/php-file-iterator": "~1.4",
|
"phpunit/php-file-iterator": "~1.4",
|
||||||
"phpunit/php-text-template": "~1.2",
|
"phpunit/php-text-template": "~1.2",
|
||||||
@@ -912,7 +912,7 @@
|
|||||||
"phpunit/phpunit-mock-objects": "~2.3",
|
"phpunit/phpunit-mock-objects": "~2.3",
|
||||||
"sebastian/comparator": "~1.1",
|
"sebastian/comparator": "~1.1",
|
||||||
"sebastian/diff": "~1.2",
|
"sebastian/diff": "~1.2",
|
||||||
"sebastian/environment": "~1.2",
|
"sebastian/environment": "~1.3",
|
||||||
"sebastian/exporter": "~1.2",
|
"sebastian/exporter": "~1.2",
|
||||||
"sebastian/global-state": "~1.0",
|
"sebastian/global-state": "~1.0",
|
||||||
"sebastian/version": "~1.0",
|
"sebastian/version": "~1.0",
|
||||||
@@ -927,7 +927,7 @@
|
|||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "4.7.x-dev"
|
"dev-master": "4.8.x-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@@ -953,24 +953,24 @@
|
|||||||
"testing",
|
"testing",
|
||||||
"xunit"
|
"xunit"
|
||||||
],
|
],
|
||||||
"time": "2015-07-13 11:28:34"
|
"time": "2015-08-19 09:20:57"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/phpunit-mock-objects",
|
"name": "phpunit/phpunit-mock-objects",
|
||||||
"version": "2.3.6",
|
"version": "2.3.7",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
|
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
|
||||||
"reference": "18dfbcb81d05e2296c0bcddd4db96cade75e6f42"
|
"reference": "5e2645ad49d196e020b85598d7c97e482725786a"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/18dfbcb81d05e2296c0bcddd4db96cade75e6f42",
|
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/5e2645ad49d196e020b85598d7c97e482725786a",
|
||||||
"reference": "18dfbcb81d05e2296c0bcddd4db96cade75e6f42",
|
"reference": "5e2645ad49d196e020b85598d7c97e482725786a",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"doctrine/instantiator": "~1.0,>=1.0.2",
|
"doctrine/instantiator": "^1.0.2",
|
||||||
"php": ">=5.3.3",
|
"php": ">=5.3.3",
|
||||||
"phpunit/php-text-template": "~1.2",
|
"phpunit/php-text-template": "~1.2",
|
||||||
"sebastian/exporter": "~1.2"
|
"sebastian/exporter": "~1.2"
|
||||||
@@ -1009,7 +1009,7 @@
|
|||||||
"mock",
|
"mock",
|
||||||
"xunit"
|
"xunit"
|
||||||
],
|
],
|
||||||
"time": "2015-07-10 06:54:24"
|
"time": "2015-08-19 09:14:08"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "scrutinizer/ocular",
|
"name": "scrutinizer/ocular",
|
||||||
@@ -1165,16 +1165,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sebastian/environment",
|
"name": "sebastian/environment",
|
||||||
"version": "1.3.0",
|
"version": "1.3.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/environment.git",
|
"url": "https://github.com/sebastianbergmann/environment.git",
|
||||||
"reference": "4fe0a44cddd8cc19583a024bdc7374eb2fef0b87"
|
"reference": "6324c907ce7a52478eeeaede764f48733ef5ae44"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4fe0a44cddd8cc19583a024bdc7374eb2fef0b87",
|
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6324c907ce7a52478eeeaede764f48733ef5ae44",
|
||||||
"reference": "4fe0a44cddd8cc19583a024bdc7374eb2fef0b87",
|
"reference": "6324c907ce7a52478eeeaede764f48733ef5ae44",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -1211,7 +1211,7 @@
|
|||||||
"environment",
|
"environment",
|
||||||
"hhvm"
|
"hhvm"
|
||||||
],
|
],
|
||||||
"time": "2015-07-26 06:42:57"
|
"time": "2015-08-03 06:14:51"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sebastian/exporter",
|
"name": "sebastian/exporter",
|
||||||
@@ -1420,16 +1420,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/console",
|
"name": "symfony/console",
|
||||||
"version": "v2.7.2",
|
"version": "v2.7.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/Console.git",
|
"url": "https://github.com/symfony/Console.git",
|
||||||
"reference": "8cf484449130cabfd98dcb4694ca9945802a21ed"
|
"reference": "d6cf02fe73634c96677e428f840704bfbcaec29e"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/Console/zipball/8cf484449130cabfd98dcb4694ca9945802a21ed",
|
"url": "https://api.github.com/repos/symfony/Console/zipball/d6cf02fe73634c96677e428f840704bfbcaec29e",
|
||||||
"reference": "8cf484449130cabfd98dcb4694ca9945802a21ed",
|
"reference": "d6cf02fe73634c96677e428f840704bfbcaec29e",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -1473,11 +1473,11 @@
|
|||||||
],
|
],
|
||||||
"description": "Symfony Console Component",
|
"description": "Symfony Console Component",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2015-07-09 16:07:40"
|
"time": "2015-07-28 15:18:12"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/event-dispatcher",
|
"name": "symfony/event-dispatcher",
|
||||||
"version": "v2.7.2",
|
"version": "v2.7.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/EventDispatcher.git",
|
"url": "https://github.com/symfony/EventDispatcher.git",
|
||||||
@@ -1535,7 +1535,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/process",
|
"name": "symfony/process",
|
||||||
"version": "v2.7.2",
|
"version": "v2.7.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/Process.git",
|
"url": "https://github.com/symfony/Process.git",
|
||||||
@@ -1584,16 +1584,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/yaml",
|
"name": "symfony/yaml",
|
||||||
"version": "v2.7.2",
|
"version": "v2.7.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/Yaml.git",
|
"url": "https://github.com/symfony/Yaml.git",
|
||||||
"reference": "4bfbe0ed3909bfddd75b70c094391ec1f142f860"
|
"reference": "71340e996171474a53f3d29111d046be4ad8a0ff"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/4bfbe0ed3909bfddd75b70c094391ec1f142f860",
|
"url": "https://api.github.com/repos/symfony/Yaml/zipball/71340e996171474a53f3d29111d046be4ad8a0ff",
|
||||||
"reference": "4bfbe0ed3909bfddd75b70c094391ec1f142f860",
|
"reference": "71340e996171474a53f3d29111d046be4ad8a0ff",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -1629,7 +1629,7 @@
|
|||||||
],
|
],
|
||||||
"description": "Symfony Yaml Component",
|
"description": "Symfony Yaml Component",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"time": "2015-07-01 11:25:50"
|
"time": "2015-07-28 14:07:07"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Box\Spout\Common\Helper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class StringHelper
|
||||||
|
* This class provides helper functions to work with strings and multibyte strings.
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
|
*
|
||||||
|
* @package Box\Spout\Common\Helper
|
||||||
|
*/
|
||||||
|
class StringHelper
|
||||||
|
{
|
||||||
|
/** @var bool Whether the mbstring extension is loaded */
|
||||||
|
protected $hasMbstringSupport;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->hasMbstringSupport = extension_loaded('mbstring');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the length of the given string.
|
||||||
|
* It uses the multi-bytes function is available.
|
||||||
|
* @see strlen
|
||||||
|
* @see mb_strlen
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getStringLength($string)
|
||||||
|
{
|
||||||
|
return $this->hasMbstringSupport ? mb_strlen($string) : strlen($string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the position of the first occurrence of the given character/substring within the given string.
|
||||||
|
* It uses the multi-bytes function is available.
|
||||||
|
* @see strpos
|
||||||
|
* @see mb_strpos
|
||||||
|
*
|
||||||
|
* @param string $char Needle
|
||||||
|
* @param string $string Haystack
|
||||||
|
* @return int Char/substring's first occurrence position within the string if found (starts at 0) or -1 if not found
|
||||||
|
*/
|
||||||
|
public function getCharFirstOccurrencePosition($char, $string)
|
||||||
|
{
|
||||||
|
$position = $this->hasMbstringSupport ? mb_strpos($string, $char) : strpos($string, $char);
|
||||||
|
return ($position !== false) ? $position : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the position of the last occurrence of the given character/substring within the given string.
|
||||||
|
* It uses the multi-bytes function is available.
|
||||||
|
* @see strrpos
|
||||||
|
* @see mb_strrpos
|
||||||
|
*
|
||||||
|
* @param string $char Needle
|
||||||
|
* @param string $string Haystack
|
||||||
|
* @return int Char/substring's last occurrence position within the string if found (starts at 0) or -1 if not found
|
||||||
|
*/
|
||||||
|
public function getCharLastOccurrencePosition($char, $string)
|
||||||
|
{
|
||||||
|
$position = $this->hasMbstringSupport ? mb_strrpos($string, $char) : strrpos($string, $char);
|
||||||
|
return ($position !== false) ? $position : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Box\Spout\Writer\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class InvalidColorException
|
||||||
|
*
|
||||||
|
* @package Box\Spout\Writer\Exception
|
||||||
|
*/
|
||||||
|
class InvalidColorException extends WriterException
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Box\Spout\Writer\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class InvalidSheetNameException
|
||||||
|
*
|
||||||
|
* @package Box\Spout\Writer\Exception
|
||||||
|
*/
|
||||||
|
class InvalidSheetNameException extends WriterException
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Box\Spout\Writer\Style;
|
||||||
|
|
||||||
|
use Box\Spout\Writer\Exception\InvalidColorException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Color
|
||||||
|
* This class provides constants and functions to work with colors
|
||||||
|
*
|
||||||
|
* @package Box\Spout\Writer\Style
|
||||||
|
*/
|
||||||
|
class Color
|
||||||
|
{
|
||||||
|
/** Standard colors - based on Office Online */
|
||||||
|
const BLACK = 'FF000000';
|
||||||
|
const WHITE = 'FFFFFFFF';
|
||||||
|
const RED = 'FFFF0000';
|
||||||
|
const DARK_RED = 'FFC00000';
|
||||||
|
const ORANGE = 'FFFFC000';
|
||||||
|
const YELLOW = 'FFFFFF00';
|
||||||
|
const LIGHT_GREEN = 'FF92D040';
|
||||||
|
const GREEN = 'FF00B050';
|
||||||
|
const LIGHT_BLUE = 'FF00B0E0';
|
||||||
|
const BLUE = 'FF0070C0';
|
||||||
|
const DARK_BLUE = 'FF002060';
|
||||||
|
const PURPLE = 'FF7030A0';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an ARGB color from R, G and B values
|
||||||
|
* Alpha is assumed to always be 1
|
||||||
|
*
|
||||||
|
* @param int $red Red component, 0 - 255
|
||||||
|
* @param int $green Green component, 0 - 255
|
||||||
|
* @param int $blue Blue component, 0 - 255
|
||||||
|
* @return string ARGB color
|
||||||
|
*/
|
||||||
|
public static function rgb($red, $green, $blue)
|
||||||
|
{
|
||||||
|
self::throwIfInvalidColorComponentValue($red);
|
||||||
|
self::throwIfInvalidColorComponentValue($green);
|
||||||
|
self::throwIfInvalidColorComponentValue($blue);
|
||||||
|
|
||||||
|
return strtoupper(
|
||||||
|
'FF' .
|
||||||
|
self::convertColorComponentToHex($red) .
|
||||||
|
self::convertColorComponentToHex($green) .
|
||||||
|
self::convertColorComponentToHex($blue)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an exception is the color component value is outside of bounds (0 - 255)
|
||||||
|
*
|
||||||
|
* @param int $colorComponent
|
||||||
|
* @return void
|
||||||
|
* @throws \Box\Spout\Writer\Exception\InvalidColorException
|
||||||
|
*/
|
||||||
|
protected static function throwIfInvalidColorComponentValue($colorComponent)
|
||||||
|
{
|
||||||
|
if (!is_int($colorComponent) || $colorComponent < 0 || $colorComponent > 255) {
|
||||||
|
throw new InvalidColorException("The RGB components must be between 0 and 255. Received: $colorComponent");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the color component to its corresponding hexadecimal value
|
||||||
|
*
|
||||||
|
* @param int $colorComponent Color component, 0 - 255
|
||||||
|
* @return string Corresponding hexadecimal value, with a leading 0 if needed. E.g "0f", "2d"
|
||||||
|
*/
|
||||||
|
protected static function convertColorComponentToHex($colorComponent)
|
||||||
|
{
|
||||||
|
return str_pad(dechex($colorComponent), 2, '0', 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ class Style
|
|||||||
{
|
{
|
||||||
/** Default font values */
|
/** Default font values */
|
||||||
const DEFAULT_FONT_SIZE = 11;
|
const DEFAULT_FONT_SIZE = 11;
|
||||||
|
const DEFAULT_FONT_COLOR = Color::BLACK;
|
||||||
const DEFAULT_FONT_NAME = 'Arial';
|
const DEFAULT_FONT_NAME = 'Arial';
|
||||||
|
|
||||||
/** @var int|null Style ID */
|
/** @var int|null Style ID */
|
||||||
@@ -42,6 +43,11 @@ class Style
|
|||||||
/** @var bool Whether the font size property was set */
|
/** @var bool Whether the font size property was set */
|
||||||
protected $hasSetFontSize = false;
|
protected $hasSetFontSize = false;
|
||||||
|
|
||||||
|
/** @var string Font color */
|
||||||
|
protected $fontColor = self::DEFAULT_FONT_COLOR;
|
||||||
|
/** @var bool Whether the font color property was set */
|
||||||
|
protected $hasSetFontColor = false;
|
||||||
|
|
||||||
/** @var string Font name */
|
/** @var string Font name */
|
||||||
protected $fontName = self::DEFAULT_FONT_NAME;
|
protected $fontName = self::DEFAULT_FONT_NAME;
|
||||||
/** @var bool Whether the font name property was set */
|
/** @var bool Whether the font name property was set */
|
||||||
@@ -169,6 +175,28 @@ class Style
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getFontColor()
|
||||||
|
{
|
||||||
|
return $this->fontColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the font color.
|
||||||
|
*
|
||||||
|
* @param string $fontColor ARGB color (@see Color)
|
||||||
|
* @return Style
|
||||||
|
*/
|
||||||
|
public function setFontColor($fontColor)
|
||||||
|
{
|
||||||
|
$this->fontColor = $fontColor;
|
||||||
|
$this->hasSetFontColor = true;
|
||||||
|
$this->shouldApplyFont = true;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@@ -265,6 +293,9 @@ class Style
|
|||||||
if (!$this->hasSetFontSize && $baseStyle->getFontSize() !== self::DEFAULT_FONT_SIZE) {
|
if (!$this->hasSetFontSize && $baseStyle->getFontSize() !== self::DEFAULT_FONT_SIZE) {
|
||||||
$mergedStyle->setFontSize($baseStyle->getFontSize());
|
$mergedStyle->setFontSize($baseStyle->getFontSize());
|
||||||
}
|
}
|
||||||
|
if (!$this->hasSetFontSize && $baseStyle->getFontColor() !== self::DEFAULT_FONT_COLOR) {
|
||||||
|
$mergedStyle->setFontColor($baseStyle->getFontColor());
|
||||||
|
}
|
||||||
if (!$this->hasSetFontName && $baseStyle->getFontName() !== self::DEFAULT_FONT_NAME) {
|
if (!$this->hasSetFontName && $baseStyle->getFontName() !== self::DEFAULT_FONT_NAME) {
|
||||||
$mergedStyle->setFontName($baseStyle->getFontName());
|
$mergedStyle->setFontName($baseStyle->getFontName());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,18 @@ class StyleBuilder
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the font color.
|
||||||
|
*
|
||||||
|
* @param string $fontColor ARGB color (@see Color)
|
||||||
|
* @return StyleBuilder
|
||||||
|
*/
|
||||||
|
public function setFontColor($fontColor)
|
||||||
|
{
|
||||||
|
$this->style->setFontColor($fontColor);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the font name.
|
* Sets the font name.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -180,10 +180,10 @@ EOD;
|
|||||||
*/
|
*/
|
||||||
protected function createCoreXmlFile()
|
protected function createCoreXmlFile()
|
||||||
{
|
{
|
||||||
$createdDate = (new \DateTime())->format('c');
|
$createdDate = (new \DateTime())->format(\DateTime::W3C);
|
||||||
$coreXmlFileContents = <<<EOD
|
$coreXmlFileContents = <<<EOD
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<dcterms:created xsi:type="dcterms:W3CDTF">$createdDate</dcterms:created>
|
<dcterms:created xsi:type="dcterms:W3CDTF">$createdDate</dcterms:created>
|
||||||
<dcterms:modified xsi:type="dcterms:W3CDTF">$createdDate</dcterms:modified>
|
<dcterms:modified xsi:type="dcterms:W3CDTF">$createdDate</dcterms:modified>
|
||||||
<cp:revision>0</cp:revision>
|
<cp:revision>0</cp:revision>
|
||||||
|
|||||||
@@ -150,9 +150,14 @@ EOD;
|
|||||||
{
|
{
|
||||||
$content = ' <fonts count="' . count($this->styleIdToStyleMappingTable) . '">' . PHP_EOL;
|
$content = ' <fonts count="' . count($this->styleIdToStyleMappingTable) . '">' . PHP_EOL;
|
||||||
|
|
||||||
|
/** @var \Box\Spout\Writer\Style\Style $style */
|
||||||
foreach ($this->styleIdToStyleMappingTable as $style) {
|
foreach ($this->styleIdToStyleMappingTable as $style) {
|
||||||
$content .= ' <font>' . PHP_EOL;
|
$content .= ' <font>' . PHP_EOL;
|
||||||
|
|
||||||
|
$content .= ' <sz val="' . $style->getFontSize() . '"/>' . PHP_EOL;
|
||||||
|
$content .= ' <color rgb="' . $style->getFontColor() . '"/>' . PHP_EOL;
|
||||||
|
$content .= ' <name val="' . $style->getFontName() . '"/>' . PHP_EOL;
|
||||||
|
|
||||||
if ($style->isFontBold()) {
|
if ($style->isFontBold()) {
|
||||||
$content .= ' <b/>' . PHP_EOL;
|
$content .= ' <b/>' . PHP_EOL;
|
||||||
}
|
}
|
||||||
@@ -166,8 +171,6 @@ EOD;
|
|||||||
$content .= ' <strike/>' . PHP_EOL;
|
$content .= ' <strike/>' . PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
$content .= ' <sz val="' . $style->getFontSize() . '"/>' . PHP_EOL;
|
|
||||||
$content .= ' <name val="' . $style->getFontName() . '"/>' . PHP_EOL;
|
|
||||||
$content .= ' </font>' . PHP_EOL;
|
$content .= ' </font>' . PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,12 @@
|
|||||||
|
|
||||||
namespace Box\Spout\Writer\XLSX;
|
namespace Box\Spout\Writer\XLSX;
|
||||||
|
|
||||||
|
use Box\Spout\Common\Helper\StringHelper;
|
||||||
|
use Box\Spout\Writer\Exception\InvalidSheetNameException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Sheet
|
* Class Sheet
|
||||||
* Represents a worksheet within a XLSX file
|
* External representation of a worksheet within a XLSX file
|
||||||
*
|
*
|
||||||
* @package Box\Spout\Writer\XLSX
|
* @package Box\Spout\Writer\XLSX
|
||||||
*/
|
*/
|
||||||
@@ -12,19 +15,32 @@ class Sheet
|
|||||||
{
|
{
|
||||||
const DEFAULT_SHEET_NAME_PREFIX = 'Sheet';
|
const DEFAULT_SHEET_NAME_PREFIX = 'Sheet';
|
||||||
|
|
||||||
|
/** Sheet name should not exceed 31 characters */
|
||||||
|
const MAX_LENGTH_SHEET_NAME = 31;
|
||||||
|
|
||||||
|
/** @var array Invalid characters that cannot be contained in the sheet name */
|
||||||
|
private static $INVALID_CHARACTERS_IN_SHEET_NAME = ['\\', '/', '?', '*', ':', '[', ']'];
|
||||||
|
|
||||||
|
/** @var array Associative array [SHEET_INDEX] => [SHEET_NAME] keeping track of sheets' name to enforce uniqueness */
|
||||||
|
protected static $SHEETS_NAME_USED = [];
|
||||||
|
|
||||||
/** @var int Index of the sheet, based on order of creation (zero-based) */
|
/** @var int Index of the sheet, based on order of creation (zero-based) */
|
||||||
protected $index;
|
protected $index;
|
||||||
|
|
||||||
/** @var string Name of the sheet */
|
/** @var string Name of the sheet */
|
||||||
protected $name;
|
protected $name;
|
||||||
|
|
||||||
|
/** @var \Box\Spout\Common\Helper\StringHelper */
|
||||||
|
protected $stringHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $sheetIndex Index of the sheet, based on order of creation (zero-based)
|
* @param int $sheetIndex Index of the sheet, based on order of creation (zero-based)
|
||||||
*/
|
*/
|
||||||
public function __construct($sheetIndex)
|
public function __construct($sheetIndex)
|
||||||
{
|
{
|
||||||
$this->index = $sheetIndex;
|
$this->index = $sheetIndex;
|
||||||
$this->name = self::DEFAULT_SHEET_NAME_PREFIX . ($sheetIndex + 1);
|
$this->stringHelper = new StringHelper();
|
||||||
|
$this->setName(self::DEFAULT_SHEET_NAME_PREFIX . ($sheetIndex + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,12 +60,97 @@ class Sheet
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Sets the name of the sheet. Note that Excel has some restrictions on the name:
|
||||||
|
* - it should not be blank
|
||||||
|
* - it should not exceed 31 characters
|
||||||
|
* - it should not contain these characters: \ / ? * : [ or ]
|
||||||
|
* - it should be unique
|
||||||
|
*
|
||||||
* @param string $name Name of the sheet
|
* @param string $name Name of the sheet
|
||||||
* @return Sheet
|
* @return Sheet
|
||||||
|
* @throws \Box\Spout\Writer\Exception\InvalidSheetNameException If the sheet's name is invalid.
|
||||||
*/
|
*/
|
||||||
public function setName($name)
|
public function setName($name)
|
||||||
{
|
{
|
||||||
|
if (!$this->isNameValid($name)) {
|
||||||
|
$errorMessage = "The sheet's name is invalid. It did not meet at least one of these requirements:\n";
|
||||||
|
$errorMessage .= " - It should not be blank\n";
|
||||||
|
$errorMessage .= " - It should not exceed 31 characters\n";
|
||||||
|
$errorMessage .= " - It should not contain these characters: \\ / ? * : [ or ]\n";
|
||||||
|
$errorMessage .= " - It should be unique";
|
||||||
|
throw new InvalidSheetNameException($errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
|
self::$SHEETS_NAME_USED[$this->index] = $name;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the given sheet's name is valid.
|
||||||
|
* @see Sheet::setName for validity rules.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return bool TRUE if the name is valid, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
protected function isNameValid($name)
|
||||||
|
{
|
||||||
|
if (!is_string($name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$nameLength = $this->stringHelper->getStringLength($name);
|
||||||
|
|
||||||
|
return (
|
||||||
|
$nameLength > 0 &&
|
||||||
|
$nameLength <= self::MAX_LENGTH_SHEET_NAME &&
|
||||||
|
!$this->doesContainInvalidCharacters($name) &&
|
||||||
|
$this->isNameUnique($name) &&
|
||||||
|
!$this->doesStartOrEndWithSingleQuote($name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the given name contains at least one invalid character.
|
||||||
|
* @see Sheet::$INVALID_CHARACTERS_IN_SHEET_NAME for the full list.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return bool TRUE if the name contains invalid characters, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
protected function doesContainInvalidCharacters($name)
|
||||||
|
{
|
||||||
|
return (str_replace(self::$INVALID_CHARACTERS_IN_SHEET_NAME, '', $name) !== $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the given name starts or ends with a single quote
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return bool TRUE if the name starts or ends with a single quote, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
protected function doesStartOrEndWithSingleQuote($name)
|
||||||
|
{
|
||||||
|
$startsWithSingleQuote = ($this->stringHelper->getCharFirstOccurrencePosition('\'', $name) === 0);
|
||||||
|
$endsWithSingleQuote = ($this->stringHelper->getCharLastOccurrencePosition('\'', $name) === ($this->stringHelper->getStringLength($name) - 1));
|
||||||
|
|
||||||
|
return ($startsWithSingleQuote || $endsWithSingleQuote);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the given name is unique.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return bool TRUE if the name is unique, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
protected function isNameUnique($name)
|
||||||
|
{
|
||||||
|
foreach (self::$SHEETS_NAME_USED as $sheetIndex => $sheetName) {
|
||||||
|
if ($sheetIndex !== $this->index && $sheetName === $name) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Box\Spout\Writer\Style;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ColorTest
|
||||||
|
*
|
||||||
|
* @package Box\Spout\Writer\Style
|
||||||
|
*/
|
||||||
|
class ColorTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function dataProviderForTestRGB()
|
||||||
|
{
|
||||||
|
|
||||||
|
return [
|
||||||
|
[0, 0, 0, Color::BLACK],
|
||||||
|
[255, 255, 255, Color::WHITE],
|
||||||
|
[255, 0, 0, Color::RED],
|
||||||
|
[192, 0, 0, Color::DARK_RED],
|
||||||
|
[255, 192, 0, Color::ORANGE],
|
||||||
|
[255, 255, 0, Color::YELLOW],
|
||||||
|
[146, 208, 64, Color::LIGHT_GREEN],
|
||||||
|
[0, 176, 80, Color::GREEN],
|
||||||
|
[0, 176, 224, Color::LIGHT_BLUE],
|
||||||
|
[0, 112, 192, Color::BLUE],
|
||||||
|
[0, 32, 96, Color::DARK_BLUE],
|
||||||
|
[112, 48, 160, Color::PURPLE],
|
||||||
|
[0, 0, 0, 'FF000000'],
|
||||||
|
[255, 255, 255, 'FFFFFFFF'],
|
||||||
|
[255, 0, 0, 'FFFF0000'],
|
||||||
|
[0, 128, 0, 'FF008000'],
|
||||||
|
[0, 255, 0, 'FF00FF00'],
|
||||||
|
[0, 0, 255, 'FF0000FF'],
|
||||||
|
[128, 22, 43, 'FF80162B'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataProviderForTestRGB
|
||||||
|
*
|
||||||
|
* @param int $red
|
||||||
|
* @param int $green
|
||||||
|
* @param int $blue
|
||||||
|
* @param string $expectedColor
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testRGB($red, $green, $blue, $expectedColor)
|
||||||
|
{
|
||||||
|
$color = Color::rgb($red, $green, $blue);
|
||||||
|
$this->assertEquals($expectedColor, $color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function dataProviderForTestRGBAInvalidColorComponents()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[-1, 0, 0],
|
||||||
|
[0, -1, 0],
|
||||||
|
[0, 0, -1],
|
||||||
|
[999, 0, 0],
|
||||||
|
[0, 999, 0],
|
||||||
|
[0, 0, 999],
|
||||||
|
[null, 0, 0],
|
||||||
|
[0, null, 0],
|
||||||
|
[0, 0, null],
|
||||||
|
['1', 0, 0],
|
||||||
|
[0, '1', 0],
|
||||||
|
[0, 0, '1'],
|
||||||
|
[true, 0, 0],
|
||||||
|
[0, true, 0],
|
||||||
|
[0, 0, true],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataProviderForTestRGBAInvalidColorComponents
|
||||||
|
* @expectedException \Box\Spout\Writer\Exception\InvalidColorException
|
||||||
|
*
|
||||||
|
* @param int $red
|
||||||
|
* @param int $green
|
||||||
|
* @param int $blue
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testRGBInvalidColorComponents($red, $green, $blue)
|
||||||
|
{
|
||||||
|
Color::rgb($red, $green, $blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,7 +20,7 @@ class SheetTest extends \PHPUnit_Framework_TestCase
|
|||||||
*/
|
*/
|
||||||
public function testGetSheetIndex()
|
public function testGetSheetIndex()
|
||||||
{
|
{
|
||||||
$sheets = $this->writeDataAndReturnSheets('test_get_sheet_index.xlsx');
|
$sheets = $this->writeDataToMulitpleSheetsAndReturnSheets('test_get_sheet_index.xlsx');
|
||||||
|
|
||||||
$this->assertEquals(2, count($sheets), '2 sheets should have been created');
|
$this->assertEquals(2, count($sheets), '2 sheets should have been created');
|
||||||
$this->assertEquals(0, $sheets[0]->getIndex(), 'The first sheet should be index 0');
|
$this->assertEquals(0, $sheets[0]->getIndex(), 'The first sheet should be index 0');
|
||||||
@@ -32,7 +32,7 @@ class SheetTest extends \PHPUnit_Framework_TestCase
|
|||||||
*/
|
*/
|
||||||
public function testGetSheetName()
|
public function testGetSheetName()
|
||||||
{
|
{
|
||||||
$sheets = $this->writeDataAndReturnSheets('test_get_sheet_name.xlsx');
|
$sheets = $this->writeDataToMulitpleSheetsAndReturnSheets('test_get_sheet_name.xlsx');
|
||||||
|
|
||||||
$this->assertEquals(2, count($sheets), '2 sheets should have been created');
|
$this->assertEquals(2, count($sheets), '2 sheets should have been created');
|
||||||
$this->assertEquals('Sheet1', $sheets[0]->getName(), 'Invalid name for the first sheet');
|
$this->assertEquals('Sheet1', $sheets[0]->getName(), 'Invalid name for the first sheet');
|
||||||
@@ -45,27 +45,118 @@ class SheetTest extends \PHPUnit_Framework_TestCase
|
|||||||
public function testSetSheetNameShouldCreateSheetWithCustomName()
|
public function testSetSheetNameShouldCreateSheetWithCustomName()
|
||||||
{
|
{
|
||||||
$fileName = 'test_set_name_should_create_sheet_with_custom_name.xlsx';
|
$fileName = 'test_set_name_should_create_sheet_with_custom_name.xlsx';
|
||||||
|
$customSheetName = 'CustomName';
|
||||||
|
$this->writeDataAndReturnSheetWithCustomName($fileName, $customSheetName);
|
||||||
|
|
||||||
|
$this->assertSheetNameEquals($customSheetName, $fileName, "The sheet name should have been changed to '$customSheetName'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function dataProviderForInvalidSheetNames()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[null],
|
||||||
|
[21],
|
||||||
|
[''],
|
||||||
|
['this title exceeds the 31 characters limit'],
|
||||||
|
['Illegal \\'],
|
||||||
|
['Illegal /'],
|
||||||
|
['Illegal ?'],
|
||||||
|
['Illegal *'],
|
||||||
|
['Illegal :'],
|
||||||
|
['Illegal ['],
|
||||||
|
['Illegal ]'],
|
||||||
|
['\'Illegal start'],
|
||||||
|
['Illegal end\''],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataProviderForInvalidSheetNames
|
||||||
|
* @expectedException \Box\Spout\Writer\Exception\InvalidSheetNameException
|
||||||
|
*
|
||||||
|
* @param string $customSheetName
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testSetSheetNameShouldThrowOnInvalidName($customSheetName)
|
||||||
|
{
|
||||||
|
$fileName = 'test_set_name_with_invalid_name_should_throw_exception.xlsx';
|
||||||
|
$this->writeDataAndReturnSheetWithCustomName($fileName, $customSheetName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testSetSheetNameShouldNotThrowWhenSettingSameNameAsCurrentOne()
|
||||||
|
{
|
||||||
|
$fileName = 'test_set_name_with_same_as_current.xlsx';
|
||||||
$this->createGeneratedFolderIfNeeded($fileName);
|
$this->createGeneratedFolderIfNeeded($fileName);
|
||||||
$resourcePath = $this->getGeneratedResourcePath($fileName);
|
$resourcePath = $this->getGeneratedResourcePath($fileName);
|
||||||
|
|
||||||
$writer = WriterFactory::create(Type::XLSX);
|
$writer = WriterFactory::create(Type::XLSX);
|
||||||
$writer->openToFile($resourcePath);
|
$writer->openToFile($resourcePath);
|
||||||
|
|
||||||
$customSheetName = 'CustomName';
|
$customSheetName = 'Sheet name';
|
||||||
$sheet = $writer->getCurrentSheet();
|
$sheet = $writer->getCurrentSheet();
|
||||||
$sheet->setName($customSheetName);
|
$sheet->setName($customSheetName);
|
||||||
|
$sheet->setName($customSheetName);
|
||||||
|
|
||||||
$writer->addRow(['xlsx--11', 'xlsx--12']);
|
$writer->addRow(['xlsx--11', 'xlsx--12']);
|
||||||
$writer->close();
|
$writer->close();
|
||||||
|
|
||||||
$this->assertSheetNameEquals($customSheetName, $resourcePath, "The sheet name should have been changed to '$customSheetName'");
|
$this->assertSheetNameEquals($customSheetName, $fileName, "The sheet name should have been changed to '$customSheetName'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Box\Spout\Writer\Exception\InvalidSheetNameException
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testSetSheetNameShouldThrowWhenNameIsAlreadyUsed()
|
||||||
|
{
|
||||||
|
$fileName = 'test_set_name_with_non_unique_name.xlsx';
|
||||||
|
$this->createGeneratedFolderIfNeeded($fileName);
|
||||||
|
$resourcePath = $this->getGeneratedResourcePath($fileName);
|
||||||
|
|
||||||
|
$writer = WriterFactory::create(Type::XLSX);
|
||||||
|
$writer->openToFile($resourcePath);
|
||||||
|
|
||||||
|
$customSheetName = 'Sheet name';
|
||||||
|
|
||||||
|
$sheet = $writer->getCurrentSheet();
|
||||||
|
$sheet->setName($customSheetName);
|
||||||
|
|
||||||
|
$writer->addNewSheetAndMakeItCurrent();
|
||||||
|
$sheet = $writer->getCurrentSheet();
|
||||||
|
$sheet->setName($customSheetName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $fileName
|
||||||
|
* @param string $sheetName
|
||||||
|
* @return Sheet
|
||||||
|
*/
|
||||||
|
private function writeDataAndReturnSheetWithCustomName($fileName, $sheetName)
|
||||||
|
{
|
||||||
|
$this->createGeneratedFolderIfNeeded($fileName);
|
||||||
|
$resourcePath = $this->getGeneratedResourcePath($fileName);
|
||||||
|
|
||||||
|
$writer = WriterFactory::create(Type::XLSX);
|
||||||
|
$writer->openToFile($resourcePath);
|
||||||
|
|
||||||
|
$sheet = $writer->getCurrentSheet();
|
||||||
|
$sheet->setName($sheetName);
|
||||||
|
|
||||||
|
$writer->addRow(['xlsx--11', 'xlsx--12']);
|
||||||
|
$writer->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $fileName
|
* @param string $fileName
|
||||||
* @return Sheet[]
|
* @return Sheet[]
|
||||||
*/
|
*/
|
||||||
private function writeDataAndReturnSheets($fileName)
|
private function writeDataToMulitpleSheetsAndReturnSheets($fileName)
|
||||||
{
|
{
|
||||||
$this->createGeneratedFolderIfNeeded($fileName);
|
$this->createGeneratedFolderIfNeeded($fileName);
|
||||||
$resourcePath = $this->getGeneratedResourcePath($fileName);
|
$resourcePath = $this->getGeneratedResourcePath($fileName);
|
||||||
@@ -85,12 +176,13 @@ class SheetTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $expectedName
|
* @param string $expectedName
|
||||||
* @param string $resourcePath
|
* @param string $fileName
|
||||||
* @param string $message
|
* @param string $message
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function assertSheetNameEquals($expectedName, $resourcePath, $message = '')
|
private function assertSheetNameEquals($expectedName, $fileName, $message = '')
|
||||||
{
|
{
|
||||||
|
$resourcePath = $this->getGeneratedResourcePath($fileName);
|
||||||
$pathToWorkbookFile = $resourcePath . '#xl/workbook.xml';
|
$pathToWorkbookFile = $resourcePath . '#xl/workbook.xml';
|
||||||
$xmlContents = file_get_contents('zip://' . $pathToWorkbookFile);
|
$xmlContents = file_get_contents('zip://' . $pathToWorkbookFile);
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ namespace Box\Spout\Writer\XLSX;
|
|||||||
|
|
||||||
use Box\Spout\Common\Type;
|
use Box\Spout\Common\Type;
|
||||||
use Box\Spout\TestUsingResource;
|
use Box\Spout\TestUsingResource;
|
||||||
|
use Box\Spout\Writer\Style\Color;
|
||||||
|
use Box\Spout\Writer\Style\Style;
|
||||||
use Box\Spout\Writer\Style\StyleBuilder;
|
use Box\Spout\Writer\Style\StyleBuilder;
|
||||||
use Box\Spout\Writer\WriterFactory;
|
use Box\Spout\Writer\WriterFactory;
|
||||||
|
|
||||||
@@ -110,6 +112,7 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
|
|||||||
->build();
|
->build();
|
||||||
$style2 = (new StyleBuilder())
|
$style2 = (new StyleBuilder())
|
||||||
->setFontSize(15)
|
->setFontSize(15)
|
||||||
|
->setFontColor(Color::RED)
|
||||||
->setFontName('Arial')
|
->setFontName('Arial')
|
||||||
->build();
|
->build();
|
||||||
|
|
||||||
@@ -123,24 +126,27 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
// First font should be the default one
|
// First font should be the default one
|
||||||
$defaultFontElement = $fontElements->item(0);
|
$defaultFontElement = $fontElements->item(0);
|
||||||
$this->assertChildrenNumEquals(2, $defaultFontElement, 'The default font should only have 2 properties.');
|
$this->assertChildrenNumEquals(3, $defaultFontElement, 'The default font should only have 3 properties.');
|
||||||
$this->assertFirstChildHasAttributeEquals((string) Writer::DEFAULT_FONT_SIZE, $defaultFontElement, 'sz', 'val');
|
$this->assertFirstChildHasAttributeEquals((string) Writer::DEFAULT_FONT_SIZE, $defaultFontElement, 'sz', 'val');
|
||||||
|
$this->assertFirstChildHasAttributeEquals(Style::DEFAULT_FONT_COLOR, $defaultFontElement, 'color', 'rgb');
|
||||||
$this->assertFirstChildHasAttributeEquals(Writer::DEFAULT_FONT_NAME, $defaultFontElement, 'name', 'val');
|
$this->assertFirstChildHasAttributeEquals(Writer::DEFAULT_FONT_NAME, $defaultFontElement, 'name', 'val');
|
||||||
|
|
||||||
// Second font should contain data from the first created style
|
// Second font should contain data from the first created style
|
||||||
$secondFontElement = $fontElements->item(1);
|
$secondFontElement = $fontElements->item(1);
|
||||||
$this->assertChildrenNumEquals(6, $secondFontElement, 'The font should only have 6 properties (4 custom styles + 2 default styles).');
|
$this->assertChildrenNumEquals(7, $secondFontElement, 'The font should only have 7 properties (4 custom styles + 3 default styles).');
|
||||||
$this->assertChildExists($secondFontElement, 'b');
|
$this->assertChildExists($secondFontElement, 'b');
|
||||||
$this->assertChildExists($secondFontElement, 'i');
|
$this->assertChildExists($secondFontElement, 'i');
|
||||||
$this->assertChildExists($secondFontElement, 'u');
|
$this->assertChildExists($secondFontElement, 'u');
|
||||||
$this->assertChildExists($secondFontElement, 'strike');
|
$this->assertChildExists($secondFontElement, 'strike');
|
||||||
$this->assertFirstChildHasAttributeEquals((string) Writer::DEFAULT_FONT_SIZE, $secondFontElement, 'sz', 'val');
|
$this->assertFirstChildHasAttributeEquals((string) Writer::DEFAULT_FONT_SIZE, $secondFontElement, 'sz', 'val');
|
||||||
|
$this->assertFirstChildHasAttributeEquals(Style::DEFAULT_FONT_COLOR, $secondFontElement, 'color', 'rgb');
|
||||||
$this->assertFirstChildHasAttributeEquals(Writer::DEFAULT_FONT_NAME, $secondFontElement, 'name', 'val');
|
$this->assertFirstChildHasAttributeEquals(Writer::DEFAULT_FONT_NAME, $secondFontElement, 'name', 'val');
|
||||||
|
|
||||||
// Third font should contain data from the second created style
|
// Third font should contain data from the second created style
|
||||||
$thirdFontElement = $fontElements->item(2);
|
$thirdFontElement = $fontElements->item(2);
|
||||||
$this->assertChildrenNumEquals(2, $thirdFontElement, 'The font should only have 2 properties.');
|
$this->assertChildrenNumEquals(3, $thirdFontElement, 'The font should only have 3 properties.');
|
||||||
$this->assertFirstChildHasAttributeEquals('15', $thirdFontElement, 'sz', 'val');
|
$this->assertFirstChildHasAttributeEquals('15', $thirdFontElement, 'sz', 'val');
|
||||||
|
$this->assertFirstChildHasAttributeEquals(Color::RED, $thirdFontElement, 'color', 'rgb');
|
||||||
$this->assertFirstChildHasAttributeEquals('Arial', $thirdFontElement, 'name', 'val');
|
$this->assertFirstChildHasAttributeEquals('Arial', $thirdFontElement, 'name', 'val');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user