ReferenceHelperTest.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. <?php
  2. namespace PhpOffice\PhpSpreadsheetTests;
  3. use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
  4. use PhpOffice\PhpSpreadsheet\Cell\DataType;
  5. use PhpOffice\PhpSpreadsheet\Cell\Hyperlink;
  6. use PhpOffice\PhpSpreadsheet\Comment;
  7. use PhpOffice\PhpSpreadsheet\NamedFormula;
  8. use PhpOffice\PhpSpreadsheet\NamedRange;
  9. use PhpOffice\PhpSpreadsheet\ReferenceHelper;
  10. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  11. use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\Wizard;
  12. use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
  13. use PHPUnit\Framework\TestCase;
  14. class ReferenceHelperTest extends TestCase
  15. {
  16. protected function setUp(): void
  17. {
  18. }
  19. public function testColumnSort(): void
  20. {
  21. $columnBase = $columnExpectedResult = [
  22. 'A', 'B', 'Z',
  23. 'AA', 'AB', 'AZ',
  24. 'BA', 'BB', 'BZ',
  25. 'ZA', 'ZB', 'ZZ',
  26. 'AAA', 'AAB', 'AAZ',
  27. 'ABA', 'ABB', 'ABZ',
  28. 'AZA', 'AZB', 'AZZ',
  29. 'BAA', 'BAB', 'BAZ',
  30. 'BBA', 'BBB', 'BBZ',
  31. 'BZA', 'BZB', 'BZZ',
  32. ];
  33. shuffle($columnBase);
  34. usort($columnBase, [ReferenceHelper::class, 'columnSort']);
  35. foreach ($columnBase as $key => $value) {
  36. self::assertEquals($columnExpectedResult[$key], $value);
  37. }
  38. }
  39. public function testColumnReverseSort(): void
  40. {
  41. $columnBase = $columnExpectedResult = [
  42. 'A', 'B', 'Z',
  43. 'AA', 'AB', 'AZ',
  44. 'BA', 'BB', 'BZ',
  45. 'ZA', 'ZB', 'ZZ',
  46. 'AAA', 'AAB', 'AAZ',
  47. 'ABA', 'ABB', 'ABZ',
  48. 'AZA', 'AZB', 'AZZ',
  49. 'BAA', 'BAB', 'BAZ',
  50. 'BBA', 'BBB', 'BBZ',
  51. 'BZA', 'BZB', 'BZZ',
  52. ];
  53. shuffle($columnBase);
  54. $columnExpectedResult = array_reverse($columnExpectedResult);
  55. usort($columnBase, [ReferenceHelper::class, 'columnReverseSort']);
  56. foreach ($columnBase as $key => $value) {
  57. self::assertEquals($columnExpectedResult[$key], $value);
  58. }
  59. }
  60. public function testCellSort(): void
  61. {
  62. $cellBase = $columnExpectedResult = [
  63. 'A1', 'B1', 'AZB1',
  64. 'BBB1', 'BB2', 'BAB2',
  65. 'BZA2', 'Z3', 'AZA3',
  66. 'BZB3', 'AB5', 'AZ6',
  67. 'ABZ7', 'BA9', 'BZ9',
  68. 'AAA9', 'AAZ9', 'BA10',
  69. 'BZZ10', 'ZA11', 'AAB11',
  70. 'BBZ29', 'BAA32', 'ZZ43',
  71. 'AZZ43', 'BAZ67', 'ZB78',
  72. 'ABA121', 'ABB289', 'BBA544',
  73. ];
  74. shuffle($cellBase);
  75. usort($cellBase, [ReferenceHelper::class, 'cellSort']);
  76. foreach ($cellBase as $key => $value) {
  77. self::assertEquals($columnExpectedResult[$key], $value);
  78. }
  79. }
  80. public function testCellReverseSort(): void
  81. {
  82. $cellBase = $columnExpectedResult = [
  83. 'BBA544', 'ABB289', 'ABA121',
  84. 'ZB78', 'BAZ67', 'AZZ43',
  85. 'ZZ43', 'BAA32', 'BBZ29',
  86. 'AAB11', 'ZA11', 'BZZ10',
  87. 'BA10', 'AAZ9', 'AAA9',
  88. 'BZ9', 'BA9', 'ABZ7',
  89. 'AZ6', 'AB5', 'BZB3',
  90. 'AZA3', 'Z3', 'BZA2',
  91. 'BAB2', 'BB2', 'BBB1',
  92. 'AZB1', 'B1', 'A1',
  93. ];
  94. shuffle($cellBase);
  95. usort($cellBase, [ReferenceHelper::class, 'cellReverseSort']);
  96. foreach ($cellBase as $key => $value) {
  97. self::assertEquals($columnExpectedResult[$key], $value);
  98. }
  99. }
  100. /**
  101. * @dataProvider providerFormulaUpdates
  102. */
  103. public function testUpdateFormula(string $formula, int $insertRows, int $insertColumns, string $worksheet, string $expectedResult): void
  104. {
  105. $referenceHelper = ReferenceHelper::getInstance();
  106. $result = $referenceHelper->updateFormulaReferences($formula, 'A1', $insertRows, $insertColumns, $worksheet);
  107. self::assertSame($expectedResult, $result);
  108. }
  109. public function providerFormulaUpdates(): array
  110. {
  111. return require 'tests/data/ReferenceHelperFormulaUpdates.php';
  112. }
  113. /**
  114. * @dataProvider providerMultipleWorksheetFormulaUpdates
  115. */
  116. public function testUpdateFormulaForMultipleWorksheets(string $formula, int $insertRows, int $insertColumns, string $expectedResult): void
  117. {
  118. $referenceHelper = ReferenceHelper::getInstance();
  119. $result = $referenceHelper->updateFormulaReferencesAnyWorksheet($formula, $insertRows, $insertColumns);
  120. self::assertSame($expectedResult, $result);
  121. }
  122. public function providerMultipleWorksheetFormulaUpdates(): array
  123. {
  124. return require 'tests/data/ReferenceHelperFormulaUpdatesMultipleSheet.php';
  125. }
  126. public function testInsertNewBeforeRetainDataType(): void
  127. {
  128. $spreadsheet = new Spreadsheet();
  129. $sheet = $spreadsheet->getActiveSheet();
  130. $cell = $sheet->getCell('A1');
  131. $cell->setValueExplicit('+1', DataType::TYPE_STRING);
  132. $oldDataType = $cell->getDataType();
  133. $oldValue = $cell->getValue();
  134. $sheet->insertNewRowBefore(1);
  135. $newCell = $sheet->getCell('A2');
  136. $newDataType = $newCell->getDataType();
  137. $newValue = $newCell->getValue();
  138. self::assertSame($oldValue, $newValue);
  139. self::assertSame($oldDataType, $newDataType);
  140. }
  141. public function testRemoveColumnShiftsCorrectColumnValueIntoRemovedColumnCoordinates(): void
  142. {
  143. $spreadsheet = new Spreadsheet();
  144. $sheet = $spreadsheet->getActiveSheet();
  145. $sheet->fromArray([
  146. ['a1', 'b1', 'c1'],
  147. ['a2', 'b2', null],
  148. ]);
  149. $cells = $sheet->toArray();
  150. self::assertSame('a1', $cells[0][0]);
  151. self::assertSame('b1', $cells[0][1]);
  152. self::assertSame('c1', $cells[0][2]);
  153. self::assertSame('a2', $cells[1][0]);
  154. self::assertSame('b2', $cells[1][1]);
  155. self::assertNull($cells[1][2]);
  156. $sheet->removeColumn('B');
  157. $cells = $sheet->toArray();
  158. self::assertSame('a1', $cells[0][0]);
  159. self::assertSame('c1', $cells[0][1]);
  160. self::assertArrayNotHasKey(2, $cells[0]);
  161. self::assertSame('a2', $cells[1][0]);
  162. self::assertNull($cells[1][1]);
  163. self::assertArrayNotHasKey(2, $cells[1]);
  164. }
  165. public function testInsertRowsWithPageBreaks(): void
  166. {
  167. $spreadsheet = new Spreadsheet();
  168. $sheet = $spreadsheet->getActiveSheet();
  169. $sheet->fromArray([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]], null, 'A1', true);
  170. $sheet->setBreak('A2', Worksheet::BREAK_ROW);
  171. $sheet->setBreak('A5', Worksheet::BREAK_ROW);
  172. $sheet->insertNewRowBefore(2, 2);
  173. $breaks = $sheet->getBreaks();
  174. ksort($breaks);
  175. self::assertSame(['A4' => Worksheet::BREAK_ROW, 'A7' => Worksheet::BREAK_ROW], $breaks);
  176. }
  177. public function testDeleteRowsWithPageBreaks(): void
  178. {
  179. $spreadsheet = new Spreadsheet();
  180. $sheet = $spreadsheet->getActiveSheet();
  181. $sheet->fromArray([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]], null, 'A1', true);
  182. $sheet->setBreak('A2', Worksheet::BREAK_ROW);
  183. $sheet->setBreak('A5', Worksheet::BREAK_ROW);
  184. $sheet->removeRow(2, 2);
  185. $breaks = $sheet->getBreaks();
  186. self::assertSame(['A3' => Worksheet::BREAK_ROW], $breaks);
  187. }
  188. public function testInsertRowsWithComments(): void
  189. {
  190. $spreadsheet = new Spreadsheet();
  191. $sheet = $spreadsheet->getActiveSheet();
  192. $sheet->fromArray([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]], null, 'A1', true);
  193. $sheet->getComment('A2')->getText()->createText('First Comment');
  194. $sheet->getComment('A5')->getText()->createText('Second Comment');
  195. $sheet->insertNewRowBefore(2, 2);
  196. $comments = array_map(
  197. function (Comment $value) {
  198. return $value->getText()->getPlainText();
  199. },
  200. $sheet->getComments()
  201. );
  202. self::assertSame(['A4' => 'First Comment', 'A7' => 'Second Comment'], $comments);
  203. }
  204. public function testDeleteRowsWithComments(): void
  205. {
  206. $spreadsheet = new Spreadsheet();
  207. $sheet = $spreadsheet->getActiveSheet();
  208. $sheet->fromArray([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]], null, 'A1', true);
  209. $sheet->getComment('A2')->getText()->createText('First Comment');
  210. $sheet->getComment('A5')->getText()->createText('Second Comment');
  211. $sheet->removeRow(2, 2);
  212. $comments = array_map(
  213. function (Comment $value) {
  214. return $value->getText()->getPlainText();
  215. },
  216. $sheet->getComments()
  217. );
  218. self::assertSame(['A3' => 'Second Comment'], $comments);
  219. }
  220. public function testInsertRowsWithHyperlinks(): void
  221. {
  222. $spreadsheet = new Spreadsheet();
  223. $sheet = $spreadsheet->getActiveSheet();
  224. $sheet->fromArray([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]], null, 'A1', true);
  225. $sheet->getCell('A2')->getHyperlink()->setUrl('https://github.com/PHPOffice/PhpSpreadsheet');
  226. $sheet->getCell('A5')->getHyperlink()->setUrl('https://phpspreadsheet.readthedocs.io/en/latest/');
  227. $sheet->insertNewRowBefore(2, 2);
  228. $hyperlinks = array_map(
  229. function (Hyperlink $value) {
  230. return $value->getUrl();
  231. },
  232. $sheet->getHyperlinkCollection()
  233. );
  234. ksort($hyperlinks);
  235. self::assertSame(
  236. [
  237. 'A4' => 'https://github.com/PHPOffice/PhpSpreadsheet',
  238. 'A7' => 'https://phpspreadsheet.readthedocs.io/en/latest/',
  239. ],
  240. $hyperlinks
  241. );
  242. }
  243. public function testDeleteRowsWithHyperlinks(): void
  244. {
  245. $spreadsheet = new Spreadsheet();
  246. $sheet = $spreadsheet->getActiveSheet();
  247. $sheet->fromArray([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]], null, 'A1', true);
  248. $sheet->getCell('A2')->getHyperlink()->setUrl('https://github.com/PHPOffice/PhpSpreadsheet');
  249. $sheet->getCell('A5')->getHyperlink()->setUrl('https://phpspreadsheet.readthedocs.io/en/latest/');
  250. $sheet->removeRow(2, 2);
  251. $hyperlinks = array_map(
  252. function (Hyperlink $value) {
  253. return $value->getUrl();
  254. },
  255. $sheet->getHyperlinkCollection()
  256. );
  257. self::assertSame(['A3' => 'https://phpspreadsheet.readthedocs.io/en/latest/'], $hyperlinks);
  258. }
  259. public function testInsertRowsWithDataValidation(): void
  260. {
  261. $spreadsheet = new Spreadsheet();
  262. $sheet = $spreadsheet->getActiveSheet();
  263. $sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
  264. $cellAddress = 'E5';
  265. $this->setDataValidation($sheet, $cellAddress);
  266. $sheet->insertNewRowBefore(2, 2);
  267. self::assertFalse($sheet->getCell($cellAddress)->hasDataValidation());
  268. self::assertTrue($sheet->getCell('E7')->hasDataValidation());
  269. self::assertSame('E7', $sheet->getDataValidation('E7')->getSqref());
  270. }
  271. public function testDeleteRowsWithDataValidation(): void
  272. {
  273. $spreadsheet = new Spreadsheet();
  274. $sheet = $spreadsheet->getActiveSheet();
  275. $sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
  276. $cellAddress = 'E5';
  277. $this->setDataValidation($sheet, $cellAddress);
  278. $sheet->removeRow(2, 2);
  279. self::assertFalse($sheet->getCell($cellAddress)->hasDataValidation());
  280. self::assertTrue($sheet->getCell('E3')->hasDataValidation());
  281. self::assertSame('E3', $sheet->getDataValidation('E3')->getSqref());
  282. }
  283. public function testDeleteColumnsWithDataValidation(): void
  284. {
  285. $spreadsheet = new Spreadsheet();
  286. $sheet = $spreadsheet->getActiveSheet();
  287. $sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
  288. $cellAddress = 'E5';
  289. $this->setDataValidation($sheet, $cellAddress);
  290. $sheet->removeColumn('B', 2);
  291. self::assertFalse($sheet->getCell($cellAddress)->hasDataValidation());
  292. self::assertTrue($sheet->getCell('C5')->hasDataValidation());
  293. self::assertSame('C5', $sheet->getDataValidation('C5')->getSqref());
  294. }
  295. public function testInsertColumnsWithDataValidation(): void
  296. {
  297. $spreadsheet = new Spreadsheet();
  298. $sheet = $spreadsheet->getActiveSheet();
  299. $sheet->fromArray([['First'], ['Second'], ['Third'], ['Fourth']], null, 'A5', true);
  300. $cellAddress = 'E5';
  301. $this->setDataValidation($sheet, $cellAddress);
  302. $sheet->insertNewColumnBefore('C', 2);
  303. self::assertFalse($sheet->getCell($cellAddress)->hasDataValidation());
  304. self::assertTrue($sheet->getCell('G5')->hasDataValidation());
  305. self::assertSame('G5', $sheet->getDataValidation('G5')->getSqref());
  306. }
  307. private function setDataValidation(Worksheet $sheet, string $cellAddress): void
  308. {
  309. $validation = $sheet->getCell($cellAddress)
  310. ->getDataValidation();
  311. $validation->setType(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::TYPE_LIST);
  312. $validation->setErrorStyle(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::STYLE_INFORMATION);
  313. $validation->setAllowBlank(false);
  314. $validation->setShowInputMessage(true);
  315. $validation->setShowErrorMessage(true);
  316. $validation->setShowDropDown(true);
  317. $validation->setErrorTitle('Input error');
  318. $validation->setError('Value is not in list.');
  319. $validation->setPromptTitle('Pick from list');
  320. $validation->setPrompt('Please pick a value from the drop-down list.');
  321. $validation->setFormula1('$A5:$A8');
  322. }
  323. public function testInsertRowsWithConditionalFormatting(): void
  324. {
  325. $spreadsheet = new Spreadsheet();
  326. $sheet = $spreadsheet->getActiveSheet();
  327. $sheet->fromArray([[1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7, 8], [7, 8, 9, 10], [9, 10, 11, 12]], null, 'C3', true);
  328. $sheet->getCell('H5')->setValue(5);
  329. $cellRange = 'C3:F7';
  330. $this->setConditionalFormatting($sheet, $cellRange);
  331. $sheet->insertNewRowBefore(4, 2);
  332. $styles = $sheet->getConditionalStylesCollection();
  333. // verify that the conditional range has been updated
  334. self::assertSame('C3:F9', array_keys($styles)[0]);
  335. // verify that the conditions have been updated
  336. foreach ($styles as $style) {
  337. foreach ($style as $conditions) {
  338. self::assertSame('$H$7', $conditions->getConditions()[0]);
  339. }
  340. }
  341. }
  342. public function testInsertColumnssWithConditionalFormatting(): void
  343. {
  344. $spreadsheet = new Spreadsheet();
  345. $sheet = $spreadsheet->getActiveSheet();
  346. $sheet->fromArray([[1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7, 8], [7, 8, 9, 10], [9, 10, 11, 12]], null, 'C3', true);
  347. $sheet->getCell('H5')->setValue(5);
  348. $cellRange = 'C3:F7';
  349. $this->setConditionalFormatting($sheet, $cellRange);
  350. $sheet->insertNewColumnBefore('C', 2);
  351. $styles = $sheet->getConditionalStylesCollection();
  352. // verify that the conditional range has been updated
  353. self::assertSame('E3:H7', array_keys($styles)[0]);
  354. // verify that the conditions have been updated
  355. foreach ($styles as $style) {
  356. foreach ($style as $conditions) {
  357. self::assertSame('$J$5', $conditions->getConditions()[0]);
  358. }
  359. }
  360. }
  361. public function testDeleteRowsWithConditionalFormatting(): void
  362. {
  363. $spreadsheet = new Spreadsheet();
  364. $sheet = $spreadsheet->getActiveSheet();
  365. $sheet->fromArray([[1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7, 8], [7, 8, 9, 10], [9, 10, 11, 12]], null, 'C3', true);
  366. $sheet->getCell('H5')->setValue(5);
  367. $cellRange = 'C3:F7';
  368. $this->setConditionalFormatting($sheet, $cellRange);
  369. $sheet->removeRow(4, 2);
  370. $styles = $sheet->getConditionalStylesCollection();
  371. // verify that the conditional range has been updated
  372. self::assertSame('C3:F5', array_keys($styles)[0]);
  373. // verify that the conditions have been updated
  374. foreach ($styles as $style) {
  375. foreach ($style as $conditions) {
  376. self::assertSame('$H$5', $conditions->getConditions()[0]);
  377. }
  378. }
  379. }
  380. public function testDeleteColumnsWithConditionalFormatting(): void
  381. {
  382. $spreadsheet = new Spreadsheet();
  383. $sheet = $spreadsheet->getActiveSheet();
  384. $sheet->fromArray([[1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7, 8], [7, 8, 9, 10], [9, 10, 11, 12]], null, 'C3', true);
  385. $sheet->getCell('H5')->setValue(5);
  386. $cellRange = 'C3:F7';
  387. $this->setConditionalFormatting($sheet, $cellRange);
  388. $sheet->removeColumn('D', 2);
  389. $styles = $sheet->getConditionalStylesCollection();
  390. // verify that the conditional range has been updated
  391. self::assertSame('C3:D7', array_keys($styles)[0]);
  392. // verify that the conditions have been updated
  393. foreach ($styles as $style) {
  394. foreach ($style as $conditions) {
  395. self::assertSame('$F$5', $conditions->getConditions()[0]);
  396. }
  397. }
  398. }
  399. private function setConditionalFormatting(Worksheet $sheet, string $cellRange): void
  400. {
  401. $conditionalStyles = [];
  402. $wizardFactory = new Wizard($cellRange);
  403. /** @var Wizard\CellValue $cellWizard */
  404. $cellWizard = $wizardFactory->newRule(Wizard::CELL_VALUE);
  405. $cellWizard->equals('$H$5', Wizard::VALUE_TYPE_CELL);
  406. $conditionalStyles[] = $cellWizard->getConditional();
  407. $cellWizard->greaterThan('$H$5', Wizard::VALUE_TYPE_CELL);
  408. $conditionalStyles[] = $cellWizard->getConditional();
  409. $cellWizard->lessThan('$H$5', Wizard::VALUE_TYPE_CELL);
  410. $conditionalStyles[] = $cellWizard->getConditional();
  411. $sheet->getStyle($cellWizard->getCellRange())
  412. ->setConditionalStyles($conditionalStyles);
  413. }
  414. public function testInsertRowsWithPrintArea(): void
  415. {
  416. $spreadsheet = new Spreadsheet();
  417. $sheet = $spreadsheet->getActiveSheet();
  418. $sheet->getPageSetup()->setPrintArea('A1:J10');
  419. $sheet->insertNewRowBefore(2, 2);
  420. $printArea = $sheet->getPageSetup()->getPrintArea();
  421. self::assertSame('A1:J12', $printArea);
  422. }
  423. public function testInsertColumnsWithPrintArea(): void
  424. {
  425. $spreadsheet = new Spreadsheet();
  426. $sheet = $spreadsheet->getActiveSheet();
  427. $sheet->getPageSetup()->setPrintArea('A1:J10');
  428. $sheet->insertNewColumnBefore('B', 2);
  429. $printArea = $sheet->getPageSetup()->getPrintArea();
  430. self::assertSame('A1:L10', $printArea);
  431. }
  432. public function testDeleteRowsWithPrintArea(): void
  433. {
  434. $spreadsheet = new Spreadsheet();
  435. $sheet = $spreadsheet->getActiveSheet();
  436. $sheet->getPageSetup()->setPrintArea('A1:J10');
  437. $sheet->removeRow(2, 2);
  438. $printArea = $sheet->getPageSetup()->getPrintArea();
  439. self::assertSame('A1:J8', $printArea);
  440. }
  441. public function testDeleteColumnsWithPrintArea(): void
  442. {
  443. $spreadsheet = new Spreadsheet();
  444. $sheet = $spreadsheet->getActiveSheet();
  445. $sheet->getPageSetup()->setPrintArea('A1:J10');
  446. $sheet->removeColumn('B', 2);
  447. $printArea = $sheet->getPageSetup()->getPrintArea();
  448. self::assertSame('A1:H10', $printArea);
  449. }
  450. public function testInsertRowsWithDefinedNames(): void
  451. {
  452. $spreadsheet = $this->buildDefinedNamesTestWorkbook();
  453. /** @var Worksheet $dataSheet */
  454. $dataSheet = $spreadsheet->getSheetByName('Data');
  455. /** @var Worksheet $totalsSheet */
  456. $totalsSheet = $spreadsheet->getSheetByName('Totals');
  457. $dataSheet->insertNewRowBefore(4, 2);
  458. Calculation::getInstance($spreadsheet)->flushInstance();
  459. /** @var NamedRange $firstColumn */
  460. $firstColumn = $spreadsheet->getNamedRange('FirstColumn');
  461. /** @var NamedRange $secondColumn */
  462. $secondColumn = $spreadsheet->getNamedRange('SecondColumn');
  463. self::assertSame('=Data!$A$2:$A8', $firstColumn->getRange());
  464. self::assertSame('=Data!B$2:B8', $secondColumn->getRange());
  465. self::assertSame(30, $totalsSheet->getCell('A20')->getCalculatedValue());
  466. self::assertSame(25, $totalsSheet->getCell('B20')->getCalculatedValue());
  467. self::assertSame(750, $totalsSheet->getCell('D20')->getCalculatedValue());
  468. }
  469. public function testInsertColumnsWithDefinedNames(): void
  470. {
  471. $spreadsheet = $this->buildDefinedNamesTestWorkbook();
  472. /** @var Worksheet $dataSheet */
  473. $dataSheet = $spreadsheet->getSheetByName('Data');
  474. /** @var Worksheet $totalsSheet */
  475. $totalsSheet = $spreadsheet->getSheetByName('Totals');
  476. $dataSheet->insertNewColumnBefore('B', 2);
  477. Calculation::getInstance($spreadsheet)->flushInstance();
  478. /** @var NamedRange $firstColumn */
  479. $firstColumn = $spreadsheet->getNamedRange('FirstColumn');
  480. /** @var NamedRange $secondColumn */
  481. $secondColumn = $spreadsheet->getNamedRange('SecondColumn');
  482. self::assertSame('=Data!$A$2:$A6', $firstColumn->getRange());
  483. self::assertSame('=Data!D$2:D6', $secondColumn->getRange());
  484. self::assertSame(30, $totalsSheet->getCell('A20')->getCalculatedValue());
  485. self::assertSame(25, $totalsSheet->getCell('B20')->getCalculatedValue());
  486. self::assertSame(750, $totalsSheet->getCell('D20')->getCalculatedValue());
  487. }
  488. public function testDeleteRowsWithDefinedNames(): void
  489. {
  490. $spreadsheet = $this->buildDefinedNamesTestWorkbook();
  491. /** @var Worksheet $dataSheet */
  492. $dataSheet = $spreadsheet->getSheetByName('Data');
  493. /** @var Worksheet $totalsSheet */
  494. $totalsSheet = $spreadsheet->getSheetByName('Totals');
  495. $dataSheet->removeRow(3, 2);
  496. Calculation::getInstance($spreadsheet)->flushInstance();
  497. /** @var NamedRange $firstColumn */
  498. $firstColumn = $spreadsheet->getNamedRange('FirstColumn');
  499. /** @var NamedRange $secondColumn */
  500. $secondColumn = $spreadsheet->getNamedRange('SecondColumn');
  501. self::assertSame('=Data!$A$2:$A4', $firstColumn->getRange());
  502. self::assertSame('=Data!B$2:B4', $secondColumn->getRange());
  503. self::assertSame(20, $totalsSheet->getCell('A20')->getCalculatedValue());
  504. self::assertSame(17, $totalsSheet->getCell('B20')->getCalculatedValue());
  505. self::assertSame(340, $totalsSheet->getCell('D20')->getCalculatedValue());
  506. }
  507. private function buildDefinedNamesTestWorkbook(): Spreadsheet
  508. {
  509. $spreadsheet = new Spreadsheet();
  510. $dataSheet = $spreadsheet->getActiveSheet();
  511. $dataSheet->setTitle('Data');
  512. $totalsSheet = $spreadsheet->addSheet(new Worksheet());
  513. $totalsSheet->setTitle('Totals');
  514. $spreadsheet->setActiveSheetIndexByName('Data');
  515. $dataSheet->fromArray([['Column 1', 'Column 2'], [2, 1], [4, 3], [6, 5], [8, 7], [10, 9]], null, 'A1', true);
  516. $spreadsheet->addNamedRange(
  517. new NamedRange('FirstColumn', $spreadsheet->getActiveSheet(), '=Data!$A$2:$A6')
  518. );
  519. $spreadsheet->addNamedFormula(
  520. new NamedFormula('FirstTotal', $spreadsheet->getActiveSheet(), '=SUM(FirstColumn)')
  521. );
  522. $totalsSheet->setCellValue('A20', '=FirstTotal');
  523. $spreadsheet->addNamedRange(
  524. new NamedRange('SecondColumn', $spreadsheet->getActiveSheet(), '=Data!B$2:B6')
  525. );
  526. $spreadsheet->addNamedFormula(
  527. new NamedFormula('SecondTotal', $spreadsheet->getActiveSheet(), '=SUM(SecondColumn)')
  528. );
  529. $totalsSheet->setCellValue('B20', '=SecondTotal');
  530. $spreadsheet->addNamedFormula(
  531. new NamedFormula('ProductTotal', $spreadsheet->getActiveSheet(), '=FirstTotal*SecondTotal')
  532. );
  533. $totalsSheet->setCellValue('D20', '=ProductTotal');
  534. return $spreadsheet;
  535. }
  536. }