WithMultipleSheetsTest.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. <?php
  2. namespace Maatwebsite\Excel\Tests\Concerns;
  3. use Illuminate\Support\Collection;
  4. use Maatwebsite\Excel\Concerns\Exportable;
  5. use Maatwebsite\Excel\Concerns\Importable;
  6. use Maatwebsite\Excel\Concerns\SkipsUnknownSheets;
  7. use Maatwebsite\Excel\Concerns\ToArray;
  8. use Maatwebsite\Excel\Concerns\WithMultipleSheets;
  9. use Maatwebsite\Excel\Tests\Data\Stubs\Database\User;
  10. use Maatwebsite\Excel\Tests\Data\Stubs\SheetForUsersFromView;
  11. use Maatwebsite\Excel\Tests\Data\Stubs\SheetWith100Rows;
  12. use Maatwebsite\Excel\Tests\TestCase;
  13. use PHPUnit\Framework\Assert;
  14. class WithMultipleSheetsTest extends TestCase
  15. {
  16. /**
  17. * Setup the test environment.
  18. */
  19. protected function setUp(): void
  20. {
  21. parent::setUp();
  22. $this->withFactories(__DIR__ . '/../Data/Stubs/Database/Factories');
  23. }
  24. /**
  25. * @test
  26. */
  27. public function can_export_with_multiple_sheets_using_collections()
  28. {
  29. $export = new class implements WithMultipleSheets
  30. {
  31. use Exportable;
  32. /**
  33. * @return SheetWith100Rows[]
  34. */
  35. public function sheets(): array
  36. {
  37. return [
  38. new SheetWith100Rows('A'),
  39. new SheetWith100Rows('B'),
  40. new SheetWith100Rows('C'),
  41. ];
  42. }
  43. };
  44. $export->store('from-view.xlsx');
  45. $this->assertCount(100, $this->readAsArray(__DIR__ . '/../Data/Disks/Local/from-view.xlsx', 'Xlsx', 0));
  46. $this->assertCount(100, $this->readAsArray(__DIR__ . '/../Data/Disks/Local/from-view.xlsx', 'Xlsx', 1));
  47. $this->assertCount(100, $this->readAsArray(__DIR__ . '/../Data/Disks/Local/from-view.xlsx', 'Xlsx', 2));
  48. }
  49. /**
  50. * @test
  51. */
  52. public function can_export_multiple_sheets_from_view()
  53. {
  54. /** @var Collection|User[] $users */
  55. $users = factory(User::class)->times(300)->make();
  56. $export = new class($users) implements WithMultipleSheets
  57. {
  58. use Exportable;
  59. /**
  60. * @var Collection
  61. */
  62. protected $users;
  63. /**
  64. * @param Collection $users
  65. */
  66. public function __construct(Collection $users)
  67. {
  68. $this->users = $users;
  69. }
  70. /**
  71. * @return SheetForUsersFromView[]
  72. */
  73. public function sheets(): array
  74. {
  75. return [
  76. new SheetForUsersFromView($this->users->forPage(1, 100)),
  77. new SheetForUsersFromView($this->users->forPage(2, 100)),
  78. new SheetForUsersFromView($this->users->forPage(3, 100)),
  79. ];
  80. }
  81. };
  82. $export->store('from-view.xlsx');
  83. $this->assertCount(101, $this->readAsArray(__DIR__ . '/../Data/Disks/Local/from-view.xlsx', 'Xlsx', 0));
  84. $this->assertCount(101, $this->readAsArray(__DIR__ . '/../Data/Disks/Local/from-view.xlsx', 'Xlsx', 1));
  85. $this->assertCount(101, $this->readAsArray(__DIR__ . '/../Data/Disks/Local/from-view.xlsx', 'Xlsx', 2));
  86. }
  87. /**
  88. * @test
  89. */
  90. public function unknown_sheet_index_will_throw_sheet_not_found_exception()
  91. {
  92. $this->expectException(\Maatwebsite\Excel\Exceptions\SheetNotFoundException::class);
  93. $this->expectExceptionMessage('Your requested sheet index: 9999 is out of bounds. The actual number of sheets is 2.');
  94. $import = new class implements WithMultipleSheets
  95. {
  96. use Importable;
  97. public function sheets(): array
  98. {
  99. return [
  100. 9999 => new class {
  101. },
  102. ];
  103. }
  104. };
  105. $import->import('import-multiple-sheets.xlsx');
  106. }
  107. /**
  108. * @test
  109. */
  110. public function unknown_sheet_name_will_throw_sheet_not_found_exception()
  111. {
  112. $this->expectException(\Maatwebsite\Excel\Exceptions\SheetNotFoundException::class);
  113. $this->expectExceptionMessage('Your requested sheet name [Some Random Sheet Name] is out of bounds.');
  114. $import = new class implements WithMultipleSheets
  115. {
  116. use Importable;
  117. public function sheets(): array
  118. {
  119. return [
  120. 'Some Random Sheet Name' => new class {
  121. },
  122. ];
  123. }
  124. };
  125. $import->import('import-multiple-sheets.xlsx');
  126. }
  127. /**
  128. * @test
  129. */
  130. public function unknown_sheet_name_can_be_ignored()
  131. {
  132. $import = new class implements WithMultipleSheets, SkipsUnknownSheets
  133. {
  134. use Importable;
  135. public $unknown;
  136. public function sheets(): array
  137. {
  138. return [
  139. 'Some Random Sheet Name' => new class {
  140. },
  141. ];
  142. }
  143. /**
  144. * @param string|int $sheetName
  145. */
  146. public function onUnknownSheet($sheetName)
  147. {
  148. $this->unknown = $sheetName;
  149. }
  150. };
  151. $import->import('import-multiple-sheets.xlsx');
  152. $this->assertEquals('Some Random Sheet Name', $import->unknown);
  153. }
  154. /**
  155. * @test
  156. */
  157. public function unknown_sheet_indices_can_be_ignored_per_name()
  158. {
  159. $import = new class implements WithMultipleSheets
  160. {
  161. use Importable;
  162. public function sheets(): array
  163. {
  164. return [
  165. 'Some Random Sheet Name' => new class implements SkipsUnknownSheets
  166. {
  167. /**
  168. * @param string|int $sheetName
  169. */
  170. public function onUnknownSheet($sheetName)
  171. {
  172. Assert::assertEquals('Some Random Sheet Name', $sheetName);
  173. }
  174. },
  175. ];
  176. }
  177. };
  178. $import->import('import-multiple-sheets.xlsx');
  179. }
  180. /**
  181. * @test
  182. */
  183. public function unknown_sheet_indices_can_be_ignored()
  184. {
  185. $import = new class implements WithMultipleSheets, SkipsUnknownSheets
  186. {
  187. use Importable;
  188. public $unknown;
  189. public function sheets(): array
  190. {
  191. return [
  192. 99999 => new class {
  193. },
  194. ];
  195. }
  196. /**
  197. * @param string|int $sheetName
  198. */
  199. public function onUnknownSheet($sheetName)
  200. {
  201. $this->unknown = $sheetName;
  202. }
  203. };
  204. $import->import('import-multiple-sheets.xlsx');
  205. $this->assertEquals(99999, $import->unknown);
  206. }
  207. /**
  208. * @test
  209. */
  210. public function unknown_sheet_indices_can_be_ignored_per_sheet()
  211. {
  212. $import = new class implements WithMultipleSheets
  213. {
  214. use Importable;
  215. public function sheets(): array
  216. {
  217. return [
  218. 99999 => new class implements SkipsUnknownSheets
  219. {
  220. /**
  221. * @param string|int $sheetName
  222. */
  223. public function onUnknownSheet($sheetName)
  224. {
  225. Assert::assertEquals(99999, $sheetName);
  226. }
  227. },
  228. ];
  229. }
  230. };
  231. $import->import('import-multiple-sheets.xlsx');
  232. }
  233. /**
  234. * @test
  235. */
  236. public function can_import_multiple_sheets()
  237. {
  238. $import = new class implements WithMultipleSheets
  239. {
  240. use Importable;
  241. public function sheets(): array
  242. {
  243. return [
  244. new class implements ToArray
  245. {
  246. public function array(array $array)
  247. {
  248. Assert::assertEquals([
  249. ['1.A1', '1.B1'],
  250. ['1.A2', '1.B2'],
  251. ], $array);
  252. }
  253. },
  254. new class implements ToArray
  255. {
  256. public function array(array $array)
  257. {
  258. Assert::assertEquals([
  259. ['2.A1', '2.B1'],
  260. ['2.A2', '2.B2'],
  261. ], $array);
  262. }
  263. },
  264. ];
  265. }
  266. };
  267. $import->import('import-multiple-sheets.xlsx');
  268. }
  269. /**
  270. * @test
  271. */
  272. public function can_import_multiple_sheets_by_sheet_name()
  273. {
  274. $import = new class implements WithMultipleSheets
  275. {
  276. use Importable;
  277. public function sheets(): array
  278. {
  279. return [
  280. 'Sheet2' => new class implements ToArray
  281. {
  282. public function array(array $array)
  283. {
  284. Assert::assertEquals([
  285. ['2.A1', '2.B1'],
  286. ['2.A2', '2.B2'],
  287. ], $array);
  288. }
  289. },
  290. 'Sheet1' => new class implements ToArray
  291. {
  292. public function array(array $array)
  293. {
  294. Assert::assertEquals([
  295. ['1.A1', '1.B1'],
  296. ['1.A2', '1.B2'],
  297. ], $array);
  298. }
  299. },
  300. ];
  301. }
  302. };
  303. $import->import('import-multiple-sheets.xlsx');
  304. }
  305. /**
  306. * @test
  307. */
  308. public function can_import_multiple_sheets_by_sheet_index_and_name()
  309. {
  310. $import = new class implements WithMultipleSheets
  311. {
  312. use Importable;
  313. public $sheets = [];
  314. public function __construct()
  315. {
  316. $this->sheets = [
  317. 0 => new class implements ToArray
  318. {
  319. public $called = false;
  320. public function array(array $array)
  321. {
  322. $this->called = true;
  323. Assert::assertEquals([
  324. ['1.A1', '1.B1'],
  325. ['1.A2', '1.B2'],
  326. ], $array);
  327. }
  328. },
  329. 'Sheet2' => new class implements ToArray
  330. {
  331. public $called = false;
  332. public function array(array $array)
  333. {
  334. $this->called = true;
  335. Assert::assertEquals([
  336. ['2.A1', '2.B1'],
  337. ['2.A2', '2.B2'],
  338. ], $array);
  339. }
  340. },
  341. ];
  342. }
  343. public function sheets(): array
  344. {
  345. return $this->sheets;
  346. }
  347. };
  348. $import->import('import-multiple-sheets.xlsx');
  349. foreach ($import->sheets as $sheet) {
  350. $this->assertTrue($sheet->called);
  351. }
  352. }
  353. /**
  354. * @test
  355. */
  356. public function can_import_multiple_sheets_by_sheet_name_and_index()
  357. {
  358. $import = new class implements WithMultipleSheets
  359. {
  360. use Importable;
  361. public $sheets = [];
  362. public function __construct()
  363. {
  364. $this->sheets = [
  365. 'Sheet1' => new class implements ToArray
  366. {
  367. public $called = false;
  368. public function array(array $array)
  369. {
  370. $this->called = true;
  371. Assert::assertEquals([
  372. ['1.A1', '1.B1'],
  373. ['1.A2', '1.B2'],
  374. ], $array);
  375. }
  376. },
  377. 1 => new class implements ToArray
  378. {
  379. public $called = false;
  380. public function array(array $array)
  381. {
  382. $this->called = true;
  383. Assert::assertEquals([
  384. ['2.A1', '2.B1'],
  385. ['2.A2', '2.B2'],
  386. ], $array);
  387. }
  388. },
  389. ];
  390. }
  391. public function sheets(): array
  392. {
  393. return $this->sheets;
  394. }
  395. };
  396. $import->import('import-multiple-sheets.xlsx');
  397. foreach ($import->sheets as $sheet) {
  398. $this->assertTrue($sheet->called);
  399. }
  400. }
  401. }