/src/Maatwebsite/Excel/Writers/LaravelExcelWriter.php

https://gitlab.com/intelij/Laravel-Excel · PHP · 541 lines · 227 code · 81 blank · 233 comment · 15 complexity · 464b7e0103d73b95ee7502da794b9f9b MD5 · raw file

  1. <?php namespace Maatwebsite\Excel\Writers;
  2. use Config;
  3. use Closure;
  4. use Response;
  5. use Carbon\Carbon;
  6. use PHPExcel_IOFactory;
  7. use Illuminate\Filesystem\Filesystem;
  8. use Maatwebsite\Excel\Classes\FormatIdentifier;
  9. use Maatwebsite\Excel\Classes\LaravelExcelWorksheet;
  10. use Maatwebsite\Excel\Exceptions\LaravelExcelException;
  11. /**
  12. *
  13. * LaravelExcel Excel writer
  14. *
  15. * @category Laravel Excel
  16. * @version 1.0.0
  17. * @package maatwebsite/excel
  18. * @copyright Copyright (c) 2013 - 2014 Maatwebsite (http://www.maatwebsite.nl)
  19. * @author Maatwebsite <info@maatwebsite.nl>
  20. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  21. */
  22. class LaravelExcelWriter {
  23. /**
  24. * Spreadsheet filename
  25. * @var stirng
  26. */
  27. public $filename;
  28. /**
  29. * Spreadsheet title
  30. * @var stirng
  31. */
  32. public $title;
  33. /**
  34. * Excel object
  35. * @var PHPExcel
  36. */
  37. public $excel;
  38. /**
  39. * Laravel response
  40. * @var Response
  41. */
  42. protected $response;
  43. /**
  44. * Spreadsheet writer
  45. * @var object
  46. */
  47. public $writer;
  48. /**
  49. * Excel sheet
  50. * @var LaravelExcelWorksheet
  51. */
  52. protected $sheet;
  53. /**
  54. * Parser
  55. * @var ViewParser
  56. */
  57. public $parser;
  58. /**
  59. * Default extension
  60. * @var string
  61. */
  62. public $ext = 'xls';
  63. /**
  64. * Path the file will be stored to
  65. * @var string
  66. */
  67. public $storagePath = 'exports';
  68. /**
  69. * Header Content-type
  70. * @var string
  71. */
  72. protected $contentType;
  73. /**
  74. * Spreadsheet is rendered
  75. * @var boolean
  76. */
  77. protected $rendered = false;
  78. /**
  79. * Construct writer
  80. * @param Response $response
  81. * @param FileSystem $filesystem
  82. * @param FormatIdentifier $identifier
  83. */
  84. public function __construct(Response $response, FileSystem $filesystem, FormatIdentifier $identifier)
  85. {
  86. $this->response = $response;
  87. $this->filesystem = $filesystem;
  88. $this->identifier = $identifier;
  89. }
  90. /**
  91. * Inject the excel object
  92. * @param PHPExcel $excel
  93. * @return void
  94. */
  95. public function injectExcel($excel, $reset = true)
  96. {
  97. $this->excel = $excel;
  98. if($reset)
  99. $this->_reset();
  100. }
  101. /**
  102. * Set the spreadsheet title
  103. * @param string $title
  104. * @return LaravelExcelWriter
  105. */
  106. public function setTitle($title)
  107. {
  108. $this->title = $title;
  109. $this->getProperties()->setTitle($title);
  110. return $this;
  111. }
  112. /**
  113. * Set the filename
  114. * @param [type] $name [description]
  115. */
  116. public function setFileName($name)
  117. {
  118. $this->filename = $name;
  119. return $this;
  120. }
  121. /**
  122. * Get the title
  123. * @return string
  124. */
  125. public function getTitle()
  126. {
  127. return $this->title;
  128. }
  129. /**
  130. * Get the title
  131. * @return string
  132. */
  133. public function getFileName()
  134. {
  135. return $this->filename;
  136. }
  137. /**
  138. * Share view with all sheets
  139. * @param string $view
  140. * @param array $data
  141. * @param array $mergeData
  142. * @return LaravelExcelWriter
  143. */
  144. public function shareView($view, $data = array(), $mergeData = array())
  145. {
  146. // Get the parser
  147. $this->getParser();
  148. // Set the view inside the parser
  149. $this->parser->setView($view);
  150. $this->parser->setData($data);
  151. $this->parser->setMergeData($mergeData);
  152. return $this;
  153. }
  154. /**
  155. * Set the view
  156. * @return LaravelExcelWriter
  157. */
  158. public function setView()
  159. {
  160. return call_user_func_array(array($this, 'shareView'), func_get_args());
  161. }
  162. /**
  163. * Load the view
  164. * @return LaravelExcelWriter
  165. */
  166. public function loadView()
  167. {
  168. return call_user_func_array(array($this, 'shareView'), func_get_args());
  169. }
  170. /**
  171. * Create a new sheet
  172. * @param string $title
  173. * @param callback|null $callback
  174. * @return LaravelExcelWriter
  175. */
  176. public function sheet($title, $callback = null)
  177. {
  178. // Clone the active sheet
  179. $this->sheet = $this->excel->createSheet(null, $title);
  180. // If a parser was set, inject it
  181. if($this->parser)
  182. $this->sheet->setParser($this->parser);
  183. // Set the sheet title
  184. $this->sheet->setTitle($title);
  185. // Set the default page setup
  186. $this->sheet->setDefaultPageSetup();
  187. // Do the callback
  188. if($callback instanceof Closure)
  189. call_user_func($callback, $this->sheet);
  190. // Autosize columns when no user didn't change anything about column sizing
  191. if(!$this->sheet->hasFixedSizeColumns())
  192. $this->sheet->setAutosize(Config::get('excel::export.autosize', false));
  193. // Parse the sheet
  194. $this->sheet->parsed();
  195. return $this;
  196. }
  197. /**
  198. * Set data for the current sheet
  199. * @param array $array
  200. * @return LaravelExcelWriter
  201. */
  202. public function with(Array $array)
  203. {
  204. // Add the vars
  205. $this->fromArray($array);
  206. return $this;
  207. }
  208. /**
  209. * Export the spreadsheet
  210. * @param string $ext
  211. * @return void
  212. */
  213. public function export($ext = 'xls')
  214. {
  215. // Set the extension
  216. $this->ext = $ext;
  217. // Render the file
  218. $this->_render();
  219. // Download the file
  220. $this->_download();
  221. }
  222. /**
  223. * Export and download the spreadsheet
  224. * @param string $ext
  225. * @return void
  226. */
  227. public function download($ext = 'xls')
  228. {
  229. return $this->export($ext);
  230. }
  231. /**
  232. * Download a file
  233. * @return void
  234. */
  235. protected function _download()
  236. {
  237. // Set the headers
  238. $this->_setHeaders(array(
  239. 'Content-Type' => $this->contentType,
  240. 'Content-Disposition' => 'attachment; filename="' . $this->filename . '.' . $this->ext . '"',
  241. 'Expires' => 'Mon, 26 Jul 1997 05:00:00 GMT', // Date in the past
  242. 'Last-Modified' => Carbon::now()->format('D, d M Y H:i:s'),
  243. 'Cache-Control' => 'cache, must-revalidate',
  244. 'Pragma' => 'public'
  245. ));
  246. // Check if writer isset
  247. if(!$this->writer)
  248. throw new LaravelExcelException('[ERROR] No writer was set.');
  249. // Download
  250. $this->writer->save('php://output');
  251. // End the script to prevent corrupted xlsx files
  252. exit;
  253. }
  254. /**
  255. * Store the excel file to the server
  256. * @param string $ext
  257. * @param boolean $path
  258. * @param boolean $returnInfo
  259. * @return LaravelExcelWriter
  260. */
  261. public function store($ext = 'xls', $path = false, $returnInfo = false)
  262. {
  263. // Set the storage path
  264. $this->_setStoragePath($path);
  265. // Set the extension
  266. $this->ext = $ext;
  267. // Render the XLS
  268. $this->_render();
  269. // Set the storage path and file
  270. $toStore = $this->storagePath . '/' . $this->filename . '.' . $this->ext;
  271. // Save the file to specified location
  272. $this->writer->save($toStore);
  273. // Return file info
  274. if($this->returnInfo($returnInfo))
  275. {
  276. // Send back information about the stored file
  277. return array(
  278. 'full' => $toStore,
  279. 'path' => $this->storagePath,
  280. 'file' => $this->filename . '.' . $this->ext,
  281. 'title' => $this->filename,
  282. 'ext' => $this->ext
  283. );
  284. }
  285. // Return itself
  286. return $this;
  287. }
  288. /**
  289. * Check if we want to return info or itself
  290. * @param boolean $returnInfo
  291. * @return boolean
  292. */
  293. public function returnInfo($returnInfo = false)
  294. {
  295. return $returnInfo ? $returnInfo : Config::get('excel::export.store.returnInfo', false);
  296. }
  297. /**
  298. * Store the excel file to the server
  299. * @param str $ext The file extension
  300. * @param str $path The save path
  301. * @return LaravelExcelWriter
  302. */
  303. public function save($ext = 'xls', $path = false, $returnInfo = false)
  304. {
  305. return $this->store($ext, $path, $returnInfo);
  306. }
  307. /**
  308. * Start render of a new spreadsheet
  309. * @return void
  310. */
  311. protected function _render()
  312. {
  313. // There should be enough sheets to continue rendering
  314. if($this->excel->getSheetCount() < 0)
  315. throw new LaravelExcelException('[ERROR] Aborting spreadsheet render: no sheets were created.');
  316. // Set the format
  317. $this->_setFormat();
  318. // Set the writer
  319. $this->_setWriter();
  320. // File has been rendered
  321. $this->rendered = true;
  322. }
  323. /**
  324. * Get the view parser
  325. * @return PHPExcel
  326. */
  327. public function getExcel()
  328. {
  329. return $this->excel;
  330. }
  331. /**
  332. * Get the view parser
  333. * @return ViewParser
  334. */
  335. public function getParser()
  336. {
  337. // Init the parser
  338. if(!$this->parser)
  339. $this->parser = app('excel.parsers.view');
  340. return $this->parser;
  341. }
  342. /**
  343. * Get the sheet
  344. * @return LaravelExcelWorksheet
  345. */
  346. public function getSheet()
  347. {
  348. return $this->sheet;
  349. }
  350. /**
  351. * Set attributes
  352. * @param string $setter
  353. * @param array $params
  354. */
  355. protected function _setAttribute($setter, $params)
  356. {
  357. // Get the key
  358. $key = lcfirst(str_replace('set', '', $setter));
  359. // If is an allowed property
  360. if($this->excel->isChangeableProperty($setter))
  361. {
  362. // Set the properties
  363. call_user_func_array(array($this->excel->getProperties(), $setter), $params);
  364. }
  365. }
  366. /**
  367. * Set the write format
  368. * @return void
  369. */
  370. protected function _setFormat()
  371. {
  372. // Get extension
  373. $this->ext = strtolower($this->ext);
  374. // get the file format
  375. $this->format = $this->identifier->getFormatByExtension($this->ext);
  376. // Get content type
  377. $this->contentType = $this->identifier->getContentTypeByFormat($this->format);
  378. }
  379. /**
  380. * Set the writer
  381. * @return PHPExcel_***_Writer
  382. */
  383. protected function _setWriter()
  384. {
  385. $this->writer = PHPExcel_IOFactory::createWriter($this->excel, $this->format);
  386. // Set CSV delimiter
  387. if($this->format == 'CSV')
  388. {
  389. $this->writer->setDelimiter(Config::get('excel::csv.delimiter', ','));
  390. $this->writer->setEnclosure(Config::get('excel::csv.enclosure', '"'));
  391. $this->writer->setLineEnding(Config::get('excel::csv.line_ending', "\r\n"));
  392. }
  393. // Calculation settings
  394. $this->writer->setPreCalculateFormulas(Config::get('excel::export.calculate', true));
  395. return $this->writer;
  396. }
  397. /**
  398. * Set the headers
  399. */
  400. protected function _setHeaders($headers)
  401. {
  402. if ( headers_sent() ) throw new LaravelExcelException('[ERROR]: Headers already sent');
  403. foreach($headers as $header => $value)
  404. {
  405. header($header . ': ' . $value);
  406. }
  407. }
  408. /**
  409. * Set the storage path
  410. * @return void
  411. */
  412. protected function _setStoragePath($path = false)
  413. {
  414. // Get the default path
  415. $path = $path ? $path : Config::get('excel::export.store.path', storage_path($this->storagePath));
  416. // Trim of slashes, to makes sure we won't add them double
  417. $this->storagePath = rtrim($path, '/');
  418. // Make sure the storage path exists
  419. if(!$this->filesystem->isWritable($this->storagePath))
  420. $this->filesystem->makeDirectory($this->storagePath, 0777, true);
  421. }
  422. /**
  423. * Reset the writer
  424. * @return void
  425. */
  426. protected function _reset()
  427. {
  428. $this->excel->disconnectWorksheets();
  429. }
  430. /**
  431. * Dynamically call methods
  432. * @param string $method
  433. * @param array $params
  434. * @return LaravelExcelWriter
  435. */
  436. public function __call($method, $params)
  437. {
  438. // If the dynamic call starts with "set"
  439. if(starts_with($method, 'set') && $this->excel->isChangeableProperty($method))
  440. {
  441. $this->_setAttribute($method, $params);
  442. return $this;
  443. }
  444. // Call a php excel method
  445. elseif(method_exists($this->excel, $method))
  446. {
  447. // Call the method from the excel object with the given params
  448. $return = call_user_func_array(array($this->excel, $method), $params);
  449. return $return ? $return : $this;
  450. }
  451. // Call a php excel sheet method
  452. elseif(method_exists($this->excel->getActiveSheet(), $method))
  453. {
  454. // Call the method from the excel object with the given params
  455. $return = call_user_func_array(array($this->excel->getActiveSheet(), $method), $params);
  456. return $return ? $return : $this;
  457. }
  458. throw new LaravelExcelException('[ERROR] Writer method ['. $method .'] does not exist.');
  459. }
  460. }