|
| 1 | +# Laravel CSV |
| 2 | +PHP Laravel package to create CSV files in a memory-optimized way. |
| 3 | + |
| 4 | +# Description |
| 5 | +Generate CSV files from any of these data sources: _PHP arrays_, _Laravel Collections_ or _Laravel Queries_. You can either prompt the user to download the file or store it in a Laravel disk. For larger datasets, you can generate the file in background as a Laravel Job. |
| 6 | + |
| 7 | +This project was inspired on https://github.com/maatwebsite/Laravel-Excel which is a great project and can handle many formats (Excel, PDF, OpenOffice and CSV). But since it uses PhpSpreadsheet, it is not optimized for exporting large CSV files (thousands of records) causing the PHP memory exhaustion. |
| 8 | + |
| 9 | +The memory usage is optimized in this project by retrieving small chunks of results at a time and outputting the CSV content directly to the client browser or to a persistent with the use of [PHP streams](https://www.php.net/manual/en/intro.stream.php). |
| 10 | + |
| 11 | +This project is using some of Laravel-Excel design principles because it is both a solid work and a reference, and by doing that, it also reduces the learning curve and adaption to this library. |
| 12 | + |
| 13 | +# Requirements |
| 14 | +* PHP >= 7.4 |
| 15 | +* Laravel >= 6.x |
| 16 | + |
| 17 | +# Installation |
| 18 | +Step 1) Add composer dependency |
| 19 | +```bash |
| 20 | +composer require vitorccs/laravel-csv |
| 21 | +``` |
| 22 | + |
| 23 | +Step 2) Publish the config file |
| 24 | +```bash |
| 25 | +php artisan vendor:publish --provider="Vitorccs\LaravelCsv\ServiceProviders\CsvServiceProvider" --tag=config |
| 26 | +``` |
| 27 | + |
| 28 | +Step 3) Edit your local `config\csv.php` file per your project preferences |
| 29 | + |
| 30 | +Step 4) Create an Export class file as show below. |
| 31 | + |
| 32 | +Note: you may implement _FromArray_, _FromCollection_ or _FromQuery_ |
| 33 | + |
| 34 | +```php |
| 35 | +namespace App\Exports; |
| 36 | + |
| 37 | +use App\User; |
| 38 | +use Vitorccs\LaravelCsv\Concerns\Exportable; |
| 39 | +use Vitorccs\LaravelCsv\Concerns\FromQuery; |
| 40 | + |
| 41 | +class UsersExport implements FromQuery |
| 42 | +{ |
| 43 | + use Exportable; |
| 44 | + |
| 45 | + public function query(); |
| 46 | + { |
| 47 | + return User::query(); |
| 48 | + } |
| 49 | +} |
| 50 | +``` |
| 51 | + |
| 52 | +Step 5) The file can now be generated by using a single line: |
| 53 | +```php |
| 54 | +# prompt the client browser to download the file |
| 55 | +return (new UsersExport)->download('users.csv'); |
| 56 | +``` |
| 57 | + |
| 58 | +In case you want the file to be stored in the disk: |
| 59 | +```php |
| 60 | +# will save the file in 's3' disk |
| 61 | +return (new UsersExport)->store('users.csv', 's3'); |
| 62 | +``` |
| 63 | + |
| 64 | +For larger files, you may want to generate the file in background as a Laravel Job |
| 65 | +```php |
| 66 | +# generate a {uuid-v4}.csv filename |
| 67 | +$filename = CsvHelper::filename(); |
| 68 | + |
| 69 | +# will create a job to create and store the file in disk |
| 70 | +# and afterwards notify the user |
| 71 | +(new BillsExport()) |
| 72 | + ->queue($filename, 's3') |
| 73 | + ->allOnQueue('default') |
| 74 | + ->chain([ |
| 75 | + new NotifyCsvCreated($filename) |
| 76 | + ]); |
| 77 | +``` |
| 78 | + |
| 79 | +# Implementations |
| 80 | + |
| 81 | +## Headings |
| 82 | +`WithHeadings` adds a heading row |
| 83 | + |
| 84 | +```php |
| 85 | +use Vitorccs\LaravelCsv\Concerns\Exportable; |
| 86 | +use Vitorccs\LaravelCsv\Concerns\FromArray; |
| 87 | +use Vitorccs\LaravelCsv\Concerns\WithHeadings; |
| 88 | + |
| 89 | +class UsersExport implements FromArray, WithHeadings |
| 90 | +{ |
| 91 | + use Exportable; |
| 92 | + |
| 93 | + public function headings(): array |
| 94 | + { |
| 95 | + return ['ID', 'Name', 'Email']; |
| 96 | + } |
| 97 | +} |
| 98 | +``` |
| 99 | + |
| 100 | +## Mapping rows |
| 101 | +Implement `WithMapping` if you either need to set the value of each column or apply some custom formatting. |
| 102 | + |
| 103 | +```php |
| 104 | +use Vitorccs\LaravelCsv\Concerns\Exportable; |
| 105 | +use Vitorccs\LaravelCsv\Concerns\FromArray; |
| 106 | +use Vitorccs\LaravelCsv\Concerns\WithMapping; |
| 107 | + |
| 108 | +class UsersExport implements FromArray, WithMapping |
| 109 | +{ |
| 110 | + use Exportable; |
| 111 | + |
| 112 | + public function map($user): array |
| 113 | + { |
| 114 | + return [ |
| 115 | + $user->id, |
| 116 | + $user->name, |
| 117 | + $user->email ?: 'N/A' |
| 118 | + ]; |
| 119 | + } |
| 120 | +} |
| 121 | +``` |
| 122 | + |
| 123 | +## Formatting columns |
| 124 | +Implement `WithColumnFormatting` to format Date and Number fields. |
| 125 | +Note: The Date must be a Carbon or Datetime object, and the number must be numeric string, integer or float. The formatting preferences are set in the config file `csv.php`. |
| 126 | + |
| 127 | +```php |
| 128 | +use Vitorccs\LaravelCsv\Concerns\Exportable; |
| 129 | +use Vitorccs\LaravelCsv\Concerns\FromArray; |
| 130 | +use Vitorccs\LaravelCsv\Concerns\WithColumnFormatting; |
| 131 | +use Vitorccs\LaravelCsv\Enum\CellFormat; |
| 132 | +use Carbon\Carbon; |
| 133 | + |
| 134 | +class UsersExport implements FromArray, WithColumnFormatting |
| 135 | +{ |
| 136 | + use Exportable; |
| 137 | + |
| 138 | + public function array(): array |
| 139 | + { |
| 140 | + return [ |
| 141 | + [ Carbon::now(), Carbon::now(), 2.50, 1.00 ], |
| 142 | + [ new DateTime(), new DateTime(), 3, 2.00 ] |
| 143 | + ]; |
| 144 | + } |
| 145 | + |
| 146 | + public function columnFormats(): array |
| 147 | + { |
| 148 | + return [ |
| 149 | + 'A' => CellFormat::DATE, |
| 150 | + 'B' => CellFormat::DATETIME, |
| 151 | + 'C' => CellFormat::DECIMAL, |
| 152 | + 'D' => CellFormat::INTEGER, |
| 153 | + ]; |
| 154 | + } |
| 155 | +} |
| 156 | +``` |
| 157 | + |
| 158 | +## Limiting the results |
| 159 | +Implement the method below if you need to limit the quantity of results. |
| 160 | + |
| 161 | +```php |
| 162 | +use Vitorccs\LaravelCsv\Concerns\Exportable; |
| 163 | +use Vitorccs\LaravelCsv\Concerns\FromQuery; |
| 164 | + |
| 165 | +class UsersExport implements FromQuery |
| 166 | +{ |
| 167 | + use Exportable; |
| 168 | + |
| 169 | + public function limit(): ?int |
| 170 | + { |
| 171 | + return 5000; |
| 172 | + } |
| 173 | +} |
| 174 | +``` |
| 175 | + |
| 176 | +## License |
| 177 | +Released under the [MIT License](LICENSE). |
0 commit comments