WithCustomValueBinderTest.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php
  2. namespace Maatwebsite\Excel\Tests\Concerns;
  3. use Carbon\Carbon;
  4. use Illuminate\Support\Collection;
  5. use Maatwebsite\Excel\Concerns\Exportable;
  6. use Maatwebsite\Excel\Concerns\FromCollection;
  7. use Maatwebsite\Excel\Concerns\ToArray;
  8. use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
  9. use Maatwebsite\Excel\Excel;
  10. use Maatwebsite\Excel\Tests\TestCase;
  11. use PhpOffice\PhpSpreadsheet\Cell\Cell;
  12. use PhpOffice\PhpSpreadsheet\Cell\DataType;
  13. use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
  14. use PhpOffice\PhpSpreadsheet\Shared\Date;
  15. use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
  16. use PHPUnit\Framework\Assert;
  17. class WithCustomValueBinderTest extends TestCase
  18. {
  19. /**
  20. * @test
  21. */
  22. public function can_set_a_value_binder_on_export()
  23. {
  24. Carbon::setTestNow(new Carbon('2018-08-07 18:00:00'));
  25. $export = new class extends DefaultValueBinder implements FromCollection, WithCustomValueBinder
  26. {
  27. use Exportable;
  28. /**
  29. * @return Collection
  30. */
  31. public function collection()
  32. {
  33. return collect([
  34. [Carbon::now(), '10%'],
  35. ]);
  36. }
  37. /**
  38. * {@inheritdoc}
  39. */
  40. public function bindValue(Cell $cell, $value)
  41. {
  42. // Handle percentage
  43. if (preg_match('/^\-?\d*\.?\d*\s?\%$/', $value)) {
  44. $cell->setValueExplicit(
  45. (float) str_replace('%', '', $value) / 100,
  46. DataType::TYPE_NUMERIC
  47. );
  48. $cell
  49. ->getWorksheet()
  50. ->getStyle($cell->getCoordinate())
  51. ->getNumberFormat()
  52. ->setFormatCode(NumberFormat::FORMAT_PERCENTAGE_00);
  53. return true;
  54. }
  55. // Handle Carbon dates
  56. if ($value instanceof Carbon) {
  57. $cell->setValueExplicit(
  58. Date::dateTimeToExcel($value),
  59. DataType::TYPE_NUMERIC
  60. );
  61. $cell->getWorksheet()
  62. ->getStyle($cell->getCoordinate())
  63. ->getNumberFormat()
  64. ->setFormatCode(NumberFormat::FORMAT_DATE_DATETIME);
  65. return true;
  66. }
  67. return parent::bindValue($cell, $value);
  68. }
  69. };
  70. $export->store('custom-value-binder-export.xlsx');
  71. $spreadsheet = $this->read(__DIR__ . '/../Data/Disks/Local/custom-value-binder-export.xlsx', 'Xlsx');
  72. $sheet = $spreadsheet->getActiveSheet();
  73. // Check if the cell has the Excel date
  74. $this->assertSame(Date::dateTimeToExcel(Carbon::now()), $sheet->getCell('A1')->getValue());
  75. // Check if formatted as datetime
  76. $this->assertEquals(NumberFormat::FORMAT_DATE_DATETIME, $sheet->getCell('A1')->getStyle()->getNumberFormat()->getFormatCode());
  77. // Check if the cell has the converted percentage
  78. $this->assertSame(0.1, $sheet->getCell('B1')->getValue());
  79. // Check if formatted as percentage
  80. $this->assertEquals(NumberFormat::FORMAT_PERCENTAGE_00, $sheet->getCell('B1')->getStyle()->getNumberFormat()->getFormatCode());
  81. }
  82. /**
  83. * @test
  84. */
  85. public function can_set_a_value_binder_on_import()
  86. {
  87. $import = new class extends DefaultValueBinder implements WithCustomValueBinder, ToArray
  88. {
  89. /**
  90. * {@inheritdoc}
  91. */
  92. public function bindValue(Cell $cell, $value)
  93. {
  94. if ($cell->getCoordinate() === 'B2') {
  95. $cell->setValueExplicit($value, DataType::TYPE_STRING);
  96. return true;
  97. }
  98. if ($cell->getRow() === 3) {
  99. $date = Carbon::instance(Date::excelToDateTimeObject($value));
  100. $cell->setValueExplicit($date->toDateTimeString(), DataType::TYPE_STRING);
  101. return true;
  102. }
  103. return parent::bindValue($cell, $value);
  104. }
  105. /**
  106. * @param array $array
  107. */
  108. public function array(array $array)
  109. {
  110. Assert::assertSame([
  111. [
  112. 'col1',
  113. 'col2',
  114. ],
  115. [
  116. 1,
  117. '2', // Forced to be a string
  118. ],
  119. [
  120. '2018-08-06 18:31:46', // Convert Excel datetime to datetime strings
  121. '2018-08-07 00:00:00', // Convert Excel date to datetime strings
  122. ],
  123. ], $array);
  124. }
  125. };
  126. $this->app->make(Excel::class)->import($import, 'value-binder-import.xlsx');
  127. }
  128. }