├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── DependencyInjection ├── Configuration.php └── MewesKTwigExcelExtension.php ├── EventListener └── RequestListener.php ├── MewesKTwigExcelBundle.php ├── README.md ├── Resources ├── config │ └── services.xml ├── doc │ ├── conf.py │ ├── examples.rst │ ├── getting_started.rst │ ├── index.rst │ ├── installation.rst │ ├── twig_functions.rst │ └── twig_tags.rst └── meta │ └── LICENSE ├── Tests ├── Fixtures │ ├── AppKernel.php │ ├── TestBundle │ │ ├── Controller │ │ │ └── DefaultController.php │ │ ├── Resources │ │ │ └── views │ │ │ │ └── Default │ │ │ │ ├── documentTemplatePath1.twig │ │ │ │ ├── documentTemplatePath2.twig │ │ │ │ ├── simple.twig │ │ │ │ └── template.xlsx │ │ └── TestBundle.php │ └── config │ │ ├── config.yml │ │ ├── config_custom.yml │ │ └── routing.yml ├── Functional │ ├── AbstractControllerTest.php │ ├── CustomConfigTest.php │ └── DefaultControllerTest.php ├── Resources │ ├── templates │ │ ├── template.csv │ │ ├── template.ods │ │ ├── template.xls │ │ ├── template.xlsx │ │ └── template_advanced.xlsx │ └── views │ │ ├── block.twig │ │ ├── blockError.twig │ │ ├── blockOverrideCell.twig │ │ ├── blockOverrideContent.twig │ │ ├── blockOverrideRow.twig │ │ ├── blockOverrideSheet.twig │ │ ├── cellFormula.twig │ │ ├── cellIndex.twig │ │ ├── cellProperties.twig │ │ ├── documentError.twig │ │ ├── documentFormat.twig │ │ ├── documentProperties.twig │ │ ├── documentSimple.twig │ │ ├── documentTemplate.csv.twig │ │ ├── documentTemplate.ods.twig │ │ ├── documentTemplate.xls.twig │ │ ├── documentTemplate.xlsx.twig │ │ ├── documentTemplateAdvanced.twig │ │ ├── drawingProperties.twig │ │ ├── drawingSimple.twig │ │ ├── headerFooterComplex.twig │ │ ├── headerFooterDrawing.twig │ │ ├── headerFooterProperties.twig │ │ ├── include.twig │ │ ├── includeCell.twig │ │ ├── includeContent.twig │ │ ├── includeDocument.twig │ │ ├── includeRow.twig │ │ ├── includeSheet.twig │ │ ├── macro.twig │ │ ├── macroError.twig │ │ ├── macroImport.twig │ │ ├── rowIndex.twig │ │ ├── sheetComplex.twig │ │ ├── sheetError.twig │ │ ├── sheetProperties.twig │ │ └── sheetState.twig └── Twig │ ├── AbstractTwigTest.php │ ├── BasicTwigTest.php │ ├── CsvTwigTest.php │ ├── ErrorTwigTest.php │ ├── PdfTwigTest.php │ ├── XlsTwigTest.php │ └── XlsxTwigTest.php ├── Twig ├── Node │ ├── SyntaxAwareNodeInterface.php │ ├── XlsCellNode.php │ ├── XlsCenterNode.php │ ├── XlsDocumentNode.php │ ├── XlsDrawingNode.php │ ├── XlsFooterNode.php │ ├── XlsHeaderNode.php │ ├── XlsLeftNode.php │ ├── XlsRightNode.php │ ├── XlsRowNode.php │ └── XlsSheetNode.php ├── NodeHelper.php ├── NodeVisitor │ └── SyntaxCheckNodeVisitor.php ├── TokenParser │ ├── AbstractTokenParser.php │ ├── XlsBlockTokenParser.php │ ├── XlsCellTokenParser.php │ ├── XlsCenterTokenParser.php │ ├── XlsDocumentTokenParser.php │ ├── XlsDrawingTokenParser.php │ ├── XlsFooterTokenParser.php │ ├── XlsHeaderTokenParser.php │ ├── XlsIncludeTokenParser.php │ ├── XlsLeftTokenParser.php │ ├── XlsMacroTokenParser.php │ ├── XlsRightTokenParser.php │ ├── XlsRowTokenParser.php │ └── XlsSheetTokenParser.php └── TwigExcelExtension.php ├── Wrapper ├── AbstractWrapper.php ├── PhpExcelWrapper.php ├── XlsCellWrapper.php ├── XlsDocumentWrapper.php ├── XlsDrawingWrapper.php ├── XlsHeaderFooterWrapper.php ├── XlsRowWrapper.php └── XlsSheetWrapper.php ├── composer.json ├── phpunit.coverage.xml.dist └── phpunit.xml.dist /.gitignore: -------------------------------------------------------------------------------- 1 | .phpunit/ 2 | tmp/ 3 | vendor/ 4 | composer.lock 5 | phpunit.xml 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - '5.5' 5 | - '5.6' 6 | - '7.0' 7 | - hhvm 8 | 9 | matrix: 10 | fast_finish: true 11 | include: 12 | - php: '5.5' 13 | env: SYMFONY_VERSION='2.7.*' 14 | - php: '5.6' 15 | env: SYMFONY_VERSION='2.7.*' 16 | - php: '7.0' 17 | env: SYMFONY_VERSION='2.7.*' 18 | - php: '7.0' 19 | env: SYMFONY_VERSION='2.8.*' 20 | - php: '7.0' 21 | env: SYMFONY_VERSION='3.1.*' 22 | - php: '7.0' 23 | env: SYMFONY_VERSION='3.2.*' 24 | - php: '7.0' 25 | env: SYMFONY_VERSION='3.4.*' 26 | 27 | sudo: false 28 | 29 | cache: 30 | directories: 31 | - $HOME/.composer/cache/files 32 | 33 | before_install: 34 | - if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then phpenv config-rm xdebug.ini; fi 35 | - if [ "$SYMFONY_VERSION" != "" ]; then composer require --dev --no-update symfony/symfony=$SYMFONY_VERSION; fi 36 | 37 | install: 38 | - composer update $COMPOSER_FLAGS --prefer-dist --prefer-stable 39 | 40 | script: 41 | - vendor/bin/simple-phpunit 42 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 2.2 (2017-05-25) 2 | 3 | **Attention** 4 | 5 | PhpExcel will not support PHP 7.1 or newer. I have changed the requirements accordingly. 6 | I will start working on the next release using PhpSpreadsheet, the successor to PhpExcel. 7 | 8 | **Fixes** 9 | 10 | * Bugfix #20 How to autosize columns (guiyomh) 11 | * Fixed a Twig 2.0 bug (a73280e) 12 | 13 | ## 2.1 (2016-10-09) 14 | 15 | **Fixes** 16 | 17 | * Bugfix #8 {% xlsmacro %} cannot call a macro defined in the same twig file (ThmX) 18 | * Fixed issue #14 'Include another template' (plfort) 19 | * Fixed issue #16 'Leading zeros problem in a string that contains an integer' (aserratorta) 20 | 21 | **Features** 22 | 23 | * Added support for cell merging (malheirosrafa) 24 | * Added 'autoFilter' property to the 'xlssheet' tag (fdicioccio) 25 | * Added new 'xlsinclude' tag to support includes containing other TwigExcelBundle tags. Not the most elegant solution but necessary to clean up the node tree before including it in the main template. 26 | 27 | ## 2.0 (2016-02-27) 28 | 29 | **Attention** 30 | 31 | Some mayor changes required to increase the minimum requirements significantly. Therefore I'm bumping the version to 2.0. 32 | 33 | **Improvements** 34 | 35 | * Converted help to RST-format and moved it to Resources/doc 36 | * Rendered version of the documentation is now hosted on readthedocs.org 37 | * Removed more deprecated function calls (for compatibility with Twig 2.0) 38 | * Removed unnecessary mock objects 39 | * Added messages to InvalidArgumentExceptions (darookee) 40 | 41 | **Features** 42 | 43 | * Added support for blocks and macros in form of the new xlsblock/xlsmacro tags. The standard tags do sadly not work since they won't allow to alter the internal node structure. 44 | * Added support for document templates. Use existing spreadsheet files as templates. 45 | 46 | ## 1.2 (2015-12-02) 47 | 48 | **Fixes** 49 | 50 | * Added Symfony 2.7 and 2.8 to the automated tests 51 | 52 | **Improvements** 53 | 54 | * Added Symfony 3 support 55 | * Added PHP 7 automated tests 56 | 57 | ## 1.1 (2015-12-02) 58 | 59 | **Fixes** 60 | 61 | * Fixed minimum PHP version to >=5.4 (short array syntax) 62 | * Fixed .PDF support 63 | 64 | **Features** 65 | 66 | * Added .ODS to the supported formats 67 | * Added 'dataType' property to the 'xlscell' tag. Used to manually override data type of the cell. 68 | * Added bundle config 'mewesk_twig_excel.pre_calculate_formulas'. Pre-calculating formulas can be slow in certain cases. Disabling this option can improve the performance but the resulting documents won't show the result of any formulas when opened in a external spreadsheet software. 69 | * Added bundle config 'mewesk_twig_excel.disk_caching_directory'. Using disk caching can improve memory consumption by writing data to disk temporarily. Works only for .XLSX and .ODS documents. 70 | 71 | **Improvements** 72 | 73 | * Updated to latest stable PHPExcel 74 | * Updated to latest stable mPDF 75 | * Improved inline documentation 76 | * Improved code quality 77 | * Added latest PHP/HHVM and Symfony versions to the automated tests 78 | * Added more unit tests and functional tests 79 | 80 | ## 1.0 (2014-03-04) 81 | 82 | * Initial release 83 | -------------------------------------------------------------------------------- /DependencyInjection/Configuration.php: -------------------------------------------------------------------------------- 1 | root('mewes_k_twig_excel'); 23 | 24 | $rootNode 25 | ->children() 26 | ->booleanNode('pre_calculate_formulas')->defaultTrue()->info('Pre-calculating formulas can be slow in certain cases. Disabling this option can improve the performance but the resulting documents won\'t show the result of any formulas when opened in a external spreadsheet software.')->end() 27 | ->scalarNode('disk_caching_directory')->defaultNull()->info('Using disk caching can improve memory consumption by writing data to disk temporary. Works only for .XLSX and .ODS documents.')->example('/tmp')->end() 28 | ->end(); 29 | 30 | return $treeBuilder; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /DependencyInjection/MewesKTwigExcelExtension.php: -------------------------------------------------------------------------------- 1 | load('services.xml'); 25 | 26 | $container->setParameter('mewes_k_twig_excel.pre_calculate_formulas', $mergedConfig['pre_calculate_formulas']); 27 | $container->setParameter('mewes_k_twig_excel.disk_caching_directory', $mergedConfig['disk_caching_directory']); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /EventListener/RequestListener.php: -------------------------------------------------------------------------------- 1 | getRequest()->setFormat('csv', 'text/csv'); 20 | $event->getRequest()->setFormat('ods', 'application/vnd.oasis.opendocument.spreadsheet'); 21 | $event->getRequest()->setFormat('pdf', 'application/pdf'); 22 | $event->getRequest()->setFormat('xls', 'application/vnd.ms-excel'); 23 | $event->getRequest()->setFormat('xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /MewesKTwigExcelBundle.php: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | MewesK\TwigExcelBundle\EventListener\RequestListener 8 | MewesK\TwigExcelBundle\Twig\TwigExcelExtension 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | %mewes_k_twig_excel.pre_calculate_formulas% 19 | %mewes_k_twig_excel.disk_caching_directory% 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Resources/doc/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | source_suffix = '.rst' 3 | master_doc = 'index' 4 | project = 'TwigExcelBundle' 5 | copyright = u'2014-2016, Mewes Kochheim' 6 | version = '' 7 | release = '' 8 | html_theme = 'default' 9 | -------------------------------------------------------------------------------- /Resources/doc/examples.rst: -------------------------------------------------------------------------------- 1 | Examples 2 | ======== 3 | 4 | For more advanced examples check the unit test scenarios here: 5 | 6 | https://github.com/MewesK/TwigExcelBundle/tree/master/Tests/Resources/views 7 | -------------------------------------------------------------------------------- /Resources/doc/getting_started.rst: -------------------------------------------------------------------------------- 1 | Getting started 2 | =============== 3 | 4 | Step 1: Create your controller 5 | ------------------------------ 6 | 7 | .. code-block:: php 8 | 9 | ['La', 'Le', 'Lu']]; 27 | } 28 | } 29 | 30 | Step 2: Create your template 31 | ---------------------------- 32 | 33 | .. code-block:: twig 34 | 35 | {# src/Acme/HelloBundle/Resources/views/Hello/index.xls.twig #} 36 | 37 | {% xlsdocument %} 38 | {% xlssheet 'Worksheet' %} 39 | {% xlsrow %} 40 | {% xlscell { style: { font: { size: '18' } } } %}Values{% endxlscell %} 41 | {% endxlsrow %} 42 | {% for value in data %} 43 | {% xlsrow %} 44 | {% xlscell %}{{ value }}{% endxlscell %} 45 | {% endxlsrow %} 46 | {% endfor %} 47 | {% endxlssheet %} 48 | {% endxlsdocument %} 49 | -------------------------------------------------------------------------------- /Resources/doc/index.rst: -------------------------------------------------------------------------------- 1 | TwigExcelBundle Documentation 2 | ============================= 3 | 4 | |TravisCI| |Scrutinizer| |SensioLabsInsight| 5 | 6 | .. _dev-docs: 7 | 8 | User Documentation 9 | ------------------ 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | installation 15 | getting_started 16 | examples 17 | twig_functions 18 | twig_tags 19 | 20 | .. |TravisCI| image:: https://travis-ci.org/MewesK/TwigExcelBundle.png?branch=master 21 | :target: https://travis-ci.org/MewesK/TwigExcelBundle 22 | .. |Scrutinizer| image:: https://scrutinizer-ci.com/g/MewesK/TwigExcelBundle/badges/quality-score.png?b=master 23 | :target: https://scrutinizer-ci.com/g/MewesK/TwigExcelBundle/?branch=master 24 | .. |SensioLabsInsight| image:: https://insight.sensiolabs.com/projects/283cfe57-6ee4-4102-8fff-da3f6e668e8f/mini.png 25 | :target: https://insight.sensiolabs.com/projects/283cfe57-6ee4-4102-8fff-da3f6e668e8f 26 | -------------------------------------------------------------------------------- /Resources/doc/installation.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | Step 1: Download the Bundle 5 | --------------------------- 6 | 7 | Open a command console, enter your project directory and execute the 8 | following command to download the latest stable version of this bundle: 9 | 10 | .. code-block:: bash 11 | 12 | $ composer require mewesk/twig-excel-bundle 13 | 14 | Or add the following code to your composer.json file and run composer update afterwards: 15 | 16 | .. code-block:: json 17 | 18 | { 19 | "require": { 20 | "mewesk/twig-excel-bundle": "1.3.*@dev" 21 | } 22 | } 23 | 24 | .. code-block:: bash 25 | 26 | $ php composer.phar update mewesk/twig-excel-bundle 27 | 28 | This requires you to have Composer installed globally, as explained 29 | in the [installation chapter](https://getcomposer.org/doc/00-intro.md) 30 | of the Composer documentation. 31 | 32 | Step 2: Enable the Bundle 33 | ------------------------- 34 | 35 | .. code-block:: php 36 | 37 | isAbsolutePath($config)) { 29 | $config = __DIR__ . '/config/' .$config; 30 | } 31 | 32 | if (!file_exists($config)) { 33 | throw new \RuntimeException(sprintf('The config file "%s" does not exist.', $config)); 34 | } 35 | 36 | $this->config = $config; 37 | } 38 | 39 | /** 40 | * @return array 41 | */ 42 | public function registerBundles() 43 | { 44 | return [ 45 | new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), 46 | new Symfony\Bundle\TwigBundle\TwigBundle(), 47 | new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(), 48 | new MewesK\TwigExcelBundle\MewesKTwigExcelBundle(), 49 | new MewesK\TwigExcelBundle\Tests\Fixtures\TestBundle\TestBundle() 50 | ]; 51 | } 52 | 53 | /** 54 | * @param LoaderInterface $loader 55 | * @throws \Exception 56 | */ 57 | public function registerContainerConfiguration(LoaderInterface $loader) 58 | { 59 | $loader->load($this->config); 60 | } 61 | 62 | /** 63 | * @return string 64 | */ 65 | public function getCacheDir() 66 | { 67 | return __DIR__ . '/../../tmp/cache'; 68 | } 69 | 70 | /** 71 | * @return string 72 | */ 73 | public function getLogDir() 74 | { 75 | return __DIR__ . '/../../tmp/logs'; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Tests/Fixtures/TestBundle/Controller/DefaultController.php: -------------------------------------------------------------------------------- 1 | render( 25 | '@Test/Default/' . $templateName . '.twig', 26 | [ 27 | 'data' => [ 28 | ['name' => 'Everette Grim', 'salary' => 5458.0], 29 | ['name' => 'Nam Poirrier', 'salary' => 3233.0], 30 | ['name' => 'Jolynn Ell', 'salary' => 5718.0], 31 | ['name' => 'Ta Burdette', 'salary' => 1255.0], 32 | ['name' => 'Aida Salvas', 'salary' => 5226.0], 33 | ['name' => 'Gilbert Navarrette', 'salary' => 1431.0], 34 | ['name' => 'Kirk Figgins', 'salary' => 7429.0], 35 | ['name' => 'Rashad Cloutier', 'salary' => 8457.0], 36 | ['name' => 'Traci Schmitmeyer', 'salary' => 7521.0], 37 | ['name' => 'Cecila Statham', 'salary' => 7180.0], 38 | ['name' => 'Chong Robicheaux', 'salary' => 3511.0], 39 | ['name' => 'Romona Stockstill', 'salary' => 2943.0], 40 | ['name' => 'Roseann Sather', 'salary' => 9126.0], 41 | ['name' => 'Vera Racette', 'salary' => 4566.0], 42 | ['name' => 'Tennille Waltripv', 'salary' => 4485.0], 43 | ['name' => 'Dot Hedgpeth', 'salary' => 7687.0], 44 | ['name' => 'Thersa Havis', 'salary' => 2264.0], 45 | ['name' => 'Long Kenner', 'salary' => 4051.0], 46 | ['name' => 'Kena Kea', 'salary' => 4090.0], 47 | ['name' => 'Evita Chittum', 'salary' => 4639.0] 48 | ], 49 | 'kernelPath' => $this->get('kernel')->getRootDir() 50 | ] 51 | ); 52 | } 53 | 54 | /** 55 | * @param $templateName 56 | * @return \Symfony\Component\HttpFoundation\Response 57 | * @throws \InvalidArgumentException 58 | * 59 | * @Route("/custom-response/{templateName}.{_format}", name="test_custom_response", defaults={"templateName" = "simple", "_format" = "xlsx"}) 60 | */ 61 | public function customResponseAction($templateName) 62 | { 63 | $response = new Response( 64 | $this->render( 65 | '@Test/Default/' . $templateName . '.twig', 66 | [ 67 | 'data' => [ 68 | ['name' => 'Everette Grim', 'salary' => 5458.0], 69 | ['name' => 'Nam Poirrier', 'salary' => 3233.0], 70 | ['name' => 'Jolynn Ell', 'salary' => 5718.0] 71 | ] 72 | ] 73 | ), 74 | Response::HTTP_OK, 75 | [ 76 | 'Content-Disposition' => 'attachment; filename="foobar.bin"' 77 | ] 78 | ); 79 | 80 | $response->setPrivate(); 81 | $response->setMaxAge(600); 82 | 83 | return $response; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Tests/Fixtures/TestBundle/Resources/views/Default/documentTemplatePath1.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument { 'template': kernelPath ~ '/../Fixtures/TestBundle/Resources/views/Default/template' ~ '.xlsx' } %} 2 | {% endxlsdocument %} 3 | -------------------------------------------------------------------------------- /Tests/Fixtures/TestBundle/Resources/views/Default/documentTemplatePath2.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument { 'template': '@Test/Default/template.xlsx' } %} 2 | {% endxlsdocument %} 3 | -------------------------------------------------------------------------------- /Tests/Fixtures/TestBundle/Resources/views/Default/simple.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument %} 2 | {% xlssheet 'Test' %} 3 | {% xlsrow %} 4 | {% xlscell %}Name{% endxlscell %} 5 | {% xlscell %}Salary{% endxlscell %} 6 | {% endxlsrow %} 7 | {% set total = 0 %} 8 | {% for entity in data %} 9 | {% xlsrow %} 10 | {% xlscell %}{{ entity['name'] }}{% endxlscell %} 11 | {% xlscell %}{{ entity['salary']|raw }}{% endxlscell %} 12 | {% endxlsrow %} 13 | {% set total = total + entity['salary'] %} 14 | {% endfor %} 15 | {% xlsrow %} 16 | {% xlscell %}Total (PHP){% endxlscell %} 17 | {% xlscell %}{{ total }}{% endxlscell %} 18 | {% endxlsrow %} 19 | {% xlsrow %} 20 | {% xlscell %}Total (Excel){% endxlscell %} 21 | {% xlscell %}=SUM(B2:B21){% endxlscell %} 22 | {% endxlsrow %} 23 | {% endxlssheet %} 24 | {% endxlsdocument %} 25 | -------------------------------------------------------------------------------- /Tests/Fixtures/TestBundle/Resources/views/Default/template.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MewesK/TwigExcelBundle/a9b4a9ffa755893b570b499c86e94dbac97b6852/Tests/Fixtures/TestBundle/Resources/views/Default/template.xlsx -------------------------------------------------------------------------------- /Tests/Fixtures/TestBundle/TestBundle.php: -------------------------------------------------------------------------------- 1 | request('GET', $uri); 52 | $source = static::$client->getResponse()->getContent(); 53 | 54 | // create paths 55 | $tempDirPath = __DIR__ . static::$TEMP_PATH; 56 | $tempFilePath = $tempDirPath . 'simple' . '.' . $format; 57 | 58 | // save source 59 | static::$fileSystem->dumpFile($tempFilePath, $source); 60 | 61 | // load source 62 | switch ($format) { 63 | case 'ods': 64 | $reader = new PHPExcel_Reader_OOCalc(); 65 | break; 66 | case 'xls': 67 | $reader = new PHPExcel_Reader_Excel5(); 68 | break; 69 | case 'xlsx': 70 | $reader = new PHPExcel_Reader_Excel2007(); 71 | break; 72 | default: 73 | throw new InvalidArgumentException(); 74 | } 75 | 76 | return $reader->load(__DIR__ . static::$TEMP_PATH . 'simple' . '.' . $format); 77 | } 78 | 79 | // 80 | // PhpUnit 81 | // 82 | 83 | /** 84 | * @return array 85 | */ 86 | abstract public function formatProvider(); 87 | 88 | /** 89 | * {@inheritdoc} 90 | * @throws \RuntimeException 91 | */ 92 | protected static function createKernel(array $options = []) 93 | { 94 | if (null === static::$class) { 95 | static::$class = static::getKernelClass(); 96 | } 97 | 98 | return new static::$class( 99 | array_key_exists('config', $options) && is_string($options['config']) ? $options['config'] : 'config.yml' 100 | ); 101 | } 102 | 103 | /** 104 | * {@inheritdoc} 105 | * @throws \Exception 106 | */ 107 | protected function setUp() 108 | { 109 | static::$client = static::createClient(['config' => static::$CONFIG_FILE]); 110 | static::$router = static::$kernel->getContainer()->get('router'); 111 | } 112 | 113 | /** 114 | * {@inheritdoc} 115 | * @throws \Exception 116 | */ 117 | public static function setUpBeforeClass() 118 | { 119 | static::$fileSystem = new Filesystem(); 120 | static::$fileSystem->remove(__DIR__ . static::$TEMP_PATH); 121 | } 122 | 123 | /** 124 | * {@inheritdoc} 125 | * @throws \Symfony\Component\Filesystem\Exception\IOException 126 | */ 127 | public static function tearDownAfterClass() 128 | { 129 | if (in_array(getenv('DELETE_TEMP_FILES'), ['true', '1', 1, true], true)) { 130 | static::$fileSystem->remove(__DIR__ . static::$TEMP_PATH); 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /Tests/Functional/CustomConfigTest.php: -------------------------------------------------------------------------------- 1 | getDocument(static::$router->generate('test_default', ['templateName' => 'simple', '_format' => $format]), $format); 39 | static::assertNotNull($document, 'Document does not exist'); 40 | 41 | static::assertFalse(static::$kernel->getContainer()->getParameter('mewes_k_twig_excel.pre_calculate_formulas'), 'Unexpected parameter'); 42 | static::assertStringEndsWith('tmp/phpexcel', static::$kernel->getContainer()->getParameter('mewes_k_twig_excel.disk_caching_directory'), 'Unexpected parameter'); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Tests/Functional/DefaultControllerTest.php: -------------------------------------------------------------------------------- 1 | getDocument(static::$router->generate('test_default', ['templateName' => 'simple', '_format' => $format]), $format); 40 | static::assertNotNull($document, 'Document does not exist'); 41 | 42 | $sheet = $document->getSheetByName('Test'); 43 | static::assertNotNull($sheet, 'Sheet does not exist'); 44 | 45 | static::assertEquals(100270, $sheet->getCell('B22')->getValue(), 'Unexpected value in B22'); 46 | 47 | static::assertEquals('=SUM(B2:B21)', $sheet->getCell('B23')->getValue(), 'Unexpected value in B23'); 48 | static::assertTrue($sheet->getCell('B23')->isFormula(), 'Unexpected value in isFormula'); 49 | static::assertEquals(100270, $sheet->getCell('B23')->getCalculatedValue(), 'Unexpected calculated value in B23'); 50 | } 51 | 52 | /** 53 | * @param string $format 54 | * @throws \Exception 55 | * 56 | * @dataProvider formatProvider 57 | */ 58 | public function testCustomResponse($format) 59 | { 60 | // Generate URI 61 | $uri = static::$router->generate('test_custom_response', ['templateName' => 'simple', '_format' => $format]); 62 | 63 | // Generate source 64 | static::$client->request('GET', $uri); 65 | 66 | /** 67 | * @var $response Response 68 | */ 69 | $response = static::$client->getResponse(); 70 | 71 | static::assertNotNull($response, 'Response does not exist'); 72 | static::assertEquals('attachment; filename="foobar.bin"', $response->headers->get('content-disposition'), 'Unexpected or missing header "Content-Disposition"'); 73 | static::assertEquals('max-age=600, private', $response->headers->get('cache-control'), 'Unexpected or missing header "Cache-Control"'); 74 | } 75 | 76 | /** 77 | * @param string $format 78 | * @throws \Exception 79 | * 80 | * @dataProvider formatProvider 81 | */ 82 | public function testDocumentTemplatePath1($format) 83 | { 84 | $document = $this->getDocument(static::$router->generate('test_default', ['templateName' => 'documentTemplatePath1', '_format' => $format]), $format); 85 | static::assertNotNull($document, 'Document does not exist'); 86 | 87 | $sheet = $document->getSheet(0); 88 | static::assertNotNull($sheet, 'Sheet does not exist'); 89 | 90 | static::assertEquals('Hello', $sheet->getCell('A1')->getValue(), 'Unexpected value in A1'); 91 | static::assertEquals('World', $sheet->getCell('B1')->getValue(), 'Unexpected value in B1'); 92 | static::assertEquals('Foo', $sheet->getCell('A2')->getValue(), 'Unexpected value in A2'); 93 | static::assertEquals('Bar', $sheet->getCell('B2')->getValue(), 'Unexpected value in B2'); 94 | } 95 | 96 | /** 97 | * @param string $format 98 | * @throws \Exception 99 | * 100 | * @dataProvider formatProvider 101 | */ 102 | public function testDocumentTemplatePath2($format) 103 | { 104 | $document = $this->getDocument(static::$router->generate('test_default', ['templateName' => 'documentTemplatePath2', '_format' => $format]), $format); 105 | static::assertNotNull($document, 'Document does not exist'); 106 | 107 | $sheet = $document->getSheet(0); 108 | static::assertNotNull($sheet, 'Sheet does not exist'); 109 | 110 | static::assertEquals('Hello', $sheet->getCell('A1')->getValue(), 'Unexpected value in A1'); 111 | static::assertEquals('World', $sheet->getCell('B1')->getValue(), 'Unexpected value in B1'); 112 | static::assertEquals('Foo', $sheet->getCell('A2')->getValue(), 'Unexpected value in A2'); 113 | static::assertEquals('Bar', $sheet->getCell('B2')->getValue(), 'Unexpected value in B2'); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Tests/Resources/templates/template.csv: -------------------------------------------------------------------------------- 1 | Hello,World 2 | Foo,Bar 3 | -------------------------------------------------------------------------------- /Tests/Resources/templates/template.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MewesK/TwigExcelBundle/a9b4a9ffa755893b570b499c86e94dbac97b6852/Tests/Resources/templates/template.ods -------------------------------------------------------------------------------- /Tests/Resources/templates/template.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MewesK/TwigExcelBundle/a9b4a9ffa755893b570b499c86e94dbac97b6852/Tests/Resources/templates/template.xls -------------------------------------------------------------------------------- /Tests/Resources/templates/template.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MewesK/TwigExcelBundle/a9b4a9ffa755893b570b499c86e94dbac97b6852/Tests/Resources/templates/template.xlsx -------------------------------------------------------------------------------- /Tests/Resources/templates/template_advanced.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MewesK/TwigExcelBundle/a9b4a9ffa755893b570b499c86e94dbac97b6852/Tests/Resources/templates/template_advanced.xlsx -------------------------------------------------------------------------------- /Tests/Resources/views/block.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument %} 2 | {% xlsblock sheet %} 3 | {% xlssheet 'Test' %} 4 | {% xlsblock row %} 5 | {% xlsrow %} 6 | {% xlscell %}Hello{% endxlscell %} 7 | {% xlscell %}World{% endxlscell %} 8 | {% endxlsrow %} 9 | {% endxlsblock %} 10 | {% xlsrow %} 11 | {% xlscell %} 12 | {% xlsblock content %}Foo{% endxlsblock %} 13 | {% endxlscell %} 14 | {% xlsblock cell %} 15 | {% xlscell %}Bar{% endxlscell %} 16 | {% endxlsblock %} 17 | {% endxlsrow %} 18 | {% endxlssheet %} 19 | {% endxlsblock %} 20 | {% endxlsdocument %} 21 | -------------------------------------------------------------------------------- /Tests/Resources/views/blockError.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument %} 2 | {% xlssheet 'Test' %} 3 | {% xlsblock row1 %} 4 | {% xlsrow %} 5 | {% xlscell %}Hello{% endxlscell %} 6 | {% xlscell %}World{% endxlscell %} 7 | {% endxlsrow %} 8 | {% endxlsblock %} 9 | {% block row2 %} 10 | {% xlsrow %} 11 | {% xlscell %}Foo{% endxlscell %} 12 | {% xlscell %}Bar{% endxlscell %} 13 | {% endxlsrow %} 14 | {% endblock %} 15 | {% endxlssheet %} 16 | {% endxlsdocument %} 17 | -------------------------------------------------------------------------------- /Tests/Resources/views/blockOverrideCell.twig: -------------------------------------------------------------------------------- 1 | {% extends 'block.twig' %} 2 | {% xlsblock cell %} 3 | {% xlscell %}Bar2{% endxlscell %} 4 | {% endxlsblock %} 5 | -------------------------------------------------------------------------------- /Tests/Resources/views/blockOverrideContent.twig: -------------------------------------------------------------------------------- 1 | {% extends 'block.twig' %} 2 | {% xlsblock content %}Foo2{% endxlsblock %} 3 | -------------------------------------------------------------------------------- /Tests/Resources/views/blockOverrideRow.twig: -------------------------------------------------------------------------------- 1 | {% extends 'block.twig' %} 2 | {% xlsblock row %} 3 | {% xlsrow %} 4 | {% xlscell %}Hello2{% endxlscell %} 5 | {% xlscell %}World2{% endxlscell %} 6 | {% endxlsrow %} 7 | {% endxlsblock %} 8 | -------------------------------------------------------------------------------- /Tests/Resources/views/blockOverrideSheet.twig: -------------------------------------------------------------------------------- 1 | {% extends 'block.twig' %} 2 | {% xlsblock sheet %} 3 | {% xlssheet 'Test2' %} 4 | {% xlsrow %} 5 | {% xlscell %}Hello3{% endxlscell %} 6 | {% xlscell %}World3{% endxlscell %} 7 | {% endxlsrow %} 8 | {% endxlssheet %} 9 | {% endxlsblock %} 10 | -------------------------------------------------------------------------------- /Tests/Resources/views/cellFormula.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument %} 2 | {% xlssheet 'Test' %} 3 | {% xlsrow %} 4 | {% xlscell %}667.5{% endxlscell %} 5 | {% xlscell %}2{% endxlscell %} 6 | {% endxlsrow %} 7 | {% xlsrow %} 8 | {% xlscell %}=A1*B1+2{% endxlscell %} 9 | {% endxlsrow %} 10 | {% xlsrow %} 11 | {% xlscell %}=SUM(A1:B1){% endxlscell %} 12 | {% endxlsrow %} 13 | {% endxlssheet %} 14 | {% endxlsdocument %} 15 | -------------------------------------------------------------------------------- /Tests/Resources/views/cellIndex.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument %} 2 | {% xlssheet 'Test' %} 3 | {% xlsrow %} 4 | {% xlscell %}Foo{% endxlscell %} 5 | {% xlscell 2 %}Bar{% endxlscell %} 6 | {% xlscell 2 %}Lorem{% endxlscell %} 7 | {% xlscell %}Ipsum{% endxlscell %} 8 | {% xlscell 1 %}Hello{% endxlscell %} 9 | {% xlscell 4 %}World{% endxlscell %} 10 | {% endxlsrow %} 11 | {% xlsrow %} 12 | {% xlscell { 13 | 'merge': 2 14 | } %}Foo{% endxlscell %} 15 | {% endxlsrow %} 16 | {% xlsrow %} 17 | {% xlscell { 18 | 'merge': 'C3' 19 | } %}Foo{% endxlscell %} 20 | {% endxlsrow %} 21 | {% xlsrow %} 22 | {% xlscell { 23 | 'merge': 'A6' 24 | } %}Foo{% endxlscell %} 25 | {% endxlsrow %} 26 | {% endxlssheet %} 27 | {% endxlsdocument %} 28 | -------------------------------------------------------------------------------- /Tests/Resources/views/cellProperties.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument %} 2 | {% xlssheet 'Test' %} 3 | {% xlsrow %} 4 | {% xlscell { 5 | 'break': 1, 6 | 'dataValidation': { 7 | 'allowBlank': true, 8 | 'error': 'Test error', 9 | 'errorStyle': 'information', 10 | 'errorTitle': 'Test errorTitle', 11 | 'formula1': '', 12 | 'formula2': '', 13 | 'operator': '', 14 | 'prompt': 'Test prompt', 15 | 'promptTitle': 'Test promptTitle', 16 | 'showDropDown': true, 17 | 'showErrorMessage': true, 18 | 'showInputMessage': true, 19 | 'type': 'custom' 20 | }, 21 | 'style': { 22 | 'font': { 23 | 'size': 18.0 24 | } 25 | }, 26 | 'url': 'http://example.com/' 27 | } %}Foo{% endxlscell %} 28 | {% xlscell { 29 | 'dataType': 's' 30 | } %}42{% endxlscell %} 31 | {% xlscell { 32 | 'dataType': 'n' 33 | } %}42{% endxlscell %} 34 | {% xlscell { 35 | 'explicitValue': true 36 | } %}007{% endxlscell %} 37 | {% endxlsrow %} 38 | {% endxlssheet %} 39 | {% endxlsdocument %} 40 | -------------------------------------------------------------------------------- /Tests/Resources/views/documentError.twig: -------------------------------------------------------------------------------- 1 | {% xlssheet 'Test' %} 2 | {% xlsdocument %} 3 | {% xlsrow %} 4 | {% xlscell %}Foo{% endxlscell %} 5 | {% xlscell %}Bar{% endxlscell %} 6 | {% endxlsrow %} 7 | {% endxlsdocument %} 8 | {% endxlssheet %} 9 | -------------------------------------------------------------------------------- /Tests/Resources/views/documentFormat.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument { 'format': 'xls' } %} 2 | {% xlssheet 'Test' %} 3 | {% endxlssheet %} 4 | {% endxlsdocument %} -------------------------------------------------------------------------------- /Tests/Resources/views/documentProperties.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument { 2 | 'category': 'Test category', 3 | 'company': 'Test company', 4 | 'created': '2000/01/01', 5 | 'creator': 'Test creator', 6 | 'defaultStyle': { 7 | 'font': { 8 | 'size': 18.0 9 | } 10 | }, 11 | 'description': 'Test description', 12 | 'keywords': 'Test keywords', 13 | 'lastModifiedBy': 'Test modifier', 14 | 'manager': 'Test manager', 15 | 'modified': '2000/01/01', 16 | 'security': { 17 | 'lockRevision': true, 18 | 'lockStructure': true, 19 | 'lockWindows': true, 20 | 'revisionsPassword': 'test', 21 | 'workbookPassword': 'test' 22 | }, 23 | 'subject': 'Test subject', 24 | 'title': 'Test title' 25 | } %} 26 | {% xlssheet 'Test' %} 27 | {% endxlssheet %} 28 | {% endxlsdocument %} 29 | -------------------------------------------------------------------------------- /Tests/Resources/views/documentSimple.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument %} 2 | {% xlssheet 'Test' %} 3 | {% xlsrow %} 4 | {% xlscell %}Foo{% endxlscell %} 5 | {% xlscell %}Bar{% endxlscell %} 6 | {% endxlsrow %} 7 | {% xlsrow %} 8 | {% xlscell %} 9 | Hello 10 | {% endxlscell %} 11 | {% xlscell %} 12 | World 13 | {% endxlscell %} 14 | {% endxlsrow %} 15 | {% endxlssheet %} 16 | {% endxlsdocument %} -------------------------------------------------------------------------------- /Tests/Resources/views/documentTemplate.csv.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument { 'template': '@templates/template.csv' } %} 2 | {% xlssheet %} 3 | {% xlsrow %} 4 | {% xlscell %}Hello2{% endxlscell %} 5 | {% endxlsrow %} 6 | {% xlsrow %} 7 | {% xlscell 1 %}Bar2{% endxlscell %} 8 | {% endxlsrow %} 9 | {% endxlssheet %} 10 | {% endxlsdocument %} 11 | -------------------------------------------------------------------------------- /Tests/Resources/views/documentTemplate.ods.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument { 'template': '@templates/template.ods' } %} 2 | {% xlssheet %} 3 | {% xlsrow %} 4 | {% xlscell %}Hello2{% endxlscell %} 5 | {% endxlsrow %} 6 | {% xlsrow %} 7 | {% xlscell 1 %}Bar2{% endxlscell %} 8 | {% endxlsrow %} 9 | {% endxlssheet %} 10 | {% endxlsdocument %} 11 | -------------------------------------------------------------------------------- /Tests/Resources/views/documentTemplate.xls.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument { 'template': '@templates/template.xls' } %} 2 | {% xlssheet %} 3 | {% xlsrow %} 4 | {% xlscell %}Hello2{% endxlscell %} 5 | {% endxlsrow %} 6 | {% xlsrow %} 7 | {% xlscell 1 %}Bar2{% endxlscell %} 8 | {% endxlsrow %} 9 | {% endxlssheet %} 10 | {% endxlsdocument %} 11 | -------------------------------------------------------------------------------- /Tests/Resources/views/documentTemplate.xlsx.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument { 'template': '@templates/template.xlsx' } %} 2 | {% xlssheet %} 3 | {% xlsrow %} 4 | {% xlscell %}Hello2{% endxlscell %} 5 | {% endxlsrow %} 6 | {% xlsrow %} 7 | {% xlscell 1 %}Bar2{% endxlscell %} 8 | {% endxlsrow %} 9 | {% endxlssheet %} 10 | {% endxlsdocument %} 11 | -------------------------------------------------------------------------------- /Tests/Resources/views/documentTemplateAdvanced.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument { 'template': '@templates/template_advanced.xlsx' } %} 2 | {% xlssheet %} 3 | {% xlsrow %} 4 | {% xlscell %}Hello2{% endxlscell %} 5 | {% endxlsrow %} 6 | {% xlsrow %} 7 | {% xlscell 1 %}Bar2{% endxlscell %} 8 | {% endxlsrow %} 9 | {% endxlssheet %} 10 | {% endxlsdocument %} 11 | -------------------------------------------------------------------------------- /Tests/Resources/views/drawingProperties.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument %} 2 | {% xlssheet 'Test' %} 3 | {% xlsdrawing 'http://www.gravatar.com/avatar/0d9079a1311d9f89b0b28b13cea56a70?s=100' { 4 | 'coordinates': 'B2', 5 | 'description': 'Test Description', 6 | 'height': 200, 7 | 'name': 'Test Name', 8 | 'offsetX': 30, 9 | 'offsetY': 20, 10 | 'resizeProportional': false, 11 | 'rotation': 45, 12 | 'width': 300, 13 | 'shadow': { 14 | 'alignment': 'ctr', 15 | 'alpha': 100, 16 | 'blurRadius': 11, 17 | 'color': '0000cc', 18 | 'direction': 30, 19 | 'distance': 4, 20 | 'visible': true 21 | } 22 | } %} 23 | {% endxlssheet %} 24 | {% endxlsdocument %} -------------------------------------------------------------------------------- /Tests/Resources/views/drawingSimple.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument %} 2 | {% xlssheet 'Test' %} 3 | {% xlsdrawing 'http://www.gravatar.com/avatar/0d9079a1311d9f89b0b28b13cea56a70?s=100' %} 4 | {% endxlssheet %} 5 | {% endxlsdocument %} -------------------------------------------------------------------------------- /Tests/Resources/views/headerFooterComplex.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument %} 2 | {% xlssheet 'Test' %} 3 | {% xlsheader 'firstHeader' %} 4 | {% xlsleft %}firstHeader left{% endxlsleft %} 5 | {% xlscenter %}firstHeader center{% endxlscenter %} 6 | {% xlsright %}firstHeader right{% endxlsright %} 7 | {% endxlsheader %} 8 | {% xlsheader 'evenHeader' %} 9 | {% xlsleft %}evenHeader left{% endxlsleft %} 10 | {% xlscenter %}evenHeader center{% endxlscenter %} 11 | {% xlsright %}evenHeader right{% endxlsright %} 12 | {% endxlsheader %} 13 | {% xlsheader 'oddHeader' %} 14 | {% xlsleft %}oddHeader left{% endxlsleft %} 15 | {% xlscenter %}oddHeader center{% endxlscenter %} 16 | {% xlsright %}oddHeader right{% endxlsright %} 17 | {% endxlsheader %} 18 | {% xlsfooter 'firstFooter' %} 19 | {% xlsleft %}firstFooter left{% endxlsleft %} 20 | {% xlscenter %}firstFooter center{% endxlscenter %} 21 | {% xlsright %}firstFooter right{% endxlsright %} 22 | {% endxlsfooter %} 23 | {% xlsfooter 'evenFooter' %} 24 | {% xlsleft %}evenFooter left{% endxlsleft %} 25 | {% xlscenter %}evenFooter center{% endxlscenter %} 26 | {% xlsright %}evenFooter right{% endxlsright %} 27 | {% endxlsfooter %} 28 | {% xlsfooter 'oddFooter' %} 29 | {% xlsleft %}oddFooter left{% endxlsleft %} 30 | {% xlscenter %}oddFooter center{% endxlscenter %} 31 | {% xlsright %}oddFooter right{% endxlsright %} 32 | {% endxlsfooter %} 33 | {% endxlssheet %} 34 | {% endxlsdocument %} -------------------------------------------------------------------------------- /Tests/Resources/views/headerFooterDrawing.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument %} 2 | {% xlssheet 'Test' %} 3 | {% xlsheader %} 4 | {% xlsleft %} 5 | {% xlsdrawing 'http://www.gravatar.com/avatar/0d9079a1311d9f89b0b28b13cea56a70?s=40' %} 6 | {% endxlsleft %} 7 | {% xlscenter %}Header{% endxlscenter %} 8 | {% endxlsheader %} 9 | {% xlsfooter %} 10 | {% xlsleft %}Footer{% endxlsleft %} 11 | {% xlsright %} 12 | {% xlsdrawing 'http://www.gravatar.com/avatar/0d9079a1311d9f89b0b28b13cea56a70?s=20' %} 13 | {% endxlsright %} 14 | {% endxlsfooter %} 15 | {% endxlssheet %} 16 | {% endxlsdocument %} -------------------------------------------------------------------------------- /Tests/Resources/views/headerFooterProperties.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument %} 2 | {% xlssheet 'Test' %} 3 | {% xlsheader { 4 | 'scaleWithDocument': false, 5 | 'alignWithMargins': true 6 | } %} 7 | {% xlscenter %}Header{% endxlscenter %} 8 | {% endxlsheader %} 9 | {% xlsfooter { 10 | 'scaleWithDocument': false, 11 | 'alignWithMargins': false 12 | } %} 13 | {% xlscenter %}Footer{% endxlscenter %} 14 | {% endxlsfooter %} 15 | {% endxlssheet %} 16 | {% endxlsdocument %} -------------------------------------------------------------------------------- /Tests/Resources/views/include.twig: -------------------------------------------------------------------------------- 1 | {% include 'includeDocument.twig' %} 2 | -------------------------------------------------------------------------------- /Tests/Resources/views/includeCell.twig: -------------------------------------------------------------------------------- 1 | {% xlsinclude %} 2 | {% xlscell %}World1{% endxlscell %} 3 | {% endxlsinclude %} 4 | -------------------------------------------------------------------------------- /Tests/Resources/views/includeContent.twig: -------------------------------------------------------------------------------- 1 | Hello1 2 | -------------------------------------------------------------------------------- /Tests/Resources/views/includeDocument.twig: -------------------------------------------------------------------------------- 1 | {% xlsinclude %} 2 | {% xlsdocument %} 3 | {% xlssheet 'Test' %} 4 | {% xlsrow %} 5 | {% xlscell %}{% include 'includeContent.twig' %}{% endxlscell %} 6 | {% include 'includeCell.twig' %} 7 | {% endxlsrow %} 8 | {% include 'includeRow.twig' %} 9 | {% endxlssheet %} 10 | {% include 'includeSheet.twig' %} 11 | {% endxlsdocument %} 12 | {% endxlsinclude %} 13 | -------------------------------------------------------------------------------- /Tests/Resources/views/includeRow.twig: -------------------------------------------------------------------------------- 1 | {% xlsinclude %} 2 | {% xlsrow %} 3 | {% xlscell %}Hello2{% endxlscell %} 4 | {% xlscell %}World2{% endxlscell %} 5 | {% endxlsrow %} 6 | {% endxlsinclude %} 7 | -------------------------------------------------------------------------------- /Tests/Resources/views/includeSheet.twig: -------------------------------------------------------------------------------- 1 | {% xlsinclude %} 2 | {% xlssheet 'Test2' %} 3 | {% xlsrow %} 4 | {% xlscell %}Hello3{% endxlscell %} 5 | {% xlscell %}World3{% endxlscell %} 6 | {% endxlsrow %} 7 | {% endxlssheet %} 8 | {% endxlsinclude %} 9 | -------------------------------------------------------------------------------- /Tests/Resources/views/macro.twig: -------------------------------------------------------------------------------- 1 | {% import 'macroImport.twig' as macros %} 2 | {% xlsdocument %} 3 | {% xlssheet 'Test' %} 4 | {% xlsrow %} 5 | {% xlscell %}{{ macros.content('Hello1') }}{% endxlscell %} 6 | {{ macros.cell('World1') }} 7 | {% endxlsrow %} 8 | {{ macros.row('Hello2', 'World2') }} 9 | {% endxlssheet %} 10 | {{ macros.sheet('Test2', 'Hello3', 'World3') }} 11 | {{ macros.sheet2('Test3', 'Hello4', 'World4') }} 12 | {% endxlsdocument %} 13 | -------------------------------------------------------------------------------- /Tests/Resources/views/macroError.twig: -------------------------------------------------------------------------------- 1 | {% macro cell(a) %} 2 | {% xlscell %}{{ a }}{% endxlscell %} 3 | {% endmacro %} 4 | -------------------------------------------------------------------------------- /Tests/Resources/views/macroImport.twig: -------------------------------------------------------------------------------- 1 | {% xlsmacro cell(a) %} 2 | {% xlscell %}{{ a }}{% endxlscell %} 3 | {% endxlsmacro %} 4 | 5 | {% xlsmacro content(a) %} 6 | {{ a }} 7 | {% endxlsmacro %} 8 | 9 | {% xlsmacro row(a, b) %} 10 | {% xlsrow %} 11 | {% xlscell %}{{ a }}{% endxlscell %} 12 | {% xlscell %}{{ b }}{% endxlscell %} 13 | {% endxlsrow %} 14 | {% endxlsmacro %} 15 | 16 | {% xlsmacro sheet(a, b, c) %} 17 | {% xlssheet a %} 18 | {% xlsrow %} 19 | {% xlscell %}{{ b }}{% endxlscell %} 20 | {% xlscell %}{{ c }}{% endxlscell %} 21 | {% endxlsrow %} 22 | {% endxlssheet %} 23 | {% endxlsmacro %} 24 | 25 | {% xlsmacro sheet2(a, b, c) %} 26 | {% from _self import cell %} 27 | {% xlssheet a %} 28 | {% xlsrow %} 29 | {{ cell(b) }} 30 | {{ cell(c) }} 31 | {% endxlsrow %} 32 | {% endxlssheet %} 33 | {% endxlsmacro %} -------------------------------------------------------------------------------- /Tests/Resources/views/rowIndex.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument %} 2 | {% xlssheet 'Test' %} 3 | {% xlsrow %} 4 | {% xlscell %}Foo{% endxlscell %} 5 | {% endxlsrow %} 6 | {% xlsrow 3 %} 7 | {% xlscell %}Bar{% endxlscell %} 8 | {% endxlsrow %} 9 | {% xlsrow 3 %} 10 | {% xlscell %}Lorem{% endxlscell %} 11 | {% endxlsrow %} 12 | {% xlsrow %} 13 | {% xlscell %}Ipsum{% endxlscell %} 14 | {% endxlsrow %} 15 | {% xlsrow 2 %} 16 | {% xlscell %}Hello{% endxlscell %} 17 | {% endxlsrow %} 18 | {% xlsrow 5 %} 19 | {% xlscell %}World{% endxlscell %} 20 | {% endxlsrow %} 21 | {% endxlssheet %} 22 | {% endxlsdocument %} -------------------------------------------------------------------------------- /Tests/Resources/views/sheetComplex.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument %} 2 | {% xlssheet 'Test 1' %} 3 | {% xlsrow %} 4 | {% xlscell %}Foo{% endxlscell %} 5 | {% endxlsrow %} 6 | {% endxlssheet %} 7 | {% xlssheet 'Test 2' %} 8 | {% xlsrow %} 9 | {% xlscell %}Hello World{% endxlscell %} 10 | {% endxlsrow %} 11 | {% endxlssheet %} 12 | {% xlssheet 'Test 1' %} 13 | {% xlsrow %} 14 | {% xlscell 1 %}Bar{% endxlscell %} 15 | {% endxlsrow %} 16 | {% endxlssheet %} 17 | {% endxlsdocument %} -------------------------------------------------------------------------------- /Tests/Resources/views/sheetError.twig: -------------------------------------------------------------------------------- 1 | {% xlssheet 'Test' %} 2 | {% xlsdocument %} 3 | {% xlsrow %} 4 | {% xlscell %}Foo{% endxlscell %} 5 | {% xlscell %}Bar{% endxlscell %} 6 | {% endxlsrow %} 7 | {% endxlsdocument %} 8 | {% endxlssheet %} 9 | -------------------------------------------------------------------------------- /Tests/Resources/views/sheetProperties.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument %} 2 | {% xlssheet 'Test' { 3 | 'autoFilter': 'A1:B1', 4 | 'columnDimension': { 5 | 'default': { 6 | 'autoSize': true, 7 | 'collapsed': false, 8 | 'outlineLevel': 0, 9 | 'visible': true, 10 | 'width': -1, 11 | 'xfIndex': 0 12 | }, 13 | 'D': { 14 | 'autoSize': false, 15 | 'collapsed': true, 16 | 'outlineLevel': 1, 17 | 'visible': false, 18 | 'width': 200, 19 | 'xfIndex': 0 20 | } 21 | }, 22 | 'pageMargins': { 23 | 'top': 1, 24 | 'bottom': 1, 25 | 'left': 0.75, 26 | 'right': 0.75, 27 | 'header': 0.5, 28 | 'footer': 0.5 29 | }, 30 | 'pageSetup': { 31 | 'fitToHeight': 1, 32 | 'fitToPage': false, 33 | 'fitToWidth': 1, 34 | 'horizontalCentered': false, 35 | 'orientation': 'landscape', 36 | 'paperSize': 9, 37 | 'printArea': 'A1:B1', 38 | 'scale': 100, 39 | 'verticalCentered': false 40 | }, 41 | 'protection': { 42 | 'autoFilter': true, 43 | 'deleteColumns': true, 44 | 'deleteRows': true, 45 | 'formatCells': true, 46 | 'formatColumns': true, 47 | 'formatRows': true, 48 | 'insertColumns': true, 49 | 'insertHyperlinks': true, 50 | 'insertRows': true, 51 | 'objects': true, 52 | 'password': 'testpassword', 53 | 'pivotTables': true, 54 | 'scenarios': true, 55 | 'selectLockedCells': true, 56 | 'selectUnlockedCells': true, 57 | 'sheet': true, 58 | 'sort': true 59 | }, 60 | 'printGridlines': true, 61 | 'rightToLeft': true, 62 | 'rowDimension': { 63 | 'default': { 64 | 'collapsed': false, 65 | 'outlineLevel': 0, 66 | 'rowHeight': -1, 67 | 'visible': true, 68 | 'xfIndex': 0, 69 | 'zeroHeight': false 70 | }, 71 | '2': { 72 | 'collapsed': true, 73 | 'outlineLevel': 1, 74 | 'rowHeight': 30, 75 | 'visible': false, 76 | 'xfIndex': 0, 77 | 'zeroHeight': true 78 | } 79 | }, 80 | 'showGridlines': false, 81 | 'tabColor': 'c0c0c0', 82 | 'zoomScale': 75 83 | } %} 84 | {% endxlssheet %} 85 | {% endxlsdocument %} 86 | -------------------------------------------------------------------------------- /Tests/Resources/views/sheetState.twig: -------------------------------------------------------------------------------- 1 | {% xlsdocument %} 2 | {% xlssheet 'Test 1' { 'sheetState': 'veryHidden' } %} 3 | {% xlsrow %} 4 | {% xlscell %}Foo{% endxlscell %} 5 | {% endxlsrow %} 6 | {% endxlssheet %} 7 | {% xlssheet 'Test 2' %} 8 | {% xlsrow %} 9 | {% xlscell %}Hello World{% endxlscell %} 10 | {% endxlsrow %} 11 | {% endxlssheet %} 12 | {% endxlsdocument %} -------------------------------------------------------------------------------- /Tests/Twig/AbstractTwigTest.php: -------------------------------------------------------------------------------- 1 | setRequestFormat($format); 55 | 56 | $requestStack = new RequestStack(); 57 | $requestStack->push($request); 58 | 59 | $appVariable = new AppVariable(); 60 | $appVariable->setRequestStack($requestStack); 61 | 62 | // generate source from template 63 | $source = static::$environment->loadTemplate($templateName . '.twig')->render(['app' => $appVariable]); 64 | 65 | // create paths 66 | $tempDirPath = __DIR__ . static::$TEMP_PATH; 67 | $tempFilePath = $tempDirPath . $templateName . '.' . $format; 68 | 69 | // save source 70 | static::$fileSystem->dumpFile($tempFilePath, $source); 71 | 72 | // load source 73 | switch ($format) { 74 | case 'ods': 75 | $reader = new PHPExcel_Reader_OOCalc(); 76 | break; 77 | case 'xls': 78 | $reader = new PHPExcel_Reader_Excel5(); 79 | break; 80 | case 'xlsx': 81 | $reader = new PHPExcel_Reader_Excel2007(); 82 | break; 83 | case 'pdf': 84 | case 'csv': 85 | return $tempFilePath; 86 | default: 87 | throw new InvalidArgumentException(); 88 | } 89 | 90 | return $reader->load($tempFilePath); 91 | } 92 | 93 | // 94 | // PhpUnit 95 | // 96 | 97 | /** 98 | * @return array 99 | */ 100 | abstract public function formatProvider(); 101 | 102 | /** 103 | * {@inheritdoc} 104 | * @throws \Twig_Error_Loader 105 | */ 106 | public static function setUpBeforeClass() 107 | { 108 | static::$fileSystem = new Filesystem(); 109 | 110 | $twigFileSystem = new Twig_Loader_Filesystem([__DIR__ . static::$RESOURCE_PATH]); 111 | $twigFileSystem->addPath( __DIR__ . static::$TEMPLATE_PATH, 'templates'); 112 | 113 | static::$environment = new Twig_Environment($twigFileSystem, ['strict_variables' => true]); 114 | static::$environment->addExtension(new TwigExcelExtension()); 115 | static::$environment->setCache(__DIR__ . static::$TEMP_PATH); 116 | } 117 | 118 | /** 119 | * {@inheritdoc} 120 | * @throws \Symfony\Component\Filesystem\Exception\IOException 121 | */ 122 | public static function tearDownAfterClass() 123 | { 124 | if (in_array(getenv('DELETE_TEMP_FILES'), ['true', '1', 1, true], true)) { 125 | static::$fileSystem->remove(__DIR__ . static::$TEMP_PATH); 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /Tests/Twig/CsvTwigTest.php: -------------------------------------------------------------------------------- 1 | getDocument('documentSimple', $format); 38 | 39 | static::assertFileExists($path, 'File does not exist'); 40 | static::assertGreaterThan(0, filesize($path), 'File is empty'); 41 | static::assertEquals("\"Foo\",\"Bar\"".PHP_EOL."\"Hello\",\"World\"".PHP_EOL, file_get_contents($path), 'Unexpected content'); 42 | } 43 | 44 | /** 45 | * @param string $format 46 | * @throws \Exception 47 | * 48 | * @dataProvider formatProvider 49 | */ 50 | public function testDocumentTemplate($format) 51 | { 52 | $path = $this->getDocument('documentTemplate.csv', $format); 53 | 54 | static::assertFileExists($path, 'File does not exist'); 55 | static::assertGreaterThan(0, filesize($path), 'File is empty'); 56 | static::assertEquals("\"Hello2\",\"World\"".PHP_EOL."\"Foo\",\"Bar2\"".PHP_EOL, file_get_contents($path), 'Unexpected content'); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Tests/Twig/ErrorTwigTest.php: -------------------------------------------------------------------------------- 1 | setExpectedException( 38 | '\Twig_Error_Syntax', 39 | 'Block tags do not work together with Twig tags provided by TwigExcelBundle. Please use \'xlsblock\' instead in "blockError.twig".' 40 | ); 41 | $this->getDocument('blockError', $format); 42 | } 43 | 44 | /** 45 | * @param string $format 46 | * @throws \Exception 47 | * 48 | * @dataProvider formatProvider 49 | */ 50 | public function testDocumentError($format) 51 | { 52 | $this->setExpectedException( 53 | '\Twig_Error_Syntax', 54 | 'Node "MewesK\TwigExcelBundle\Twig\Node\XlsDocumentNode" is not allowed inside of Node "MewesK\TwigExcelBundle\Twig\Node\XlsSheetNode"' 55 | ); 56 | $this->getDocument('documentError', $format); 57 | } 58 | 59 | /** 60 | * @param string $format 61 | * @throws \Exception 62 | * 63 | * @dataProvider formatProvider 64 | */ 65 | public function testMacroError($format) 66 | { 67 | $this->setExpectedException( 68 | '\Twig_Error_Syntax', 69 | 'Macro tags do not work together with Twig tags provided by TwigExcelBundle. Please use \'xlsmacro\' instead in "macroError.twig".' 70 | ); 71 | $this->getDocument('macroError', $format); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Tests/Twig/PdfTwigTest.php: -------------------------------------------------------------------------------- 1 | =')) { 40 | return; 41 | } 42 | 43 | $path = $this->getDocument('cellProperties', $format); 44 | 45 | static::assertFileExists($path, 'File does not exist'); 46 | static::assertGreaterThan(0, filesize($path), 'File is empty'); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Tests/Twig/XlsTwigTest.php: -------------------------------------------------------------------------------- 1 | getDocument('cellIndex', $format); 38 | static::assertNotNull($document, 'Document does not exist'); 39 | 40 | $sheet = $document->getSheetByName('Test'); 41 | static::assertNotNull($sheet, 'Sheet does not exist'); 42 | 43 | static::assertEquals('A2:C2', $sheet->getCell('A2')->getMergeRange(), 'Unexpected value in mergeRange'); 44 | static::assertEquals('A3:C3', $sheet->getCell('A3')->getMergeRange(), 'Unexpected value in mergeRange'); 45 | static::assertEquals('A4:A6', $sheet->getCell('A4')->getMergeRange(), 'Unexpected value in mergeRange'); 46 | } 47 | 48 | /** 49 | * @param string $format 50 | * @throws \Exception 51 | * 52 | * @dataProvider formatProvider 53 | */ 54 | public function testCellProperties($format) 55 | { 56 | $document = $this->getDocument('cellProperties', $format); 57 | $sheet = $document->getSheetByName('Test'); 58 | $cell = $sheet->getCell('A1'); 59 | $style = $cell->getStyle(); 60 | 61 | $breaks = $sheet->getBreaks(); 62 | static::assertCount(1, $breaks, 'Unexpected break count'); 63 | static::assertArrayHasKey('A1', $breaks, 'Break does not exist'); 64 | 65 | $break = $breaks['A1']; 66 | static::assertNotNull($break, 'Break is null'); 67 | 68 | $font = $style->getFont(); 69 | static::assertNotNull($font, 'Font does not exist'); 70 | static::assertEquals(18, $font->getSize(), 'Unexpected value in size'); 71 | 72 | static::assertEquals('http://example.com/', $cell->getHyperlink()->getUrl(), 'Unexpected value in url'); 73 | } 74 | 75 | /** 76 | * The following attributes are not supported by the readers and therefore cannot be tested: 77 | * $security->getLockRevision() -> true 78 | * $security->getLockStructure() -> true 79 | * $security->getLockWindows() -> true 80 | * $security->getRevisionsPassword() -> 'test' 81 | * $security->getWorkbookPassword() -> 'test' 82 | * 83 | * @param string $format 84 | * @throws \Exception 85 | * 86 | * @dataProvider formatProvider 87 | */ 88 | public function testDocumentProperties($format) 89 | { 90 | $document = $this->getDocument('documentProperties', $format); 91 | $properties = $document->getProperties(); 92 | $defaultStyle = $document->getDefaultStyle(); 93 | 94 | static::assertEquals('Test category', $properties->getCategory(), 'Unexpected value in category'); 95 | 96 | $font = $defaultStyle->getFont(); 97 | static::assertNotNull($font, 'Font does not exist'); 98 | static::assertEquals(18, $font->getSize(), 'Unexpected value in size'); 99 | 100 | static::assertEquals('Test keywords', $properties->getKeywords(), 'Unexpected value in keywords'); 101 | static::assertEquals('Test modifier', $properties->getLastModifiedBy(), 'Unexpected value in lastModifiedBy'); 102 | } 103 | 104 | /** 105 | * @param string $format 106 | * @throws \Exception 107 | * 108 | * @dataProvider formatProvider 109 | */ 110 | public function testDrawingProperties($format) 111 | { 112 | $document = $this->getDocument('drawingProperties', $format); 113 | static::assertNotNull($document, 'Document does not exist'); 114 | 115 | $sheet = $document->getSheetByName('Test'); 116 | static::assertNotNull($sheet, 'Sheet does not exist'); 117 | 118 | $drawings = $sheet->getDrawingCollection(); 119 | static::assertCount(1, $drawings, 'Unexpected drawing count'); 120 | static::assertArrayHasKey(0, $drawings, 'Drawing does not exist'); 121 | 122 | $drawing = $drawings[0]; 123 | static::assertNotNull($drawing, 'Drawing is null'); 124 | 125 | static::assertEquals('B2', $drawing->getCoordinates(), 'Unexpected value in coordinates'); 126 | static::assertEquals(200, $drawing->getHeight(), 'Unexpected value in height'); 127 | static::assertFalse($drawing->getResizeProportional(), 'Unexpected value in resizeProportional'); 128 | static::assertEquals(300, $drawing->getWidth(), 'Unexpected value in width'); 129 | 130 | $shadow = $drawing->getShadow(); 131 | static::assertNotNull($shadow, 'Shadow is null'); 132 | } 133 | 134 | /** 135 | * @param string $format 136 | * @throws \Exception 137 | * 138 | * @dataProvider formatProvider 139 | */ 140 | public function testDrawingSimple($format) 141 | { 142 | $document = $this->getDocument('drawingSimple', $format); 143 | static::assertNotNull($document, 'Document does not exist'); 144 | 145 | $sheet = $document->getSheetByName('Test'); 146 | static::assertNotNull($sheet, 'Sheet does not exist'); 147 | 148 | $drawings = $sheet->getDrawingCollection(); 149 | static::assertCount(1, $drawings, 'Unexpected drawing count'); 150 | static::assertArrayHasKey(0, $drawings, 'Drawing does not exist'); 151 | 152 | $drawing = $drawings[0]; 153 | static::assertNotNull($drawing, 'Drawing is null'); 154 | static::assertEquals(100, $drawing->getWidth(), 'Unexpected value in width'); 155 | static::assertEquals(100, $drawing->getHeight(), 'Unexpected value in height'); 156 | } 157 | 158 | /** 159 | * @param string $format 160 | * @throws \Exception 161 | * 162 | * @dataProvider formatProvider 163 | */ 164 | public function testHeaderFooterComplex($format) 165 | { 166 | $document = $this->getDocument('headerFooterComplex', $format); 167 | static::assertNotNull($document, 'Document does not exist'); 168 | 169 | $sheet = $document->getSheetByName('Test'); 170 | static::assertNotNull($sheet, 'Sheet does not exist'); 171 | 172 | $headerFooter = $sheet->getHeaderFooter(); 173 | static::assertNotNull($headerFooter, 'HeaderFooter does not exist'); 174 | 175 | static::assertEquals('&LoddHeader left&CoddHeader center&RoddHeader right', $headerFooter->getOddHeader(), 'Unexpected value in oddHeader'); 176 | static::assertEquals('&LoddFooter left&CoddFooter center&RoddFooter right', $headerFooter->getOddFooter(), 'Unexpected value in oddFooter'); 177 | } 178 | 179 | /** 180 | * The following attributes are not supported by the readers and therefore cannot be tested: 181 | * $columnDimension->getAutoSize() -> false 182 | * $columnDimension->getCollapsed() -> true 183 | * $columnDimension->getColumnIndex() -> 1 184 | * $columnDimension->getVisible() -> false 185 | * $defaultColumnDimension->getAutoSize() -> true 186 | * $defaultColumnDimension->getCollapsed() -> false 187 | * $defaultColumnDimension->getColumnIndex() -> 1 188 | * $defaultColumnDimension->getVisible() -> true 189 | * $defaultRowDimension->getCollapsed() -> false 190 | * $defaultRowDimension->getRowIndex() -> 1 191 | * $defaultRowDimension->getVisible() -> true 192 | * $defaultRowDimension->getzeroHeight() -> false 193 | * $rowDimension->getCollapsed() -> true 194 | * $rowDimension->getRowIndex() -> 1 195 | * $rowDimension->getVisible() -> false 196 | * $rowDimension->getzeroHeight() -> true 197 | * $sheet->getShowGridlines() -> false 198 | * 199 | * @param string $format 200 | * @throws \Exception 201 | * 202 | * @dataProvider formatProvider 203 | */ 204 | public function testSheetProperties($format) 205 | { 206 | $document = $this->getDocument('sheetProperties', $format); 207 | $sheet = $document->getSheetByName('Test'); 208 | $columnDimension = $sheet->getColumnDimension('D'); 209 | $pageSetup = $sheet->getPageSetup(); 210 | 211 | static::assertEquals(1, $columnDimension->getOutlineLevel(), 'Unexpected value in outlineLevel'); 212 | static::assertEquals(200, $columnDimension->getWidth(), 'Unexpected value in width'); 213 | 214 | $pageMargins = $sheet->getPageMargins(); 215 | static::assertNotNull($pageMargins, 'PageMargins does not exist'); 216 | static::assertEquals(1, $pageMargins->getTop(), 'Unexpected value in top'); 217 | static::assertEquals(1, $pageMargins->getBottom(), 'Unexpected value in bottom'); 218 | static::assertEquals(0.75, $pageMargins->getLeft(), 'Unexpected value in left'); 219 | static::assertEquals(0.75, $pageMargins->getRight(), 'Unexpected value in right'); 220 | static::assertEquals(0.5, $pageMargins->getHeader(), 'Unexpected value in header'); 221 | static::assertEquals(0.5, $pageMargins->getFooter(), 'Unexpected value in footer'); 222 | 223 | static::assertEquals('landscape', $pageSetup->getOrientation(), 'Unexpected value in orientation'); 224 | static::assertEquals(9, $pageSetup->getPaperSize(), 'Unexpected value in paperSize'); 225 | static::assertEquals('A1:B1', $pageSetup->getPrintArea(), 'Unexpected value in printArea'); 226 | 227 | $protection = $sheet->getProtection(); 228 | static::assertTrue($protection->getAutoFilter(), 'Unexpected value in autoFilter'); 229 | static::assertNotNull($protection, 'Protection does not exist'); 230 | static::assertTrue($protection->getDeleteColumns(), 'Unexpected value in deleteColumns'); 231 | static::assertTrue($protection->getDeleteRows(), 'Unexpected value in deleteRows'); 232 | static::assertTrue($protection->getFormatCells(), 'Unexpected value in formatCells'); 233 | static::assertTrue($protection->getFormatColumns(), 'Unexpected value in formatColumns'); 234 | static::assertTrue($protection->getFormatRows(), 'Unexpected value in formatRows'); 235 | static::assertTrue($protection->getInsertColumns(), 'Unexpected value in insertColumns'); 236 | static::assertTrue($protection->getInsertHyperlinks(), 'Unexpected value in insertHyperlinks'); 237 | static::assertTrue($protection->getInsertRows(), 'Unexpected value in insertRows'); 238 | static::assertTrue($protection->getObjects(), 'Unexpected value in objects'); 239 | static::assertEquals(\PHPExcel_Shared_PasswordHasher::hashPassword('testpassword'), $protection->getPassword(), 'Unexpected value in password'); 240 | static::assertTrue($protection->getPivotTables(), 'Unexpected value in pivotTables'); 241 | static::assertTrue($protection->getScenarios(), 'Unexpected value in scenarios'); 242 | static::assertTrue($protection->getSelectLockedCells(), 'Unexpected value in selectLockedCells'); 243 | static::assertTrue($protection->getSelectUnlockedCells(), 'Unexpected value in selectUnlockedCells'); 244 | static::assertTrue($protection->getSheet(), 'Unexpected value in sheet'); 245 | static::assertTrue($protection->getSort(), 'Unexpected value in sort'); 246 | 247 | static::assertTrue($sheet->getPrintGridlines(), 'Unexpected value in printGridlines'); 248 | static::assertTrue($sheet->getRightToLeft(), 'Unexpected value in rightToLeft'); 249 | static::assertEquals('c0c0c0', strtolower($sheet->getTabColor()->getRGB()), 'Unexpected value in tabColor'); 250 | static::assertEquals(75, $sheet->getSheetView()->getZoomScale(), 'Unexpected value in zoomScale'); 251 | 252 | $rowDimension = $sheet->getRowDimension(2); 253 | static::assertNotNull($rowDimension, 'RowDimension does not exist'); 254 | static::assertEquals(1, $rowDimension->getOutlineLevel(), 'Unexpected value in outlineLevel'); 255 | static::assertEquals(30, $rowDimension->getRowHeight(), 'Unexpected value in rowHeight'); 256 | static::assertEquals(0, $rowDimension->getXfIndex(), 'Unexpected value in xfIndex'); 257 | } 258 | } 259 | -------------------------------------------------------------------------------- /Tests/Twig/XlsxTwigTest.php: -------------------------------------------------------------------------------- 1 | getDocument('cellProperties', $format); 39 | $sheet = $document->getSheetByName('Test'); 40 | $cell = $sheet->getCell('A1'); 41 | $dataValidation = $cell->getDataValidation(); 42 | 43 | static::assertTrue($dataValidation->getAllowBlank(), 'Unexpected value in allowBlank'); 44 | static::assertEquals('Test error', $dataValidation->getError(), 'Unexpected value in error'); 45 | static::assertEquals('information', $dataValidation->getErrorStyle(), 'Unexpected value in errorStyle'); 46 | static::assertEquals('Test errorTitle', $dataValidation->getErrorTitle(), 'Unexpected value in errorTitle'); 47 | static::assertEquals('', $dataValidation->getFormula1(), 'Unexpected value in formula1'); 48 | static::assertEquals('', $dataValidation->getFormula2(), 'Unexpected value in formula2'); 49 | static::assertEquals('', $dataValidation->getOperator(), 'Unexpected value in operator'); 50 | static::assertEquals('Test prompt', $dataValidation->getPrompt(), 'Unexpected value in prompt'); 51 | static::assertEquals('Test promptTitle', $dataValidation->getPromptTitle(), 'Unexpected value in promptTitle'); 52 | static::assertTrue($dataValidation->getShowDropDown(), 'Unexpected value in showDropDown'); 53 | static::assertTrue($dataValidation->getShowErrorMessage(), 'Unexpected value in showErrorMessage'); 54 | static::assertTrue($dataValidation->getShowInputMessage(), 'Unexpected value in showInputMessage'); 55 | static::assertEquals('custom', $dataValidation->getType(), 'Unexpected value in type'); 56 | } 57 | 58 | /** 59 | * The following attributes are not supported by the readers and therefore cannot be tested: 60 | * $security->getLockRevision() -> true 61 | * $security->getLockStructure() -> true 62 | * $security->getLockWindows() -> true 63 | * $security->getRevisionsPassword() -> 'test' 64 | * $security->getWorkbookPassword() -> 'test' 65 | * 66 | * @param string $format 67 | * @throws \Exception 68 | * 69 | * @dataProvider formatProvider 70 | */ 71 | public function testDocumentProperties($format) 72 | { 73 | $document = $this->getDocument('documentProperties', $format); 74 | $properties = $document->getProperties(); 75 | 76 | static::assertEquals('Test company', $properties->getCompany(), 'Unexpected value in company'); 77 | static::assertEquals('Test manager', $properties->getManager(), 'Unexpected value in manager'); 78 | } 79 | 80 | /** 81 | * @param string $format 82 | * @throws \Exception 83 | * 84 | * @dataProvider formatProvider 85 | */ 86 | public function testDocumentTemplate($format) 87 | { 88 | $document = $this->getDocument('documentTemplateAdvanced', $format); 89 | static::assertNotNull($document, 'Document does not exist'); 90 | 91 | $sheet = $document->getSheet(0); 92 | static::assertNotNull($sheet, 'Sheet does not exist'); 93 | 94 | static::assertEquals('Hello2', $sheet->getCell('A1')->getValue(), 'Unexpected value in A1'); 95 | static::assertEquals('World', $sheet->getCell('B1')->getValue(), 'Unexpected value in B1'); 96 | static::assertEquals('Foo', $sheet->getCell('A2')->getValue(), 'Unexpected value in A2'); 97 | static::assertEquals('Bar2', $sheet->getCell('B2')->getValue(), 'Unexpected value in B2'); 98 | 99 | static::assertTrue($sheet->getCell('A1')->getStyle()->getFont()->getBold(), 'Unexpected value in bold'); 100 | static::assertTrue($sheet->getCell('B1')->getStyle()->getFont()->getItalic(), 'Unexpected value in italic'); 101 | static::assertEquals('single', $sheet->getCell('A2')->getStyle()->getFont()->getUnderline(), 'Unexpected value in underline'); 102 | static::assertEquals('FFFF3333', $sheet->getCell('B2')->getStyle()->getFont()->getColor()->getARGB(), 'Unexpected value in color'); 103 | 104 | $headerFooter = $sheet->getHeaderFooter(); 105 | static::assertNotNull($headerFooter, 'HeaderFooter does not exist'); 106 | static::assertContains('Left area header', $headerFooter->getOddHeader(), 'Unexpected value in oddHeader'); 107 | static::assertContains('12Center area header', $headerFooter->getOddHeader(), 'Unexpected value in oddHeader'); 108 | static::assertContains('12Right area header', $headerFooter->getOddHeader(), 'Unexpected value in oddHeader'); 109 | static::assertContains('Left area footer', $headerFooter->getOddFooter(), 'Unexpected value in oddFooter'); 110 | static::assertContains('12Center area footer', $headerFooter->getOddFooter(), 'Unexpected value in oddFooter'); 111 | static::assertContains('12Right area footer', $headerFooter->getOddFooter(), 'Unexpected value in oddFooter'); 112 | 113 | $drawings = $sheet->getDrawingCollection(); 114 | static::assertCount(1, $drawings, 'Not enough drawings exist'); 115 | 116 | $drawing = $drawings[0]; 117 | static::assertEquals(196, $drawing->getWidth(), 'Unexpected value in width'); 118 | static::assertEquals(187, $drawing->getHeight(), 'Unexpected value in height'); 119 | } 120 | 121 | /** 122 | * @param string $format 123 | * @throws \Exception 124 | * 125 | * @dataProvider formatProvider 126 | */ 127 | public function testDrawingProperties($format) 128 | { 129 | $document = $this->getDocument('drawingProperties', $format); 130 | static::assertNotNull($document, 'Document does not exist'); 131 | 132 | $sheet = $document->getSheetByName('Test'); 133 | static::assertNotNull($sheet, 'Sheet does not exist'); 134 | 135 | $drawings = $sheet->getDrawingCollection(); 136 | static::assertCount(1, $drawings, 'Not enough drawings exist'); 137 | 138 | $drawing = $drawings[0]; 139 | static::assertEquals('Test Description', $drawing->getDescription(), 'Unexpected value in description'); 140 | static::assertEquals('Test Name', $drawing->getName(), 'Unexpected value in name'); 141 | static::assertEquals(30, $drawing->getOffsetX(), 'Unexpected value in offsetX'); 142 | static::assertEquals(20, $drawing->getOffsetY(), 'Unexpected value in offsetY'); 143 | static::assertEquals(45, $drawing->getRotation(), 'Unexpected value in rotation'); 144 | 145 | $shadow = $drawing->getShadow(); 146 | static::assertEquals('ctr', $shadow->getAlignment(), 'Unexpected value in alignment'); 147 | static::assertEquals(100, $shadow->getAlpha(), 'Unexpected value in alpha'); 148 | static::assertEquals(11, $shadow->getBlurRadius(), 'Unexpected value in blurRadius'); 149 | static::assertEquals('0000cc', $shadow->getColor()->getRGB(), 'Unexpected value in color'); 150 | static::assertEquals(30, $shadow->getDirection(), 'Unexpected value in direction'); 151 | static::assertEquals(4, $shadow->getDistance(), 'Unexpected value in distance'); 152 | static::assertTrue($shadow->getVisible(), 'Unexpected value in visible'); 153 | } 154 | 155 | /** 156 | * @param string $format 157 | * @throws \Exception 158 | * 159 | * @dataProvider formatProvider 160 | */ 161 | public function testHeaderFooterComplex($format) 162 | { 163 | $document = $this->getDocument('headerFooterComplex', $format); 164 | static::assertNotNull($document, 'Document does not exist'); 165 | 166 | $sheet = $document->getSheetByName('Test'); 167 | static::assertNotNull($sheet, 'Sheet does not exist'); 168 | 169 | $headerFooter = $sheet->getHeaderFooter(); 170 | static::assertNotNull($headerFooter, 'HeaderFooter does not exist'); 171 | static::assertEquals('&LfirstHeader left&CfirstHeader center&RfirstHeader right', 172 | $headerFooter->getFirstHeader(), 173 | 'Unexpected value in firstHeader'); 174 | static::assertEquals('&LevenHeader left&CevenHeader center&RevenHeader right', 175 | $headerFooter->getEvenHeader(), 176 | 'Unexpected value in evenHeader'); 177 | static::assertEquals('&LfirstFooter left&CfirstFooter center&RfirstFooter right', 178 | $headerFooter->getFirstFooter(), 179 | 'Unexpected value in firstFooter'); 180 | static::assertEquals('&LevenFooter left&CevenFooter center&RevenFooter right', 181 | $headerFooter->getEvenFooter(), 182 | 'Unexpected value in evenFooter'); 183 | } 184 | 185 | /** 186 | * @param string $format 187 | * @throws \Exception 188 | * 189 | * @dataProvider formatProvider 190 | */ 191 | public function testHeaderFooterDrawing($format) 192 | { 193 | $document = $this->getDocument('headerFooterDrawing', $format); 194 | static::assertNotNull($document, 'Document does not exist'); 195 | 196 | $sheet = $document->getSheetByName('Test'); 197 | static::assertNotNull($sheet, 'Sheet does not exist'); 198 | 199 | $headerFooter = $sheet->getHeaderFooter(); 200 | static::assertNotNull($headerFooter, 'HeaderFooter does not exist'); 201 | static::assertEquals('&L&G&CHeader', $headerFooter->getFirstHeader(), 'Unexpected value in firstHeader'); 202 | static::assertEquals('&L&G&CHeader', $headerFooter->getEvenHeader(), 'Unexpected value in evenHeader'); 203 | static::assertEquals('&L&G&CHeader', $headerFooter->getOddHeader(), 'Unexpected value in oddHeader'); 204 | static::assertEquals('&LFooter&R&G', $headerFooter->getFirstFooter(), 'Unexpected value in firstFooter'); 205 | static::assertEquals('&LFooter&R&G', $headerFooter->getEvenFooter(), 'Unexpected value in evenFooter'); 206 | static::assertEquals('&LFooter&R&G', $headerFooter->getOddFooter(), 'Unexpected value in oddFooter'); 207 | 208 | $drawings = $headerFooter->getImages(); 209 | static::assertCount(2, $drawings, 'Sheet has not exactly 2 drawings'); 210 | static::assertArrayHasKey('LH', $drawings, 'Header drawing does not exist'); 211 | static::assertArrayHasKey('RF', $drawings, 'Footer drawing does not exist'); 212 | 213 | $drawing = $drawings['LH']; 214 | static::assertNotNull($drawing, 'Header drawing is null'); 215 | static::assertEquals(40, $drawing->getWidth(), 'Unexpected value in width'); 216 | static::assertEquals(40, $drawing->getHeight(), 'Unexpected value in height'); 217 | 218 | $drawing = $drawings['RF']; 219 | static::assertNotNull($drawing, 'Footer drawing is null'); 220 | static::assertEquals(20, $drawing->getWidth(), 'Unexpected value in width'); 221 | static::assertEquals(20, $drawing->getHeight(), 'Unexpected value in height'); 222 | } 223 | 224 | /** 225 | * @param string $format 226 | * @throws \Exception 227 | * 228 | * @dataProvider formatProvider 229 | */ 230 | public function testHeaderFooterProperties($format) 231 | { 232 | $document = $this->getDocument('headerFooterProperties', $format); 233 | static::assertNotNull($document, 'Document does not exist'); 234 | 235 | $sheet = $document->getSheetByName('Test'); 236 | static::assertNotNull($sheet, 'Sheet does not exist'); 237 | 238 | $headerFooter = $sheet->getHeaderFooter(); 239 | static::assertNotNull($headerFooter, 'HeaderFooter does not exist'); 240 | 241 | static::assertEquals('&CHeader', $headerFooter->getFirstHeader(), 'Unexpected value in firstHeader'); 242 | static::assertEquals('&CHeader', $headerFooter->getEvenHeader(), 'Unexpected value in evenHeader'); 243 | static::assertEquals('&CHeader', $headerFooter->getOddHeader(), 'Unexpected value in oddHeader'); 244 | static::assertEquals('&CFooter', $headerFooter->getFirstFooter(), 'Unexpected value in firstFooter'); 245 | static::assertEquals('&CFooter', $headerFooter->getEvenFooter(), 'Unexpected value in evenFooter'); 246 | static::assertEquals('&CFooter', $headerFooter->getOddFooter(), 'Unexpected value in oddFooter'); 247 | 248 | static::assertFalse($headerFooter->getAlignWithMargins(), 'Unexpected value in alignWithMargins'); 249 | static::assertFalse($headerFooter->getScaleWithDocument(), 'Unexpected value in scaleWithDocument'); 250 | } 251 | 252 | /** 253 | * @param string $format 254 | * @throws \Exception 255 | * 256 | * @dataProvider formatProvider 257 | */ 258 | public function testSheetProperties($format) 259 | { 260 | $document = $this->getDocument('sheetProperties', $format); 261 | static::assertNotNull($document, 'Document does not exist'); 262 | 263 | $sheet = $document->getSheetByName('Test'); 264 | static::assertNotNull($sheet, 'Sheet does not exist'); 265 | static::assertEquals('A1:B1', $sheet->getAutoFilter()->getRange(), 'Unexpected value in autoFilter'); 266 | } 267 | } 268 | -------------------------------------------------------------------------------- /Twig/Node/SyntaxAwareNodeInterface.php: -------------------------------------------------------------------------------- 1 | $index, 'properties' => $properties, 'body' => $body], [], $line, $tag); 26 | } 27 | 28 | /** 29 | * @param Twig_Compiler $compiler 30 | */ 31 | public function compile(Twig_Compiler $compiler) 32 | { 33 | $compiler->addDebugInfo($this) 34 | ->write('$context[\'phpExcel\']->setCellIndex(') 35 | ->subcompile($this->getNode('index')) 36 | ->raw(');' . PHP_EOL) 37 | ->write("ob_start();\n") 38 | ->subcompile($this->getNode('body')) 39 | ->write('$cellValue = trim(ob_get_clean());' . PHP_EOL) 40 | ->write('$cellProperties = ') 41 | ->subcompile($this->getNode('properties')) 42 | ->raw(';' . PHP_EOL) 43 | ->write('$context[\'phpExcel\']->startCell($cellValue, $cellProperties);' . PHP_EOL) 44 | ->write('unset($cellIndex, $cellValue, $cellProperties);' . PHP_EOL) 45 | ->write('$context[\'phpExcel\']->endCell();' . PHP_EOL); 46 | } 47 | 48 | /** 49 | * @return string[] 50 | */ 51 | public function getAllowedParents() 52 | { 53 | return [ 54 | 'MewesK\TwigExcelBundle\Twig\Node\XlsRowNode' 55 | ]; 56 | } 57 | 58 | /** 59 | * @return bool 60 | */ 61 | public function canContainText() 62 | { 63 | return true; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Twig/Node/XlsCenterNode.php: -------------------------------------------------------------------------------- 1 | $body], [], $line, $tag); 23 | } 24 | 25 | /** 26 | * @param Twig_Compiler $compiler 27 | */ 28 | public function compile(Twig_Compiler $compiler) 29 | { 30 | $compiler->addDebugInfo($this) 31 | ->write('$context[\'phpExcel\']->startAlignment(\'center\');' . PHP_EOL) 32 | ->write("ob_start();\n") 33 | ->subcompile($this->getNode('body')) 34 | ->write('$centerValue = trim(ob_get_clean());' . PHP_EOL) 35 | ->write('$context[\'phpExcel\']->endAlignment($centerValue);' . PHP_EOL) 36 | ->write('unset($centerValue);' . PHP_EOL); 37 | } 38 | 39 | /** 40 | * @return string[] 41 | */ 42 | public function getAllowedParents() 43 | { 44 | return [ 45 | 'MewesK\TwigExcelBundle\Twig\Node\XlsFooterNode', 46 | 'MewesK\TwigExcelBundle\Twig\Node\XlsHeaderNode' 47 | ]; 48 | } 49 | 50 | /** 51 | * @return bool 52 | */ 53 | public function canContainText() 54 | { 55 | return true; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Twig/Node/XlsDocumentNode.php: -------------------------------------------------------------------------------- 1 | $properties, 'body' => $body], [], $line, $tag); 36 | $this->preCalculateFormulas = $preCalculateFormulas; 37 | $this->diskCachingDirectory = $diskCachingDirectory; 38 | } 39 | 40 | /** 41 | * @param Twig_Compiler $compiler 42 | */ 43 | public function compile(Twig_Compiler $compiler) 44 | { 45 | $compiler->addDebugInfo($this) 46 | ->write('$documentProperties = ') 47 | ->subcompile($this->getNode('properties')) 48 | ->raw(';' . PHP_EOL) 49 | ->write('$context[\'phpExcel\'] = new MewesK\TwigExcelBundle\Wrapper\PhpExcelWrapper($context, $this->env);' . PHP_EOL) 50 | ->write('$context[\'phpExcel\']->startDocument($documentProperties);' . PHP_EOL) 51 | ->write('unset($documentProperties);' . PHP_EOL) 52 | ->subcompile($this->getNode('body')) 53 | ->addDebugInfo($this) 54 | ->write('$context[\'phpExcel\']->endDocument(' . 55 | ($this->preCalculateFormulas ? 'true' : 'false') . ', ' . 56 | ($this->diskCachingDirectory ? '\'' . $this->diskCachingDirectory . '\'' : 'null') . ');' . PHP_EOL) 57 | ->write('unset($context[\'phpExcel\']);' . PHP_EOL); 58 | } 59 | 60 | /** 61 | * @return string[] 62 | */ 63 | public function getAllowedParents() 64 | { 65 | return []; 66 | } 67 | 68 | /** 69 | * @return bool 70 | */ 71 | public function canContainText() 72 | { 73 | return false; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Twig/Node/XlsDrawingNode.php: -------------------------------------------------------------------------------- 1 | $path, 'properties' => $properties], [], $line, $tag); 25 | } 26 | 27 | /** 28 | * @param Twig_Compiler $compiler 29 | */ 30 | public function compile(Twig_Compiler $compiler) 31 | { 32 | $compiler->addDebugInfo($this) 33 | ->write('$drawingPath = ') 34 | ->subcompile($this->getNode('path')) 35 | ->raw(';' . PHP_EOL) 36 | ->write('$drawingProperties = ') 37 | ->subcompile($this->getNode('properties')) 38 | ->raw(';' . PHP_EOL) 39 | ->write('$context[\'phpExcel\']->startDrawing($drawingPath, $drawingProperties);' . PHP_EOL) 40 | ->write('unset($drawingPath, $drawingProperties);' . PHP_EOL) 41 | ->write('$context[\'phpExcel\']->endDrawing();' . PHP_EOL); 42 | } 43 | 44 | /** 45 | * @return string[] 46 | */ 47 | public function getAllowedParents() 48 | { 49 | return [ 50 | 'MewesK\TwigExcelBundle\Twig\Node\XlsSheetNode', 51 | 'MewesK\TwigExcelBundle\Twig\Node\XlsLeftNode', 52 | 'MewesK\TwigExcelBundle\Twig\Node\XlsCenterNode', 53 | 'MewesK\TwigExcelBundle\Twig\Node\XlsRightNode' 54 | ]; 55 | } 56 | 57 | /** 58 | * @return bool 59 | */ 60 | public function canContainText() 61 | { 62 | return false; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Twig/Node/XlsFooterNode.php: -------------------------------------------------------------------------------- 1 | $type, 'properties' => $properties, 'body' => $body], [], $line, $tag); 26 | } 27 | 28 | /** 29 | * @param Twig_Compiler $compiler 30 | */ 31 | public function compile(Twig_Compiler $compiler) 32 | { 33 | $compiler->addDebugInfo($this) 34 | ->write('$footerType = ') 35 | ->subcompile($this->getNode('type')) 36 | ->raw(';' . PHP_EOL) 37 | ->write('$footerType = $footerType ? $footerType : \'footer\';' . PHP_EOL) 38 | ->write('$footerProperties = ') 39 | ->subcompile($this->getNode('properties')) 40 | ->raw(';' . PHP_EOL) 41 | ->write('$context[\'phpExcel\']->startHeaderFooter($footerType, $footerProperties);' . PHP_EOL) 42 | ->write('unset($footerType, $footerProperties);' . PHP_EOL) 43 | ->subcompile($this->getNode('body')) 44 | ->addDebugInfo($this) 45 | ->write('$context[\'phpExcel\']->endHeaderFooter();' . PHP_EOL); 46 | } 47 | 48 | /** 49 | * @return string[] 50 | */ 51 | public function getAllowedParents() 52 | { 53 | return [ 54 | 'MewesK\TwigExcelBundle\Twig\Node\XlsSheetNode' 55 | ]; 56 | } 57 | 58 | /** 59 | * @return bool 60 | */ 61 | public function canContainText() 62 | { 63 | return false; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Twig/Node/XlsHeaderNode.php: -------------------------------------------------------------------------------- 1 | $type, 'properties' => $properties, 'body' => $body], [], $line, $tag); 26 | } 27 | 28 | /** 29 | * @param Twig_Compiler $compiler 30 | */ 31 | public function compile(Twig_Compiler $compiler) 32 | { 33 | $compiler->addDebugInfo($this) 34 | ->write('$headerType = ') 35 | ->subcompile($this->getNode('type')) 36 | ->raw(';' . PHP_EOL) 37 | ->write('$headerType = $headerType ? $headerType : \'header\';' . PHP_EOL) 38 | ->write('$headerProperties = ') 39 | ->subcompile($this->getNode('properties')) 40 | ->raw(';' . PHP_EOL) 41 | ->write('$context[\'phpExcel\']->startHeaderFooter($headerType, $headerProperties);' . PHP_EOL) 42 | ->write('unset($headerType, $headerProperties);' . PHP_EOL) 43 | ->subcompile($this->getNode('body')) 44 | ->addDebugInfo($this) 45 | ->write('$context[\'phpExcel\']->endHeaderFooter();' . PHP_EOL); 46 | } 47 | 48 | /** 49 | * @return string[] 50 | */ 51 | public function getAllowedParents() 52 | { 53 | return [ 54 | 'MewesK\TwigExcelBundle\Twig\Node\XlsSheetNode' 55 | ]; 56 | } 57 | 58 | /** 59 | * @return bool 60 | */ 61 | public function canContainText() 62 | { 63 | return false; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Twig/Node/XlsLeftNode.php: -------------------------------------------------------------------------------- 1 | $body], [], $line, $tag); 23 | } 24 | 25 | /** 26 | * @param Twig_Compiler $compiler 27 | */ 28 | public function compile(Twig_Compiler $compiler) 29 | { 30 | $compiler->addDebugInfo($this) 31 | ->write('$context[\'phpExcel\']->startAlignment(\'left\');' . PHP_EOL) 32 | ->write("ob_start();\n") 33 | ->subcompile($this->getNode('body')) 34 | ->write('$leftValue = trim(ob_get_clean());' . PHP_EOL) 35 | ->write('$context[\'phpExcel\']->endAlignment($leftValue);' . PHP_EOL) 36 | ->write('unset($leftValue);' . PHP_EOL); 37 | } 38 | 39 | /** 40 | * @return string[] 41 | */ 42 | public function getAllowedParents() 43 | { 44 | return [ 45 | 'MewesK\TwigExcelBundle\Twig\Node\XlsFooterNode', 46 | 'MewesK\TwigExcelBundle\Twig\Node\XlsHeaderNode' 47 | ]; 48 | } 49 | 50 | /** 51 | * @return bool 52 | */ 53 | public function canContainText() 54 | { 55 | return true; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Twig/Node/XlsRightNode.php: -------------------------------------------------------------------------------- 1 | $body], [], $line, $tag); 23 | } 24 | 25 | /** 26 | * @param Twig_Compiler $compiler 27 | */ 28 | public function compile(Twig_Compiler $compiler) 29 | { 30 | $compiler->addDebugInfo($this) 31 | ->write('$context[\'phpExcel\']->startAlignment(\'right\');' . PHP_EOL) 32 | ->write("ob_start();\n") 33 | ->subcompile($this->getNode('body')) 34 | ->write('$rightValue = trim(ob_get_clean());' . PHP_EOL) 35 | ->write('$context[\'phpExcel\']->endAlignment($rightValue);' . PHP_EOL) 36 | ->write('unset($rightValue);' . PHP_EOL); 37 | } 38 | 39 | /** 40 | * @return string[] 41 | */ 42 | public function getAllowedParents() 43 | { 44 | return [ 45 | 'MewesK\TwigExcelBundle\Twig\Node\XlsFooterNode', 46 | 'MewesK\TwigExcelBundle\Twig\Node\XlsHeaderNode' 47 | ]; 48 | } 49 | 50 | /** 51 | * @return bool 52 | */ 53 | public function canContainText() 54 | { 55 | return true; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Twig/Node/XlsRowNode.php: -------------------------------------------------------------------------------- 1 | $index, 'body' => $body], [], $line, $tag); 25 | } 26 | 27 | /** 28 | * @param Twig_Compiler $compiler 29 | */ 30 | public function compile(Twig_Compiler $compiler) 31 | { 32 | $compiler->addDebugInfo($this) 33 | ->write('$context[\'phpExcel\']->setRowIndex(') 34 | ->subcompile($this->getNode('index')) 35 | ->raw(');' . PHP_EOL) 36 | ->write('$context[\'phpExcel\']->startRow($context[\'phpExcel\']->getRowIndex());' . PHP_EOL) 37 | ->write('$context[\'phpExcel\']->setRowIndex(0);' . PHP_EOL) 38 | ->subcompile($this->getNode('body')) 39 | ->addDebugInfo($this) 40 | ->write('$context[\'phpExcel\']->endRow();' . PHP_EOL); 41 | } 42 | 43 | /** 44 | * @return string[] 45 | */ 46 | public function getAllowedParents() 47 | { 48 | return [ 49 | 'MewesK\TwigExcelBundle\Twig\Node\XlsSheetNode' 50 | ]; 51 | } 52 | 53 | /** 54 | * @return bool 55 | */ 56 | public function canContainText() 57 | { 58 | return false; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Twig/Node/XlsSheetNode.php: -------------------------------------------------------------------------------- 1 | $index, 'properties' => $properties, 'body' => $body], [], $line, $tag); 26 | } 27 | 28 | /** 29 | * @param Twig_Compiler $compiler 30 | */ 31 | public function compile(Twig_Compiler $compiler) 32 | { 33 | $compiler->addDebugInfo($this) 34 | ->write('$sheetIndex = ') 35 | ->subcompile($this->getNode('index')) 36 | ->raw(';' . PHP_EOL) 37 | ->write('$sheetProperties = ') 38 | ->subcompile($this->getNode('properties')) 39 | ->raw(';' . PHP_EOL) 40 | ->write('$context[\'phpExcel\']->startSheet($sheetIndex, $sheetProperties);' . PHP_EOL) 41 | ->write('unset($sheetIndex, $sheetProperties);' . PHP_EOL); 42 | 43 | if ($this->hasNode('body')) { 44 | $compiler->subcompile($this->getNode('body')); 45 | } 46 | 47 | $compiler->addDebugInfo($this)->write('$context[\'phpExcel\']->endSheet();' . PHP_EOL); 48 | } 49 | 50 | /** 51 | * @return string[] 52 | */ 53 | public function getAllowedParents() 54 | { 55 | return [ 56 | 'MewesK\TwigExcelBundle\Twig\Node\XlsDocumentNode' 57 | ]; 58 | } 59 | 60 | /** 61 | * @return bool 62 | */ 63 | public function canContainText() 64 | { 65 | return false; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Twig/NodeHelper.php: -------------------------------------------------------------------------------- 1 | getIterator() as $key => $subNode) { 30 | if ($subNode instanceof Twig_Node_Expression_MethodCall) { 31 | /** 32 | * @var \Twig_Node_Expression_Array $argumentsNode 33 | */ 34 | $argumentsNode = $subNode->getNode('arguments'); 35 | $argumentsNode->addElement(new Twig_Node_Expression_Name('phpExcel', null), null); 36 | } elseif ($subNode instanceof Twig_Node && $subNode->count() > 0) { 37 | self::fixMacroCallsRecursively($subNode); 38 | } 39 | } 40 | } 41 | 42 | /** 43 | * Removes all TextNodes that are in illegal places to avoid echos in unwanted places. 44 | * 45 | * @param Twig_Node $node 46 | * @param Twig_Parser $parser 47 | */ 48 | public static function removeTextNodesRecursively(Twig_Node $node, Twig_Parser $parser) 49 | { 50 | foreach ($node->getIterator() as $key => $subNode) { 51 | if ($subNode instanceof Twig_Node_Text) { 52 | // Never delete a block body 53 | if ($key === 'body' && $node instanceof Twig_Node_Block) { 54 | continue; 55 | } 56 | 57 | $node->removeNode($key); 58 | } elseif ($subNode instanceof Twig_Node_BlockReference) { 59 | self::removeTextNodesRecursively($parser->getBlock($subNode->getAttribute('name')), $parser); 60 | } elseif ($subNode instanceof Twig_Node && $subNode->count() > 0) { 61 | if ($subNode instanceof SyntaxAwareNodeInterface && $subNode->canContainText()) { 62 | continue; 63 | } 64 | self::removeTextNodesRecursively($subNode, $parser); 65 | } 66 | } 67 | } 68 | 69 | /** 70 | * @param SyntaxAwareNodeInterface $node 71 | * @param array $path 72 | * @throws Twig_Error_Syntax 73 | */ 74 | public static function checkAllowedParents(SyntaxAwareNodeInterface $node, array $path) 75 | { 76 | $parentName = null; 77 | 78 | foreach (array_reverse($path) as $className) { 79 | if (strpos($className, 'MewesK\TwigExcelBundle\Twig\Node\Xls') === 0) { 80 | $parentName = $className; 81 | break; 82 | } 83 | } 84 | 85 | if ($parentName === null) { 86 | return; 87 | } 88 | 89 | foreach ($node->getAllowedParents() as $className) { 90 | if ($className === $parentName) { 91 | return; 92 | } 93 | } 94 | 95 | throw new Twig_Error_Syntax(sprintf('Node "%s" is not allowed inside of Node "%s".', get_class($node), $parentName)); 96 | } 97 | 98 | /** 99 | * @param Twig_Node $node 100 | * @return bool 101 | */ 102 | public static function checkContainsXlsNode(Twig_Node $node) 103 | { 104 | foreach ($node->getIterator() as $key => $subNode) { 105 | if ($node instanceof SyntaxAwareNodeInterface) { 106 | return true; 107 | } elseif ($subNode instanceof Twig_Node && $subNode->count() > 0) { 108 | if (self::checkContainsXlsNode($subNode)) { 109 | return true; 110 | } 111 | } 112 | } 113 | return false; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Twig/NodeVisitor/SyntaxCheckNodeVisitor.php: -------------------------------------------------------------------------------- 1 | hasAttribute('twigExcelBundle') && NodeHelper::checkContainsXlsNode($node)) { 34 | if ($node instanceof Twig_Node_Block) { 35 | throw new Twig_Error_Syntax('Block tags do not work together with Twig tags provided by TwigExcelBundle. Please use \'xlsblock\' instead.'); 36 | } 37 | elseif ($node instanceof Twig_Node_Macro) { 38 | throw new Twig_Error_Syntax('Macro tags do not work together with Twig tags provided by TwigExcelBundle. Please use \'xlsmacro\' instead.'); 39 | } 40 | } 41 | elseif ($node instanceof SyntaxAwareNodeInterface) { 42 | /** 43 | * @var SyntaxAwareNodeInterface $node 44 | */ 45 | try { 46 | NodeHelper::checkAllowedParents($node, $this->path); 47 | } catch(Twig_Error_Syntax $e) { 48 | // reset path since throwing an error prevents doLeaveNode to be called 49 | $this->path = []; 50 | throw $e; 51 | } 52 | } 53 | 54 | $this->path[] = get_class($node); 55 | 56 | return $node; 57 | } 58 | 59 | /** 60 | * {@inheritdoc} 61 | */ 62 | protected function doLeaveNode(Twig_Node $node, Twig_Environment $env) 63 | { 64 | array_pop($this->path); 65 | 66 | return $node; 67 | } 68 | 69 | /** 70 | * {@inheritdoc} 71 | */ 72 | public function getPriority() 73 | { 74 | return 0; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Twig/TokenParser/AbstractTokenParser.php: -------------------------------------------------------------------------------- 1 | parser->subparse(function (Twig_Token $token) { 24 | return $token->test('end' . $this->getTag()); 25 | }, 26 | true); 27 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 28 | 29 | return $body; 30 | } 31 | 32 | /** 33 | * @param Twig_Token $token 34 | * @return mixed|\Twig_Node_Expression_Array|\Twig_Node_Expression_Conditional|\Twig_Node_Expression_GetAttr 35 | */ 36 | protected function parseProperties(Twig_Token $token) 37 | { 38 | $properties = new Twig_Node_Expression_Array([], $token->getLine()); 39 | if (!$this->parser->getStream()->test(Twig_Token::BLOCK_END_TYPE)) { 40 | $properties = $this->parser->getExpressionParser()->parseExpression(); 41 | } 42 | 43 | return $properties; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Twig/TokenParser/XlsBlockTokenParser.php: -------------------------------------------------------------------------------- 1 | getLine(); 31 | $stream = $this->parser->getStream(); 32 | $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); 33 | if ($this->parser->hasBlock($name)) { 34 | throw new Twig_Error_Syntax(sprintf("The block '%s' has already been defined line %d.", $name, $this->parser->getBlock($name)->getTemplateLine()), $stream->getCurrent()->getLine(), $stream->getSourceContext()); 35 | } 36 | $this->parser->setBlock($name, $block = new Twig_Node_Block($name, new Twig_Node(array()), $lineno)); 37 | $this->parser->pushLocalScope(); 38 | $this->parser->pushBlockStack($name); 39 | 40 | if ($stream->nextIf(Twig_Token::BLOCK_END_TYPE)) { 41 | $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); 42 | if ($token = $stream->nextIf(Twig_Token::NAME_TYPE)) { 43 | $value = $token->getValue(); 44 | 45 | if ($value !== $name) { 46 | throw new Twig_Error_Syntax(sprintf('Expected endblock for block "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext()); 47 | } 48 | } 49 | } else { 50 | $body = new Twig_Node(array( 51 | new Twig_Node_Print($this->parser->getExpressionParser()->parseExpression(), $lineno), 52 | )); 53 | } 54 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 55 | 56 | $block->setNode('body', $body); 57 | $this->parser->popBlockStack(); 58 | $this->parser->popLocalScope(); 59 | 60 | $blockReference = new Twig_Node_BlockReference($name, $lineno, $this->getTag()); 61 | 62 | /** 63 | * @var Twig_Node_Block $block 64 | */ 65 | $block = $this->parser->getBlock($blockReference->getAttribute('name')); 66 | 67 | // prepare block 68 | NodeHelper::removeTextNodesRecursively($block, $this->parser); 69 | NodeHelper::fixMacroCallsRecursively($block); 70 | 71 | // mark for syntax checks 72 | foreach ($block->getIterator() as $node) { 73 | if ($node instanceof Twig_Node_Block) { 74 | $node->setAttribute('twigExcelBundle', true); 75 | } 76 | } 77 | 78 | return $blockReference; 79 | } 80 | 81 | /** 82 | * @param Twig_Token $token 83 | * @return bool 84 | */ 85 | public function decideBlockEnd(Twig_Token $token) 86 | { 87 | return $token->test('endxlsblock'); 88 | } 89 | 90 | /** 91 | * @return string 92 | */ 93 | public function getTag() 94 | { 95 | return 'xlsblock'; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Twig/TokenParser/XlsCellTokenParser.php: -------------------------------------------------------------------------------- 1 | getLine()); 26 | if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE) && !$this->parser->getStream()->test(Twig_Token::BLOCK_END_TYPE)) { 27 | $index = $this->parser->getExpressionParser()->parseExpression(); 28 | } 29 | $properties = $this->parseProperties($token); 30 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 31 | 32 | // parse body 33 | $body = $this->parseBody(); 34 | 35 | // return node 36 | return new XlsCellNode($index, $properties, $body, $token->getLine(), $this->getTag()); 37 | } 38 | 39 | /** 40 | * @return string 41 | */ 42 | public function getTag() 43 | { 44 | return 'xlscell'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Twig/TokenParser/XlsCenterTokenParser.php: -------------------------------------------------------------------------------- 1 | parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 25 | 26 | // parse body 27 | $body = $this->parseBody(); 28 | 29 | // return node 30 | return new XlsCenterNode($body, $token->getLine(), $this->getTag()); 31 | } 32 | 33 | /** 34 | * @return string 35 | */ 36 | public function getTag() 37 | { 38 | return 'xlscenter'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Twig/TokenParser/XlsDocumentTokenParser.php: -------------------------------------------------------------------------------- 1 | preCalculateFormulas = $preCalculateFormulas; 32 | $this->diskCachingDirectory = $diskCachingDirectory; 33 | } 34 | 35 | /** 36 | * @param Twig_Token $token 37 | * 38 | * @return XlsDocumentNode 39 | * @throws \Twig_Error_Syntax 40 | */ 41 | public function parse(Twig_Token $token) 42 | { 43 | // parse attributes 44 | $properties = $this->parseProperties($token); 45 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 46 | 47 | // parse body 48 | $body = $this->parseBody(); 49 | NodeHelper::removeTextNodesRecursively($body, $this->parser); 50 | NodeHelper::fixMacroCallsRecursively($body); 51 | 52 | // return node 53 | return new XlsDocumentNode($properties, $body, $token->getLine(), $this->getTag(), $this->preCalculateFormulas, $this->diskCachingDirectory); 54 | } 55 | 56 | /** 57 | * @return string 58 | */ 59 | public function getTag() 60 | { 61 | return 'xlsdocument'; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Twig/TokenParser/XlsDrawingTokenParser.php: -------------------------------------------------------------------------------- 1 | parser->getExpressionParser()->parseExpression(); 25 | $properties = $this->parseProperties($token); 26 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 27 | 28 | // return node 29 | return new XlsDrawingNode($path, $properties, $token->getLine(), $this->getTag()); 30 | } 31 | 32 | /** 33 | * @return string 34 | */ 35 | public function getTag() 36 | { 37 | return 'xlsdrawing'; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Twig/TokenParser/XlsFooterTokenParser.php: -------------------------------------------------------------------------------- 1 | getLine()); 26 | if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE) && !$this->parser->getStream()->test(Twig_Token::BLOCK_END_TYPE)) { 27 | $type = $this->parser->getExpressionParser()->parseExpression(); 28 | } 29 | $properties = $this->parseProperties($token); 30 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 31 | 32 | // parse body 33 | $body = $this->parseBody(); 34 | 35 | // return node 36 | return new XlsFooterNode($type, $properties, $body, $token->getLine(), $this->getTag()); 37 | } 38 | 39 | /** 40 | * @return string 41 | */ 42 | public function getTag() 43 | { 44 | return 'xlsfooter'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Twig/TokenParser/XlsHeaderTokenParser.php: -------------------------------------------------------------------------------- 1 | getLine()); 26 | if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE) && !$this->parser->getStream()->test(Twig_Token::BLOCK_END_TYPE)) { 27 | $type = $this->parser->getExpressionParser()->parseExpression(); 28 | } 29 | $properties = $this->parseProperties($token); 30 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 31 | 32 | // parse body 33 | $body = $this->parseBody(); 34 | 35 | // return node 36 | return new XlsHeaderNode($type, $properties, $body, $token->getLine(), $this->getTag()); 37 | } 38 | 39 | /** 40 | * @return string 41 | */ 42 | public function getTag() 43 | { 44 | return 'xlsheader'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Twig/TokenParser/XlsIncludeTokenParser.php: -------------------------------------------------------------------------------- 1 | parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 26 | $body = $this->parseBody(); 27 | NodeHelper::removeTextNodesRecursively($body, $this->parser); 28 | NodeHelper::fixMacroCallsRecursively($body); 29 | 30 | // return node 31 | return $body; 32 | } 33 | 34 | /** 35 | * @return string 36 | */ 37 | public function getTag() 38 | { 39 | return 'xlsinclude'; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Twig/TokenParser/XlsLeftTokenParser.php: -------------------------------------------------------------------------------- 1 | parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 25 | 26 | // parse body 27 | $body = $this->parseBody(); 28 | 29 | // return node 30 | return new XlsLeftNode($body, $token->getLine(), $this->getTag()); 31 | } 32 | 33 | /** 34 | * @return string 35 | */ 36 | public function getTag() 37 | { 38 | return 'xlsleft'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Twig/TokenParser/XlsMacroTokenParser.php: -------------------------------------------------------------------------------- 1 | getLine(); 30 | $stream = $this->parser->getStream(); 31 | $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); 32 | 33 | $arguments = $this->parser->getExpressionParser()->parseArguments(true, true); 34 | 35 | // fix macro context 36 | $arguments->setNode('phpExcel', new Twig_Node_Expression_Constant(null, null)); 37 | 38 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 39 | $this->parser->pushLocalScope(); 40 | $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true); 41 | if ($token = $stream->nextIf(Twig_Token::NAME_TYPE)) { 42 | $value = $token->getValue(); 43 | 44 | if ($value !== $name) { 45 | throw new Twig_Error_Syntax(sprintf('Expected endxlsmacro for macro "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getFilename()); 46 | } 47 | } 48 | $this->parser->popLocalScope(); 49 | $stream->expect(Twig_Token::BLOCK_END_TYPE); 50 | 51 | // remove all unwanted text nodes 52 | NodeHelper::removeTextNodesRecursively($body, $this->parser); 53 | 54 | // fix the methodCalls inside the body 55 | NodeHelper::fixMacroCallsRecursively($body); 56 | 57 | $macro = new Twig_Node_Macro($name, new Twig_Node_Body(array($body)), $arguments, $lineno, $this->getTag()); 58 | 59 | // mark for syntax checks 60 | $macro->setAttribute('twigExcelBundle', true); 61 | 62 | $this->parser->setMacro($name, $macro); 63 | } 64 | 65 | /** 66 | * @param Twig_Token $token 67 | * @return bool 68 | */ 69 | public function decideBlockEnd(Twig_Token $token) 70 | { 71 | return $token->test('endxlsmacro'); 72 | } 73 | 74 | /** 75 | * @return string 76 | */ 77 | public function getTag() 78 | { 79 | return 'xlsmacro'; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Twig/TokenParser/XlsRightTokenParser.php: -------------------------------------------------------------------------------- 1 | parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 25 | 26 | // parse body 27 | $body = $this->parseBody(); 28 | 29 | // return node 30 | return new XlsRightNode($body, $token->getLine(), $this->getTag()); 31 | } 32 | 33 | /** 34 | * @return string 35 | */ 36 | public function getTag() 37 | { 38 | return 'xlsright'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Twig/TokenParser/XlsRowTokenParser.php: -------------------------------------------------------------------------------- 1 | getLine()); 26 | if (!$this->parser->getStream()->test(Twig_Token::BLOCK_END_TYPE)) { 27 | $index = $this->parser->getExpressionParser()->parseExpression(); 28 | } 29 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 30 | 31 | // parse body 32 | $body = $this->parseBody(); 33 | 34 | // return node 35 | return new XlsRowNode($index, $body, $token->getLine(), $this->getTag()); 36 | } 37 | 38 | /** 39 | * @return string 40 | */ 41 | public function getTag() 42 | { 43 | return 'xlsrow'; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Twig/TokenParser/XlsSheetTokenParser.php: -------------------------------------------------------------------------------- 1 | getLine()); 26 | if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE) && !$this->parser->getStream()->test(Twig_Token::BLOCK_END_TYPE)) { 27 | $title = $this->parser->getExpressionParser()->parseExpression(); 28 | } 29 | $properties = $this->parseProperties($token); 30 | $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); 31 | 32 | // parse body 33 | $body = $this->parseBody(); 34 | 35 | // return node 36 | return new XlsSheetNode($title, $properties, $body, $token->getLine(), $this->getTag()); 37 | } 38 | 39 | /** 40 | * @return string 41 | */ 42 | public function getTag() 43 | { 44 | return 'xlssheet'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Twig/TwigExcelExtension.php: -------------------------------------------------------------------------------- 1 | preCalculateFormulas = $preCalculateFormulas; 46 | $this->diskCachingDirectory = $diskCachingDirectory; 47 | } 48 | 49 | /** 50 | * {@inheritdoc} 51 | */ 52 | public function getFunctions() 53 | { 54 | return [new Twig_SimpleFunction('xlsmergestyles', [$this, 'mergeStyles'])]; 55 | } 56 | 57 | /** 58 | * {@inheritdoc} 59 | */ 60 | public function getTokenParsers() 61 | { 62 | return [ 63 | new XlsBlockTokenParser(), 64 | new XlsCellTokenParser(), 65 | new XlsCenterTokenParser(), 66 | new XlsDocumentTokenParser($this->preCalculateFormulas, $this->diskCachingDirectory), 67 | new XlsDrawingTokenParser(), 68 | new XlsFooterTokenParser(), 69 | new XlsHeaderTokenParser(), 70 | new XlsIncludeTokenParser(), 71 | new XlsLeftTokenParser(), 72 | new XlsMacroTokenParser(), 73 | new XlsRightTokenParser(), 74 | new XlsRowTokenParser(), 75 | new XlsSheetTokenParser() 76 | ]; 77 | } 78 | 79 | /** 80 | * {@inheritdoc} 81 | */ 82 | public function getNodeVisitors() 83 | { 84 | return [ 85 | new SyntaxCheckNodeVisitor() 86 | ]; 87 | } 88 | 89 | /** 90 | * {@inheritdoc} 91 | */ 92 | public function getName() 93 | { 94 | return 'excel_extension'; 95 | } 96 | 97 | /** 98 | * @param array $style1 99 | * @param array $style2 100 | * 101 | * @return array 102 | * @throws Twig_Error_Runtime 103 | */ 104 | public function mergeStyles(array $style1, array $style2) 105 | { 106 | if (!is_array($style1) || !is_array($style2)) { 107 | throw new Twig_Error_Runtime('The xlsmergestyles function only works with arrays.'); 108 | } 109 | 110 | return array_merge_recursive($style1, $style2); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /Wrapper/AbstractWrapper.php: -------------------------------------------------------------------------------- 1 | $value) { 19 | if (array_key_exists($key, $mappings)) { 20 | if (is_array($value) && is_array($mappings) && $key !== 'style' && $key !== 'defaultStyle') { 21 | /** 22 | * @var array $value 23 | */ 24 | if (array_key_exists('__multi', $mappings[$key]) && $mappings[$key]['__multi'] === true) { 25 | foreach ($value as $_key => $_value) { 26 | $this->setPropertiesByKey($_key, $_value, $mappings[$key]); 27 | } 28 | } else { 29 | $this->setProperties($value, $mappings[$key]); 30 | } 31 | } else { 32 | $mappings[$key]($value); 33 | } 34 | } 35 | } 36 | } 37 | 38 | /** 39 | * @param string $key 40 | * @param array $properties 41 | * @param array $mappings 42 | */ 43 | protected function setPropertiesByKey($key, array $properties, array $mappings) 44 | { 45 | foreach ($properties as $_key => $value) { 46 | if (array_key_exists($_key, $mappings)) { 47 | if (is_array($value)) { 48 | $this->setPropertiesByKey($key, $value, $mappings[$_key]); 49 | } else { 50 | $mappings[$_key]($key, $value); 51 | } 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Wrapper/PhpExcelWrapper.php: -------------------------------------------------------------------------------- 1 | documentWrapper = new XlsDocumentWrapper($context, $environment); 55 | $this->sheetWrapper = new XlsSheetWrapper($context, $environment, $this->documentWrapper); 56 | $this->rowWrapper = new XlsRowWrapper($context, $environment, $this->sheetWrapper); 57 | $this->cellWrapper = new XlsCellWrapper($context, $environment, $this->sheetWrapper); 58 | $this->headerFooterWrapper = new XlsHeaderFooterWrapper($context, $environment, $this->sheetWrapper); 59 | $this->drawingWrapper = new XlsDrawingWrapper($context, $environment, $this->sheetWrapper, $this->headerFooterWrapper); 60 | } 61 | 62 | // 63 | // Tags 64 | // 65 | 66 | /** 67 | * @param null|array $properties 68 | * 69 | * @throws \PHPExcel_Exception 70 | */ 71 | public function startDocument(array $properties = null) 72 | { 73 | $this->documentWrapper->start($properties); 74 | } 75 | 76 | /** 77 | * @throws \PHPExcel_Reader_Exception 78 | * @throws \PHPExcel_Exception 79 | * @throws \InvalidArgumentException 80 | * @throws \PHPExcel_Writer_Exception 81 | */ 82 | public function endDocument() 83 | { 84 | $this->documentWrapper->end(); 85 | } 86 | 87 | /** 88 | * @param string $index 89 | * @param null|array $properties 90 | * @throws \PHPExcel_Exception 91 | */ 92 | public function startSheet($index, array $properties = null) 93 | { 94 | $this->sheetWrapper->start($index, $properties); 95 | } 96 | 97 | public function endSheet() 98 | { 99 | $this->sheetWrapper->end(); 100 | } 101 | 102 | public function startRow() 103 | { 104 | $this->rowWrapper->start($this->rowIndex); 105 | } 106 | 107 | public function endRow() 108 | { 109 | $this->rowWrapper->end(); 110 | } 111 | 112 | /** 113 | * @param null|mixed $value 114 | * @param null|array $properties 115 | * @throws \PHPExcel_Exception 116 | * @throws \InvalidArgumentException 117 | * @throws \LogicException 118 | */ 119 | public function startCell($value = null, array $properties = null) 120 | { 121 | $this->cellWrapper->start($this->cellIndex, $value, $properties); 122 | } 123 | 124 | public function endCell() 125 | { 126 | $this->cellWrapper->end(); 127 | } 128 | 129 | /** 130 | * @param string $type 131 | * @param null|array $properties 132 | * @throws \LogicException 133 | */ 134 | public function startHeaderFooter($type, array $properties = null) 135 | { 136 | $this->headerFooterWrapper->start($type, $properties); 137 | } 138 | 139 | public function endHeaderFooter() 140 | { 141 | $this->headerFooterWrapper->end(); 142 | } 143 | 144 | /** 145 | * @param null|string $type 146 | * @param null|array $properties 147 | * @throws \InvalidArgumentException 148 | */ 149 | public function startAlignment($type = null, array $properties = null) 150 | { 151 | $this->headerFooterWrapper->startAlignment($type, $properties); 152 | } 153 | 154 | /** 155 | * @param null|string $value 156 | * @throws \InvalidArgumentException 157 | */ 158 | public function endAlignment($value = null) 159 | { 160 | $this->headerFooterWrapper->endAlignment($value); 161 | } 162 | 163 | /** 164 | * @param string $path 165 | * @param array $properties 166 | * @throws \PHPExcel_Exception 167 | * @throws \InvalidArgumentException 168 | * @throws \LogicException 169 | * @throws \RuntimeException 170 | */ 171 | public function startDrawing($path, array $properties = null) 172 | { 173 | $this->drawingWrapper->start($path, $properties); 174 | } 175 | 176 | public function endDrawing() 177 | { 178 | $this->drawingWrapper->end(); 179 | } 180 | 181 | // Getter / Setter 182 | 183 | /** 184 | * @return int 185 | */ 186 | public function getCellIndex() 187 | { 188 | return $this->cellIndex; 189 | } 190 | 191 | /** 192 | * @param int $cellIndex 193 | */ 194 | public function setCellIndex($cellIndex) 195 | { 196 | $this->cellIndex = $cellIndex; 197 | } 198 | 199 | /** 200 | * @return int 201 | */ 202 | public function getRowIndex() 203 | { 204 | return $this->rowIndex; 205 | } 206 | 207 | /** 208 | * @param int $rowIndex 209 | */ 210 | public function setRowIndex($rowIndex) 211 | { 212 | $this->rowIndex = $rowIndex; 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /Wrapper/XlsCellWrapper.php: -------------------------------------------------------------------------------- 1 | context = $context; 51 | $this->environment = $environment; 52 | $this->sheetWrapper = $sheetWrapper; 53 | 54 | $this->object = null; 55 | $this->attributes = []; 56 | $this->mappings = []; 57 | 58 | $this->initializeMappings(); 59 | } 60 | 61 | protected function initializeMappings() 62 | { 63 | $this->mappings['break'] = function ($value) { 64 | $this->sheetWrapper->getObject()->setBreak($this->object->getCoordinate(), $value); 65 | }; 66 | $this->mappings['dataType'] = function ($value) { 67 | $this->object->setDataType($value); 68 | }; 69 | $this->mappings['dataValidation']['allowBlank'] = function ($value) { 70 | $this->object->getDataValidation()->setAllowBlank($value); 71 | }; 72 | $this->mappings['dataValidation']['error'] = function ($value) { 73 | $this->object->getDataValidation()->setError($value); 74 | }; 75 | $this->mappings['dataValidation']['errorStyle'] = function ($value) { 76 | $this->object->getDataValidation()->setErrorStyle($value); 77 | }; 78 | $this->mappings['dataValidation']['errorTitle'] = function ($value) { 79 | $this->object->getDataValidation()->setErrorTitle($value); 80 | }; 81 | $this->mappings['dataValidation']['formula1'] = function ($value) { 82 | $this->object->getDataValidation()->setFormula1($value); 83 | }; 84 | $this->mappings['dataValidation']['formula2'] = function ($value) { 85 | $this->object->getDataValidation()->setFormula2($value); 86 | }; 87 | $this->mappings['dataValidation']['operator'] = function ($value) { 88 | $this->object->getDataValidation()->setOperator($value); 89 | }; 90 | $this->mappings['dataValidation']['prompt'] = function ($value) { 91 | $this->object->getDataValidation()->setPrompt($value); 92 | }; 93 | $this->mappings['dataValidation']['promptTitle'] = function ($value) { 94 | $this->object->getDataValidation()->setPromptTitle($value); 95 | }; 96 | $this->mappings['dataValidation']['showDropDown'] = function ($value) { 97 | $this->object->getDataValidation()->setShowDropDown($value); 98 | }; 99 | $this->mappings['dataValidation']['showErrorMessage'] = function ($value) { 100 | $this->object->getDataValidation()->setShowErrorMessage($value); 101 | }; 102 | $this->mappings['dataValidation']['showInputMessage'] = function ($value) { 103 | $this->object->getDataValidation()->setShowInputMessage($value); 104 | }; 105 | $this->mappings['dataValidation']['type'] = function ($value) { 106 | $this->object->getDataValidation()->setType($value); 107 | }; 108 | $this->mappings['merge'] = function ($value) { 109 | if (is_int($value)) { 110 | $value = PHPExcel_Cell::stringFromColumnIndex($value) . $this->sheetWrapper->getRow(); 111 | } 112 | $this->sheetWrapper->getObject()->mergeCells(sprintf('%s:%s', $this->object->getCoordinate(), $value)); 113 | }; 114 | $this->mappings['style'] = function ($value) { 115 | $this->sheetWrapper->getObject()->getStyle($this->object->getCoordinate())->applyFromArray($value); 116 | }; 117 | $this->mappings['url'] = function ($value) { 118 | $this->object->getHyperlink()->setUrl($value); 119 | }; 120 | } 121 | 122 | /** 123 | * @param null|int $index 124 | * @param null|mixed $value 125 | * @param null|array $properties 126 | * @throws \PHPExcel_Exception 127 | * @throws \LogicException 128 | * @throws \InvalidArgumentException 129 | */ 130 | public function start($index = null, $value = null, array $properties = null) 131 | { 132 | if ($this->sheetWrapper->getObject() === null) { 133 | throw new \LogicException(); 134 | } 135 | if ($index !== null && !is_int($index)) { 136 | throw new \InvalidArgumentException('Invalid index'); 137 | } 138 | 139 | if ($index === null) { 140 | $this->sheetWrapper->increaseColumn(); 141 | } else { 142 | $this->sheetWrapper->setColumn($index); 143 | } 144 | 145 | $this->object = $this->sheetWrapper->getObject()->getCellByColumnAndRow($this->sheetWrapper->getColumn(), 146 | $this->sheetWrapper->getRow()); 147 | 148 | if ($value !== null) { 149 | if (array_key_exists('explicitValue', $properties) && $properties['explicitValue'] === true) { 150 | $this->object->setValueExplicit($value); 151 | } else { 152 | $this->object->setValue($value); 153 | } 154 | } 155 | 156 | if ($properties !== null) { 157 | $this->setProperties($properties, $this->mappings); 158 | } 159 | 160 | $this->attributes['value'] = $value; 161 | $this->attributes['properties'] = $properties ?: []; 162 | } 163 | 164 | public function end() 165 | { 166 | $this->object = null; 167 | $this->attributes = []; 168 | } 169 | 170 | // 171 | // Getters/Setters 172 | // 173 | 174 | /** 175 | * @return \PHPExcel_Cell 176 | */ 177 | public function getObject() 178 | { 179 | return $this->object; 180 | } 181 | 182 | /** 183 | * @param \PHPExcel_Cell $object 184 | */ 185 | public function setObject($object) 186 | { 187 | $this->object = $object; 188 | } 189 | 190 | /** 191 | * @return array 192 | */ 193 | public function getAttributes() 194 | { 195 | return $this->attributes; 196 | } 197 | 198 | /** 199 | * @param array $attributes 200 | */ 201 | public function setAttributes($attributes) 202 | { 203 | $this->attributes = $attributes; 204 | } 205 | 206 | /** 207 | * @return array 208 | */ 209 | public function getMappings() 210 | { 211 | return $this->mappings; 212 | } 213 | 214 | /** 215 | * @param array $mappings 216 | */ 217 | public function setMappings($mappings) 218 | { 219 | $this->mappings = $mappings; 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /Wrapper/XlsDocumentWrapper.php: -------------------------------------------------------------------------------- 1 | context = $context; 50 | $this->environment = $environment; 51 | 52 | $this->object = null; 53 | $this->attributes = []; 54 | $this->mappings = []; 55 | 56 | $this->initializeMappings(); 57 | } 58 | 59 | protected function initializeMappings() 60 | { 61 | $this->mappings['category'] = function ($value) { 62 | $this->object->getProperties()->setCategory($value); 63 | }; 64 | $this->mappings['company'] = function ($value) { 65 | $this->object->getProperties()->setCompany($value); 66 | }; 67 | $this->mappings['created'] = function ($value) { 68 | $this->object->getProperties()->setCreated($value); 69 | }; 70 | $this->mappings['creator'] = function ($value) { 71 | $this->object->getProperties()->setCreator($value); 72 | }; 73 | $this->mappings['defaultStyle'] = function ($value) { 74 | $this->object->getDefaultStyle()->applyFromArray($value); 75 | }; 76 | $this->mappings['description'] = function ($value) { 77 | $this->object->getProperties()->setDescription($value); 78 | }; 79 | $this->mappings['format'] = function ($value) { 80 | $this->attributes['format'] = $value; 81 | }; 82 | $this->mappings['keywords'] = function ($value) { 83 | $this->object->getProperties()->setKeywords($value); 84 | }; 85 | $this->mappings['lastModifiedBy'] = function ($value) { 86 | $this->object->getProperties()->setLastModifiedBy($value); 87 | }; 88 | $this->mappings['manager'] = function ($value) { 89 | $this->object->getProperties()->setManager($value); 90 | }; 91 | $this->mappings['modified'] = function ($value) { 92 | $this->object->getProperties()->setModified($value); 93 | }; 94 | $this->mappings['security']['lockRevision'] = function ($value) { 95 | $this->object->getSecurity()->setLockRevision($value); 96 | }; 97 | $this->mappings['security']['lockStructure'] = function ($value) { 98 | $this->object->getSecurity()->setLockStructure($value); 99 | }; 100 | $this->mappings['security']['lockWindows'] = function ($value) { 101 | $this->object->getSecurity()->setLockWindows($value); 102 | }; 103 | $this->mappings['security']['revisionsPassword'] = function ($value) { 104 | $this->object->getSecurity()->setRevisionsPassword($value); 105 | }; 106 | $this->mappings['security']['workbookPassword'] = function ($value) { 107 | $this->object->getSecurity()->setWorkbookPassword($value); 108 | }; 109 | $this->mappings['subject'] = function ($value) { 110 | $this->object->getProperties()->setSubject($value); 111 | }; 112 | $this->mappings['template'] = function ($value) { 113 | $this->attributes['template'] = $value; 114 | }; 115 | $this->mappings['title'] = function ($value) { 116 | $this->object->getProperties()->setTitle($value); 117 | }; 118 | } 119 | 120 | /** 121 | * @param null|array $properties 122 | * @throws \PHPExcel_Exception 123 | */ 124 | public function start(array $properties = null) 125 | { 126 | // load template 127 | if (array_key_exists('template', $properties)) { 128 | $templatePath = $this->expandPath($properties['template']); 129 | $reader = PHPExcel_IOFactory::createReaderForFile($templatePath); 130 | $this->object = $reader->load($templatePath); 131 | } 132 | 133 | // create new 134 | else { 135 | $this->object = new \PHPExcel(); 136 | $this->object->removeSheetByIndex(0); 137 | } 138 | 139 | $this->attributes['properties'] = $properties ?: []; 140 | 141 | if ($properties !== null) { 142 | $this->setProperties($properties, $this->mappings); 143 | } 144 | } 145 | 146 | /** 147 | * @param bool $preCalculateFormulas 148 | * @param null|string $diskCachingDirectory 149 | * @throws \InvalidArgumentException 150 | * @throws \PHPExcel_Exception 151 | * @throws \PHPExcel_Reader_Exception 152 | * @throws \PHPExcel_Writer_Exception 153 | */ 154 | public function end($preCalculateFormulas = true, $diskCachingDirectory = null) 155 | { 156 | $format = null; 157 | 158 | // try document property 159 | if (array_key_exists('format', $this->attributes)) { 160 | $format = $this->attributes['format']; 161 | } 162 | 163 | // try Symfony request 164 | else if (array_key_exists('app', $this->context)) { 165 | /** 166 | * @var $appVariable AppVariable 167 | */ 168 | $appVariable = $this->context['app']; 169 | if ($appVariable instanceof AppVariable && $appVariable->getRequest() !== null) { 170 | $format = $appVariable->getRequest()->getRequestFormat(); 171 | } 172 | } 173 | 174 | // set default 175 | if ($format === null || !is_string($format)) { 176 | $format = 'xlsx'; 177 | } 178 | 179 | switch (strtolower($format)) { 180 | case 'csv': 181 | $writerType = 'CSV'; 182 | break; 183 | case 'ods': 184 | $writerType = 'OpenDocument'; 185 | break; 186 | case 'pdf': 187 | $writerType = 'PDF'; 188 | try { 189 | $reflectionClass = new ReflectionClass('mPDF'); 190 | $path = dirname($reflectionClass->getFileName()); 191 | if (!PHPExcel_Settings::setPdfRenderer(PHPExcel_Settings::PDF_RENDERER_MPDF, $path)) { 192 | throw new \PHPExcel_Exception(); 193 | } 194 | } catch (\Exception $e) { 195 | throw new \PHPExcel_Exception('Error loading mPDF. Is mPDF correctly installed?', $e->getCode(), $e); 196 | } 197 | break; 198 | case 'xls': 199 | $writerType = 'Excel5'; 200 | break; 201 | case 'xlsx': 202 | $writerType = 'Excel2007'; 203 | break; 204 | default: 205 | throw new \InvalidArgumentException(sprintf('Unknown format "%s"', $format)); 206 | } 207 | 208 | /** 209 | * @var $writer PHPExcel_Writer_Abstract 210 | */ 211 | $writer = \PHPExcel_IOFactory::createWriter($this->object, $writerType); 212 | $writer->setPreCalculateFormulas($preCalculateFormulas); 213 | $writer->setUseDiskCaching($diskCachingDirectory !== null, $diskCachingDirectory); 214 | $writer->save('php://output'); 215 | 216 | $this->object = null; 217 | $this->attributes = []; 218 | } 219 | 220 | // 221 | // Helpers 222 | // 223 | 224 | /** 225 | * Resolves properties containing paths using namespaces. 226 | * 227 | * @param string $path 228 | * @return bool 229 | */ 230 | private function expandPath($path) 231 | { 232 | $loader = $this->environment->getLoader(); 233 | if ($loader instanceof Twig_Loader_Filesystem) { 234 | /** 235 | * @var Twig_Loader_Filesystem $loader 236 | */ 237 | foreach ($loader->getNamespaces() as $namespace) { 238 | if (strpos($path, $namespace) === 1) { 239 | foreach ($loader->getPaths($namespace) as $namespacePath) { 240 | $expandedPathAttribute = str_replace('@' . $namespace, $namespacePath, $path); 241 | if (file_exists($expandedPathAttribute)) { 242 | return $expandedPathAttribute; 243 | } 244 | } 245 | } 246 | } 247 | } 248 | return $path; 249 | } 250 | 251 | // 252 | // Getters/Setters 253 | // 254 | 255 | /** 256 | * @return \PHPExcel 257 | */ 258 | public function getObject() 259 | { 260 | return $this->object; 261 | } 262 | 263 | /** 264 | * @param \PHPExcel $object 265 | */ 266 | public function setObject($object) 267 | { 268 | $this->object = $object; 269 | } 270 | 271 | /** 272 | * @return array 273 | */ 274 | public function getAttributes() 275 | { 276 | return $this->attributes; 277 | } 278 | 279 | /** 280 | * @param array $attributes 281 | */ 282 | public function setAttributes($attributes) 283 | { 284 | $this->attributes = $attributes; 285 | } 286 | 287 | /** 288 | * @return array 289 | */ 290 | public function getMappings() 291 | { 292 | return $this->mappings; 293 | } 294 | 295 | /** 296 | * @param array $mappings 297 | */ 298 | public function setMappings($mappings) 299 | { 300 | $this->mappings = $mappings; 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /Wrapper/XlsDrawingWrapper.php: -------------------------------------------------------------------------------- 1 | context = $context; 54 | $this->environment = $environment; 55 | $this->sheetWrapper = $sheetWrapper; 56 | $this->headerFooterWrapper = $headerFooterWrapper; 57 | 58 | $this->object = null; 59 | $this->attributes = []; 60 | $this->mappings = []; 61 | 62 | $this->initializeMappings(); 63 | } 64 | 65 | protected function initializeMappings() 66 | { 67 | $this->mappings['coordinates'] = function ($value) { 68 | $this->object->setCoordinates($value); 69 | }; 70 | $this->mappings['description'] = function ($value) { 71 | $this->object->setDescription($value); 72 | }; 73 | $this->mappings['height'] = function ($value) { 74 | $this->object->setHeight($value); 75 | }; 76 | $this->mappings['name'] = function ($value) { 77 | $this->object->setName($value); 78 | }; 79 | $this->mappings['offsetX'] = function ($value) { 80 | $this->object->setOffsetX($value); 81 | }; 82 | $this->mappings['offsetY'] = function ($value) { 83 | $this->object->setOffsetY($value); 84 | }; 85 | $this->mappings['resizeProportional'] = function ($value) { 86 | $this->object->setResizeProportional($value); 87 | }; 88 | $this->mappings['rotation'] = function ($value) { 89 | $this->object->setRotation($value); 90 | }; 91 | $this->mappings['shadow']['alignment'] = function ($value) { 92 | $this->object->getShadow()->setAlignment($value); 93 | }; 94 | $this->mappings['shadow']['alpha'] = function ($value) { 95 | $this->object->getShadow()->setAlpha($value); 96 | }; 97 | $this->mappings['shadow']['blurRadius'] = function ($value) { 98 | $this->object->getShadow()->setBlurRadius($value); 99 | }; 100 | $this->mappings['shadow']['color'] = function ($value) { 101 | $this->object->getShadow()->getColor()->setRGB($value); 102 | }; 103 | $this->mappings['shadow']['direction'] = function ($value) { 104 | $this->object->getShadow()->setDirection($value); 105 | }; 106 | $this->mappings['shadow']['distance'] = function ($value) { 107 | $this->object->getShadow()->setDistance($value); 108 | }; 109 | $this->mappings['shadow']['visible'] = function ($value) { 110 | $this->object->getShadow()->setVisible($value); 111 | }; 112 | $this->mappings['width'] = function ($value) { 113 | $this->object->setWidth($value); 114 | }; 115 | } 116 | 117 | /** 118 | * @param $path 119 | * @param array|null $properties 120 | * @throws \PHPExcel_Exception 121 | * @throws \LogicException 122 | * @throws \InvalidArgumentException 123 | * @throws \RuntimeException 124 | */ 125 | public function start($path, array $properties = null) 126 | { 127 | if ($this->sheetWrapper->getObject() === null) { 128 | throw new \LogicException(); 129 | } 130 | 131 | // create local copy of the asset 132 | $tempPath = $this->createTempCopy($path); 133 | 134 | // add to header/footer 135 | if ($this->headerFooterWrapper->getObject()) { 136 | $headerFooterAttributes = $this->headerFooterWrapper->getAttributes(); 137 | $location = ''; 138 | 139 | switch (strtolower($this->headerFooterWrapper->getAlignmentAttributes()['type'])) { 140 | case 'left': 141 | $location .= 'L'; 142 | $headerFooterAttributes['value']['left'] .= '&G'; 143 | break; 144 | case 'center': 145 | $location .= 'C'; 146 | $headerFooterAttributes['value']['center'] .= '&G'; 147 | break; 148 | case 'right': 149 | $location .= 'R'; 150 | $headerFooterAttributes['value']['right'] .= '&G'; 151 | break; 152 | default: 153 | throw new \InvalidArgumentException(sprintf('Unknown alignment type "%s"', $this->headerFooterWrapper->getAlignmentAttributes()['type'])); 154 | } 155 | 156 | switch (strtolower($headerFooterAttributes['type'])) { 157 | case 'header': 158 | case 'oddheader': 159 | case 'evenheader': 160 | case 'firstheader': 161 | $location .= 'H'; 162 | break; 163 | case 'footer': 164 | case 'oddfooter': 165 | case 'evenfooter': 166 | case 'firstfooter': 167 | $location .= 'F'; 168 | break; 169 | default: 170 | throw new \InvalidArgumentException(sprintf('Unknown type "%s"', $headerFooterAttributes['type'])); 171 | } 172 | 173 | $this->object = new \PHPExcel_Worksheet_HeaderFooterDrawing(); 174 | $this->object->setPath($tempPath); 175 | $this->headerFooterWrapper->getObject()->addImage($this->object, $location); 176 | $this->headerFooterWrapper->setAttributes($headerFooterAttributes); 177 | } 178 | 179 | // add to worksheet 180 | else { 181 | $this->object = new \PHPExcel_Worksheet_Drawing(); 182 | $this->object->setWorksheet($this->sheetWrapper->getObject()); 183 | $this->object->setPath($tempPath); 184 | } 185 | 186 | if ($properties !== null) { 187 | $this->setProperties($properties, $this->mappings); 188 | } 189 | } 190 | 191 | public function end() 192 | { 193 | $this->object = null; 194 | $this->attributes = []; 195 | } 196 | 197 | // 198 | // Helpers 199 | // 200 | 201 | /** 202 | * @param $path 203 | * @return string 204 | * @throws \RuntimeException 205 | * @throws \InvalidArgumentException 206 | */ 207 | private function createTempCopy($path) 208 | { 209 | // create temp path 210 | $pathExtension = pathinfo($path, PATHINFO_EXTENSION); 211 | $tempPath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'xlsdrawing' . '_' . md5($path) . ($pathExtension ? '.' . $pathExtension : ''); 212 | 213 | // create local copy 214 | if (!file_exists($tempPath)) { 215 | $data = file_get_contents($path); 216 | if ($data === false) { 217 | throw new \InvalidArgumentException($path . ' does not exist.'); 218 | } 219 | $temp = fopen($tempPath, 'w+'); 220 | if ($temp === false) { 221 | throw new \RuntimeException('Cannot open ' . $tempPath); 222 | } 223 | fwrite($temp, $data); 224 | if (fclose($temp) === false) { 225 | throw new \RuntimeException('Cannot close ' . $tempPath); 226 | } 227 | unset($data, $temp); 228 | } 229 | 230 | return $tempPath; 231 | } 232 | 233 | // 234 | // Getters/Setters 235 | // 236 | 237 | /** 238 | * @return array 239 | */ 240 | public function getMappings() 241 | { 242 | return $this->mappings; 243 | } 244 | 245 | /** 246 | * @param array $mappings 247 | */ 248 | public function setMappings($mappings) 249 | { 250 | $this->mappings = $mappings; 251 | } 252 | 253 | /** 254 | * @return \PHPExcel_Worksheet_Drawing|\PHPExcel_Worksheet_HeaderFooterDrawing 255 | */ 256 | public function getObject() 257 | { 258 | return $this->object; 259 | } 260 | 261 | /** 262 | * @param \PHPExcel_Worksheet_Drawing|\PHPExcel_Worksheet_HeaderFooterDrawing $object 263 | */ 264 | public function setObject($object) 265 | { 266 | $this->object = $object; 267 | } 268 | 269 | /** 270 | * @return array 271 | */ 272 | public function getAttributes() 273 | { 274 | return $this->attributes; 275 | } 276 | 277 | /** 278 | * @param array $attributes 279 | */ 280 | public function setAttributes($attributes) 281 | { 282 | $this->attributes = $attributes; 283 | } 284 | } 285 | -------------------------------------------------------------------------------- /Wrapper/XlsHeaderFooterWrapper.php: -------------------------------------------------------------------------------- 1 | context = $context; 53 | $this->environment = $environment; 54 | $this->sheetWrapper = $sheetWrapper; 55 | 56 | $this->alignmentAttributes = []; 57 | 58 | $this->object = null; 59 | $this->attributes = []; 60 | $this->mappings = []; 61 | 62 | $this->initializeMappings(); 63 | } 64 | 65 | protected function initializeMappings() 66 | { 67 | $this->mappings['scaleWithDocument'] = function ($value) { 68 | $this->object->setScaleWithDocument($value); 69 | }; 70 | $this->mappings['alignWithMargins'] = function ($value) { 71 | $this->object->setAlignWithMargins($value); 72 | }; 73 | } 74 | 75 | /** 76 | * @param string $type 77 | * @param null|array $properties 78 | * @throws \LogicException 79 | */ 80 | public function start($type, array $properties = null) 81 | { 82 | if ($this->sheetWrapper->getObject() === null) { 83 | throw new \LogicException(); 84 | } 85 | if (in_array(strtolower($type), 86 | ['header', 'oddheader', 'evenheader', 'firstheader', 'footer', 'oddfooter', 'evenfooter', 'firstfooter'], 87 | true) === false 88 | ) { 89 | throw new \InvalidArgumentException(sprintf('Unknown type "%s"', $type)); 90 | } 91 | 92 | $this->object = $this->sheetWrapper->getObject()->getHeaderFooter(); 93 | $this->attributes['value'] = ['left' => null, 'center' => null, 'right' => null]; // will be generated by the alignment tags 94 | $this->attributes['type'] = $type; 95 | $this->attributes['properties'] = $properties ?: []; 96 | 97 | if ($properties !== null) { 98 | $this->setProperties($properties, $this->mappings); 99 | } 100 | } 101 | 102 | public function end() 103 | { 104 | $value = implode('', $this->attributes['value']); 105 | 106 | switch (strtolower($this->attributes['type'])) { 107 | case 'header': 108 | $this->object->setOddHeader($value); 109 | $this->object->setEvenHeader($value); 110 | $this->object->setFirstHeader($value); 111 | break; 112 | case 'oddheader': 113 | $this->object->setDifferentOddEven(true); 114 | $this->object->setOddHeader($value); 115 | break; 116 | case 'evenheader': 117 | $this->object->setDifferentOddEven(true); 118 | $this->object->setEvenHeader($value); 119 | break; 120 | case 'firstheader': 121 | $this->object->setDifferentFirst(true); 122 | $this->object->setFirstHeader($value); 123 | break; 124 | case 'footer': 125 | $this->object->setOddFooter($value); 126 | $this->object->setEvenFooter($value); 127 | $this->object->setFirstFooter($value); 128 | break; 129 | case 'oddfooter': 130 | $this->object->setDifferentOddEven(true); 131 | $this->object->setOddFooter($value); 132 | break; 133 | case 'evenfooter': 134 | $this->object->setDifferentOddEven(true); 135 | $this->object->setEvenFooter($value); 136 | break; 137 | case 'firstfooter': 138 | $this->object->setDifferentFirst(true); 139 | $this->object->setFirstFooter($value); 140 | break; 141 | default: 142 | throw new \InvalidArgumentException(sprintf('Unknown type "%s"', $this->attributes['type'])); 143 | } 144 | 145 | $this->object = null; 146 | $this->attributes = []; 147 | } 148 | 149 | /** 150 | * @param null|string $type 151 | * @param null|array $properties 152 | * @throws \InvalidArgumentException 153 | */ 154 | public function startAlignment($type = null, array $properties = null) 155 | { 156 | $this->alignmentAttributes['type'] = $type; 157 | $this->alignmentAttributes['properties'] = $properties; 158 | 159 | switch (strtolower($this->alignmentAttributes['type'])) { 160 | case 'left': 161 | $this->attributes['value']['left'] = '&L'; 162 | break; 163 | case 'center': 164 | $this->attributes['value']['center'] = '&C'; 165 | break; 166 | case 'right': 167 | $this->attributes['value']['right'] = '&R'; 168 | break; 169 | default: 170 | throw new \InvalidArgumentException(sprintf('Unknown alignment type "%s"', $this->alignmentAttributes['type'])); 171 | } 172 | } 173 | 174 | /** 175 | * @param null|string $value 176 | * @throws \InvalidArgumentException 177 | */ 178 | public function endAlignment($value = null) 179 | { 180 | switch (strtolower($this->alignmentAttributes['type'])) { 181 | case 'left': 182 | if (strpos($this->attributes['value']['left'], '&G') === false) { 183 | $this->attributes['value']['left'] .= $value; 184 | } 185 | break; 186 | case 'center': 187 | if (strpos($this->attributes['value']['center'], '&G') === false) { 188 | $this->attributes['value']['center'] .= $value; 189 | } 190 | break; 191 | case 'right': 192 | if (strpos($this->attributes['value']['right'], '&G') === false) { 193 | $this->attributes['value']['right'] .= $value; 194 | } 195 | break; 196 | default: 197 | throw new \InvalidArgumentException(sprintf('Unknown alignment type "%s"', $this->alignmentAttributes['type'])); 198 | } 199 | 200 | $this->alignmentAttributes = []; 201 | } 202 | 203 | // 204 | // Getters/Setters 205 | // 206 | 207 | /** 208 | * @return \PHPExcel_Worksheet_HeaderFooter 209 | */ 210 | public function getObject() 211 | { 212 | return $this->object; 213 | } 214 | 215 | /** 216 | * @param \PHPExcel_Worksheet_HeaderFooter $object 217 | */ 218 | public function setObject($object) 219 | { 220 | $this->object = $object; 221 | } 222 | 223 | /** 224 | * @return array 225 | */ 226 | public function getAttributes() 227 | { 228 | return $this->attributes; 229 | } 230 | 231 | /** 232 | * @param array $attributes 233 | */ 234 | public function setAttributes($attributes) 235 | { 236 | $this->attributes = $attributes; 237 | } 238 | 239 | /** 240 | * @return array 241 | */ 242 | public function getMappings() 243 | { 244 | return $this->mappings; 245 | } 246 | 247 | /** 248 | * @param array $mappings 249 | */ 250 | public function setMappings($mappings) 251 | { 252 | $this->mappings = $mappings; 253 | } 254 | 255 | /** 256 | * @return array 257 | */ 258 | public function getAlignmentAttributes() 259 | { 260 | return $this->alignmentAttributes; 261 | } 262 | 263 | /** 264 | * @param array $alignmentAttributes 265 | */ 266 | public function setAlignmentAttributes($alignmentAttributes) 267 | { 268 | $this->alignmentAttributes = $alignmentAttributes; 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /Wrapper/XlsRowWrapper.php: -------------------------------------------------------------------------------- 1 | context = $context; 35 | $this->environment = $environment; 36 | $this->sheetWrapper = $sheetWrapper; 37 | } 38 | 39 | /** 40 | * @param null|int $index 41 | * @throws \LogicException 42 | */ 43 | public function start($index = null) 44 | { 45 | if ($this->sheetWrapper->getObject() === null) { 46 | throw new \LogicException(); 47 | } 48 | if ($index !== null && !is_int($index)) { 49 | throw new \InvalidArgumentException('Invalid index'); 50 | } 51 | 52 | if ($index === null) { 53 | $this->sheetWrapper->increaseRow(); 54 | } else { 55 | $this->sheetWrapper->setRow($index); 56 | } 57 | } 58 | 59 | public function end() 60 | { 61 | $this->sheetWrapper->setColumn(null); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Wrapper/XlsSheetWrapper.php: -------------------------------------------------------------------------------- 1 | context = $context; 68 | $this->environment = $environment; 69 | $this->documentWrapper = $documentWrapper; 70 | 71 | $this->row = null; 72 | $this->column = null; 73 | 74 | $this->object = null; 75 | $this->attributes = []; 76 | $this->mappings = []; 77 | 78 | $this->initializeMappings(); 79 | } 80 | 81 | protected function initializeMappings() 82 | { 83 | $this->mappings['autoFilter'] = function ($value) { 84 | $this->object->setAutoFilter($value); 85 | }; 86 | $this->mappings['columnDimension']['__multi'] = true; 87 | $this->mappings['columnDimension']['__object'] = function ($key = 'default') { 88 | return $key === 'default' ? $this->object->getDefaultColumnDimension() : $this->object->getColumnDimension($key); 89 | }; 90 | $this->mappings['columnDimension']['autoSize'] = function ($key, $value) { 91 | $this->mappings['columnDimension']['__object']($key)->setAutoSize($value); 92 | }; 93 | $this->mappings['columnDimension']['collapsed'] = function ($key, $value) { 94 | $this->mappings['columnDimension']['__object']($key)->setCollapsed($value); 95 | }; 96 | $this->mappings['columnDimension']['columnIndex'] = function ($key, $value) { 97 | $this->mappings['columnDimension']['__object']($key)->setColumnIndex($value); 98 | }; 99 | $this->mappings['columnDimension']['outlineLevel'] = function ($key, $value) { 100 | $this->mappings['columnDimension']['__object']($key)->setOutlineLevel($value); 101 | }; 102 | $this->mappings['columnDimension']['visible'] = function ($key, $value) { 103 | $this->mappings['columnDimension']['__object']($key)->setVisible($value); 104 | }; 105 | $this->mappings['columnDimension']['width'] = function ($key, $value) { 106 | $this->mappings['columnDimension']['__object']($key)->setWidth($value); 107 | }; 108 | $this->mappings['columnDimension']['xfIndex'] = function ($key, $value) { 109 | $this->mappings['columnDimension']['__object']($key)->setXfIndex($value); 110 | }; 111 | $this->mappings['pageMargins']['top'] = function ($value) { 112 | $this->object->getPageMargins()->setTop($value); 113 | }; 114 | $this->mappings['pageMargins']['bottom'] = function ($value) { 115 | $this->object->getPageMargins()->setBottom($value); 116 | }; 117 | $this->mappings['pageMargins']['left'] = function ($value) { 118 | $this->object->getPageMargins()->setLeft($value); 119 | }; 120 | $this->mappings['pageMargins']['right'] = function ($value) { 121 | $this->object->getPageMargins()->setRight($value); 122 | }; 123 | $this->mappings['pageMargins']['header'] = function ($value) { 124 | $this->object->getPageMargins()->setHeader($value); 125 | }; 126 | $this->mappings['pageMargins']['footer'] = function ($value) { 127 | $this->object->getPageMargins()->setFooter($value); 128 | }; 129 | $this->mappings['pageSetup']['fitToHeight'] = function ($value) { 130 | $this->object->getPageSetup()->setFitToHeight($value); 131 | }; 132 | $this->mappings['pageSetup']['fitToPage'] = function ($value) { 133 | $this->object->getPageSetup()->setFitToPage($value); 134 | }; 135 | $this->mappings['pageSetup']['fitToWidth'] = function ($value) { 136 | $this->object->getPageSetup()->setFitToWidth($value); 137 | }; 138 | $this->mappings['pageSetup']['horizontalCentered'] = function ($value) { 139 | $this->object->getPageSetup()->setHorizontalCentered($value); 140 | }; 141 | $this->mappings['pageSetup']['orientation'] = function ($value) { 142 | $this->object->getPageSetup()->setOrientation($value); 143 | }; 144 | $this->mappings['pageSetup']['paperSize'] = function ($value) { 145 | $this->object->getPageSetup()->setPaperSize($value); 146 | }; 147 | $this->mappings['pageSetup']['printArea'] = function ($value) { 148 | $this->object->getPageSetup()->setPrintArea($value); 149 | }; 150 | $this->mappings['pageSetup']['scale'] = function ($value) { 151 | $this->object->getPageSetup()->setScale($value); 152 | }; 153 | $this->mappings['pageSetup']['verticalCentered'] = function ($value) { 154 | $this->object->getPageSetup()->setVerticalCentered($value); 155 | }; 156 | $this->mappings['printGridlines'] = function ($value) { 157 | $this->object->setPrintGridlines($value); 158 | }; 159 | $this->mappings['protection']['autoFilter'] = function ($value) { 160 | $this->object->getProtection()->setAutoFilter($value); 161 | }; 162 | $this->mappings['protection']['deleteColumns'] = function ($value) { 163 | $this->object->getProtection()->setDeleteColumns($value); 164 | }; 165 | $this->mappings['protection']['deleteRows'] = function ($value) { 166 | $this->object->getProtection()->setDeleteRows($value); 167 | }; 168 | $this->mappings['protection']['formatCells'] = function ($value) { 169 | $this->object->getProtection()->setFormatCells($value); 170 | }; 171 | $this->mappings['protection']['formatColumns'] = function ($value) { 172 | $this->object->getProtection()->setFormatColumns($value); 173 | }; 174 | $this->mappings['protection']['formatRows'] = function ($value) { 175 | $this->object->getProtection()->setFormatRows($value); 176 | }; 177 | $this->mappings['protection']['insertColumns'] = function ($value) { 178 | $this->object->getProtection()->setInsertColumns($value); 179 | }; 180 | $this->mappings['protection']['insertHyperlinks'] = function ($value) { 181 | $this->object->getProtection()->setInsertHyperlinks($value); 182 | }; 183 | $this->mappings['protection']['insertRows'] = function ($value) { 184 | $this->object->getProtection()->setInsertRows($value); 185 | }; 186 | $this->mappings['protection']['objects'] = function ($value) { 187 | $this->object->getProtection()->setObjects($value); 188 | }; 189 | $this->mappings['protection']['password'] = function ($value) { 190 | $this->object->getProtection()->setPassword($value); 191 | }; 192 | $this->mappings['protection']['pivotTables'] = function ($value) { 193 | $this->object->getProtection()->setPivotTables($value); 194 | }; 195 | $this->mappings['protection']['scenarios'] = function ($value) { 196 | $this->object->getProtection()->setScenarios($value); 197 | }; 198 | $this->mappings['protection']['selectLockedCells'] = function ($value) { 199 | $this->object->getProtection()->setSelectLockedCells($value); 200 | }; 201 | $this->mappings['protection']['selectUnlockedCells'] = function ($value) { 202 | $this->object->getProtection()->setSelectUnlockedCells($value); 203 | }; 204 | $this->mappings['protection']['sheet'] = function ($value) { 205 | $this->object->getProtection()->setSheet($value); 206 | }; 207 | $this->mappings['protection']['sort'] = function ($value) { 208 | $this->object->getProtection()->setSort($value); 209 | }; 210 | $this->mappings['rightToLeft'] = function ($value) { 211 | $this->object->setRightToLeft($value); 212 | }; 213 | $this->mappings['rowDimension']['__multi'] = true; 214 | $this->mappings['rowDimension']['__object'] = function ($key) { 215 | return $key === 'default' ? $this->object->getDefaultRowDimension() : $this->object->getRowDimension($key); 216 | }; 217 | $this->mappings['rowDimension']['collapsed'] = function ($key, $value) { 218 | $this->mappings['rowDimension']['__object']($key)->setCollapsed($value); 219 | }; 220 | $this->mappings['rowDimension']['outlineLevel'] = function ($key, $value) { 221 | $this->mappings['rowDimension']['__object']($key)->setOutlineLevel($value); 222 | }; 223 | $this->mappings['rowDimension']['rowHeight'] = function ($key, $value) { 224 | $this->mappings['rowDimension']['__object']($key)->setRowHeight($value); 225 | }; 226 | $this->mappings['rowDimension']['rowIndex'] = function ($key, $value) { 227 | $this->mappings['rowDimension']['__object']($key)->setRowIndex($value); 228 | }; 229 | $this->mappings['rowDimension']['visible'] = function ($key, $value) { 230 | $this->mappings['rowDimension']['__object']($key)->setVisible($value); 231 | }; 232 | $this->mappings['rowDimension']['xfIndex'] = function ($key, $value) { 233 | $this->mappings['rowDimension']['__object']($key)->setXfIndex($value); 234 | }; 235 | $this->mappings['rowDimension']['zeroHeight'] = function ($key, $value) { 236 | $this->mappings['rowDimension']['__object']($key)->setZeroHeight($value); 237 | }; 238 | $this->mappings['sheetState'] = function ($value) { 239 | $this->object->setSheetState($value); 240 | }; 241 | $this->mappings['showGridlines'] = function ($value) { 242 | $this->object->setShowGridlines($value); 243 | }; 244 | $this->mappings['tabColor'] = function ($value) { 245 | $this->object->getTabColor()->setRGB($value); 246 | }; 247 | $this->mappings['zoomScale'] = function ($value) { 248 | $this->object->getSheetView()->setZoomScale($value); 249 | }; 250 | } 251 | 252 | /** 253 | * @param $index 254 | * @param array|null $properties 255 | * @throws \PHPExcel_Exception 256 | */ 257 | public function start($index, array $properties = null) 258 | { 259 | if (is_int($index) && $index <$this->documentWrapper->getObject()->getSheetCount()) { 260 | $this->object = $this->documentWrapper->getObject()->setActiveSheetIndex($index); 261 | } elseif (is_string($index)) { 262 | if (!$this->documentWrapper->getObject()->sheetNameExists($index)) { 263 | // create new sheet with a name 264 | $this->documentWrapper->getObject()->createSheet()->setTitle($index); 265 | } 266 | $this->object = $this->documentWrapper->getObject()->setActiveSheetIndexByName($index); 267 | } else { 268 | // create new sheet without a name 269 | $this->documentWrapper->getObject()->createSheet(); 270 | $this->object = $this->documentWrapper->getObject()->setActiveSheetIndex(0); 271 | } 272 | 273 | $this->attributes['index'] = $index; 274 | $this->attributes['properties'] = $properties ?: []; 275 | 276 | if ($properties !== null) { 277 | $this->setProperties($properties, $this->mappings); 278 | } 279 | } 280 | 281 | /** 282 | * @throws \PHPExcel_Reader_Exception 283 | * @throws \PHPExcel_Exception 284 | */ 285 | public function end() 286 | { 287 | // auto-size columns 288 | if ( 289 | true === isset($this->attributes['properties']['columnDimension']) && 290 | is_array($this->attributes['properties']['columnDimension']) 291 | ) { 292 | /** 293 | * @var array $columnDimension 294 | */ 295 | $columnDimension = $this->attributes['properties']['columnDimension']; 296 | foreach ($columnDimension as $key => $value) { 297 | if(true === is_array($value) && true === isset($value['autoSize'])) { 298 | if ('default' === $key) { 299 | try { 300 | /** 301 | * @var PHPExcel_Worksheet_RowCellIterator $cellIterator 302 | */ 303 | $cellIterator = $this->object->getRowIterator()->current()->getCellIterator(); 304 | $cellIterator->setIterateOnlyExistingCells(true); 305 | 306 | /** 307 | * @var PHPExcel_Cell $cell 308 | */ 309 | foreach ($cellIterator as $cell) { 310 | $this->object->getColumnDimension($cell->getColumn())->setAutoSize($value['autoSize']); 311 | } 312 | } catch (PHPExcel_Exception $e) { 313 | // ignore exceptions thrown when no cells are defined 314 | } 315 | } else { 316 | $this->object->getColumnDimension($key)->setAutoSize($value['autoSize']); 317 | } 318 | } 319 | } 320 | } 321 | 322 | $this->object = null; 323 | $this->attributes = []; 324 | $this->row = null; 325 | } 326 | 327 | // 328 | // Helpers 329 | // 330 | 331 | public function increaseRow() 332 | { 333 | $this->row = $this->row === null ? self::$ROW_DEFAULT : $this->row + 1; 334 | } 335 | 336 | public function increaseColumn() 337 | { 338 | $this->column = $this->column === null ? self::$COLUMN_DEFAULT : $this->column + 1; 339 | } 340 | 341 | // 342 | // Getters/Setters 343 | // 344 | 345 | /** 346 | * @return int|null 347 | */ 348 | public function getRow() 349 | { 350 | return $this->row; 351 | } 352 | 353 | /** 354 | * @param int|null $row 355 | */ 356 | public function setRow($row) 357 | { 358 | $this->row = $row; 359 | } 360 | 361 | /** 362 | * @return int|null 363 | */ 364 | public function getColumn() 365 | { 366 | return $this->column; 367 | } 368 | 369 | /** 370 | * @param int|null $column 371 | */ 372 | public function setColumn($column) 373 | { 374 | $this->column = $column; 375 | } 376 | 377 | /** 378 | * @return \PHPExcel_Worksheet 379 | */ 380 | public function getObject() 381 | { 382 | return $this->object; 383 | } 384 | 385 | /** 386 | * @param \PHPExcel_Worksheet $object 387 | */ 388 | public function setObject($object) 389 | { 390 | $this->object = $object; 391 | } 392 | 393 | /** 394 | * @return array 395 | */ 396 | public function getAttributes() 397 | { 398 | return $this->attributes; 399 | } 400 | 401 | /** 402 | * @param array $attributes 403 | */ 404 | public function setAttributes($attributes) 405 | { 406 | $this->attributes = $attributes; 407 | } 408 | 409 | /** 410 | * @return array 411 | */ 412 | public function getMappings() 413 | { 414 | return $this->mappings; 415 | } 416 | 417 | /** 418 | * @param array $mappings 419 | */ 420 | public function setMappings($mappings) 421 | { 422 | $this->mappings = $mappings; 423 | } 424 | } 425 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mewesk/twig-excel-bundle", 3 | "type": "symfony-bundle", 4 | "description": "This Symfony bundle provides a PhpExcel integration for Twig", 5 | "keywords": ["excel","phpexcel","twig","symfony"], 6 | "homepage": "https://github.com/MewesK/TwigExcelBundle", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Mewes Kochheim", 11 | "email": "mewes@kochheim.de" 12 | }, 13 | { 14 | "name": "Community Contributors", 15 | "homepage": "https://github.com/MewesK/TwigExcelBundle/graphs/contributors" 16 | } 17 | ], 18 | "require": { 19 | "php": "5.5.9 - 7.0", 20 | "symfony/framework-bundle": "~2.7|~3.0", 21 | "phpoffice/phpexcel": "~1.8.1" 22 | }, 23 | "require-dev": { 24 | "symfony/symfony": "~2.7|~3.0", 25 | "symfony/phpunit-bridge": "~3.0", 26 | "sensio/framework-extra-bundle": "~3.0", 27 | "mpdf/mpdf": "~6.0" 28 | }, 29 | "minimum-stability": "dev", 30 | "suggest": { 31 | "mpdf/mpdf": "Add support for PDF rendering, requires ~6.0" 32 | }, 33 | "autoload": { 34 | "psr-4": { "MewesK\\TwigExcelBundle\\": "" } 35 | }, 36 | "extra": { 37 | "branch-alias": { 38 | "dev-master": "2.x-dev" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /phpunit.coverage.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ./Tests/ 18 | 19 | 20 | 21 | 22 | 23 | ./ 24 | 25 | ./Resources 26 | ./Tests 27 | ./vendor 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | ./Tests/ 17 | 18 | 19 | 20 | 21 | 22 | ./ 23 | 24 | ./Resources 25 | ./Tests 26 | ./vendor 27 | 28 | 29 | 30 | 31 | --------------------------------------------------------------------------------