XlfnFunctionsTest.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <?php
  2. namespace PhpOffice\PhpSpreadsheetTests\Calculation;
  3. use PhpOffice\PhpSpreadsheet\Shared\File;
  4. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  5. use PhpOffice\PhpSpreadsheet\Style\Color;
  6. use PhpOffice\PhpSpreadsheet\Style\Conditional;
  7. use PhpOffice\PhpSpreadsheet\Style\Fill;
  8. class XlfnFunctionsTest extends \PHPUnit\Framework\TestCase
  9. {
  10. public function testXlfn(): void
  11. {
  12. $formulas = [
  13. // null indicates function not implemented in Calculation engine
  14. ['2010', 'A1', '=MODE.SNGL({5.6,4,4,3,2,4})', '=_xlfn.MODE.SNGL({5.6,4,4,3,2,4})', 4],
  15. ['2010', 'A2', '=MODE.SNGL({"x","y"})', '=_xlfn.MODE.SNGL({"x","y"})', '#N/A'],
  16. ['2013', 'A1', '=ISOWEEKNUM("2019-12-19")', '=_xlfn.ISOWEEKNUM("2019-12-19")', 51],
  17. ['2013', 'A2', '=SHEET("2019")', '=_xlfn.SHEET("2019")', null],
  18. ['2013', 'A3', '2019-01-04', '2019-01-04', null],
  19. ['2013', 'A4', '2019-07-04', '2019-07-04', null],
  20. ['2013', 'A5', '2019-12-04', '2019-12-04', null],
  21. ['2013', 'B3', 1, 1, null],
  22. ['2013', 'B4', 2, 2, null],
  23. ['2013', 'B5', -3, -3, null],
  24. // multiple xlfn functions interleaved with non-xlfn
  25. ['2013', 'C3', '=ISOWEEKNUM(A3)+WEEKNUM(A4)+ISOWEEKNUM(A5)', '=_xlfn.ISOWEEKNUM(A3)+WEEKNUM(A4)+_xlfn.ISOWEEKNUM(A5)', 77],
  26. ['2016', 'A1', '=SWITCH(WEEKDAY("2019-12-22",1),1,"Sunday",2,"Monday","No Match")', '=_xlfn.SWITCH(WEEKDAY("2019-12-22",1),1,"Sunday",2,"Monday","No Match")', 'Sunday'],
  27. ['2016', 'B1', '=SWITCH(WEEKDAY("2019-12-20",1),1,"Sunday",2,"Monday","No Match")', '=_xlfn.SWITCH(WEEKDAY("2019-12-20",1),1,"Sunday",2,"Monday","No Match")', 'No Match'],
  28. ['2019', 'A1', '=CONCAT("The"," ","sun"," ","will"," ","come"," ","up"," ","tomorrow.")', '=_xlfn.CONCAT("The"," ","sun"," ","will"," ","come"," ","up"," ","tomorrow.")', 'The sun will come up tomorrow.'],
  29. ];
  30. $workbook = new Spreadsheet();
  31. $sheet = $workbook->getActiveSheet();
  32. $sheet->setTitle('2010');
  33. $sheet = $workbook->createSheet();
  34. $sheet->setTitle('2013');
  35. $sheet = $workbook->createSheet();
  36. $sheet->setTitle('2016');
  37. $sheet = $workbook->createSheet();
  38. $sheet->setTitle('2019');
  39. foreach ($formulas as $values) {
  40. $sheet = $workbook->setActiveSheetIndexByName($values[0]);
  41. $sheet->setCellValue($values[1], $values[2]);
  42. }
  43. $sheet = $workbook->setActiveSheetIndexByName('2013');
  44. $sheet->getStyle('A3:A5')->getNumberFormat()->setFormatCode('yyyy-mm-dd');
  45. $sheet->getColumnDimension('A')->setAutoSize(true);
  46. $condition0 = new Conditional();
  47. $condition0->setConditionType(Conditional::CONDITION_EXPRESSION);
  48. $condition0->addCondition('ABS(B3)<2');
  49. $condition0->getStyle()->getFill()->setFillType(Fill::FILL_SOLID);
  50. $condition0->getStyle()->getFill()->getEndColor()->setARGB(Color::COLOR_RED);
  51. $condition1 = new Conditional();
  52. $condition1->setConditionType(Conditional::CONDITION_EXPRESSION);
  53. $condition1->addCondition('ABS(B3)>2');
  54. $condition1->getStyle()->getFill()->setFillType(Fill::FILL_SOLID);
  55. $condition1->getStyle()->getFill()->getEndColor()->setARGB(Color::COLOR_GREEN);
  56. $cond = [$condition0, $condition1];
  57. $sheet->getStyle('B3:B5')->setConditionalStyles($cond);
  58. $condition0 = new Conditional();
  59. $condition0->setConditionType(Conditional::CONDITION_EXPRESSION);
  60. $condition0->addCondition('ISOWEEKNUM(A3)<10');
  61. $condition0->getStyle()->getFill()->setFillType(Fill::FILL_SOLID);
  62. $condition0->getStyle()->getFill()->getEndColor()->setARGB(Color::COLOR_RED);
  63. $condition1 = new Conditional();
  64. $condition1->setConditionType(Conditional::CONDITION_EXPRESSION);
  65. $condition1->addCondition('ISOWEEKNUM(A3)>40');
  66. $condition1->getStyle()->getFill()->setFillType(Fill::FILL_SOLID);
  67. $condition1->getStyle()->getFill()->getEndColor()->setARGB(Color::COLOR_GREEN);
  68. $cond = [$condition0, $condition1];
  69. $sheet->getStyle('A3:A5')->setConditionalStyles($cond);
  70. $sheet->setSelectedCell('B1');
  71. $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($workbook, 'Xlsx');
  72. $oufil = File::temporaryFilename();
  73. $writer->save($oufil);
  74. $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx');
  75. $rdobj = $reader->load($oufil);
  76. unlink($oufil);
  77. foreach ($formulas as $values) {
  78. $sheet = $rdobj->setActiveSheetIndexByName($values[0]);
  79. self::assertEquals($values[3], $sheet->getCell($values[1])->getValue());
  80. if ($values[4] !== null) {
  81. self::assertEquals($values[4], $sheet->getCell($values[1])->getCalculatedValue());
  82. }
  83. }
  84. $sheet = $rdobj->setActiveSheetIndexByName('2013');
  85. $cond = $sheet->getConditionalStyles('A3:A5');
  86. self::assertEquals('_xlfn.ISOWEEKNUM(A3)<10', $cond[0]->getConditions()[0]);
  87. self::assertEquals('_xlfn.ISOWEEKNUM(A3)>40', $cond[1]->getConditions()[0]);
  88. $cond = $sheet->getConditionalStyles('B3:B5');
  89. self::assertEquals('ABS(B3)<2', $cond[0]->getConditions()[0]);
  90. self::assertEquals('ABS(B3)>2', $cond[1]->getConditions()[0]);
  91. }
  92. }