Create and Download CSV Files in Laravel without using Package

We can create and download CSV files in Laravel. In this tutorial, we will develop an application to learn how to generate and download CSV files in Laravel without using any package.

We will create some dummy data in MySQL database using Laravel factory and display data in pages using Laravel pagination.

This is a simple application and it is useful as well. All you have to do is select the data in the controller and display them in an html table. To create a CSV file, create a controller function to write the data in a file using fputcsv() function.

Watch YouTube Video

Create the Laravel project

Create the Laravel project using the below command. We have given the project name as lara_csv.


composer create-project --prefer-dist laravel/laravel lara_csv

Migration

Update database details in the .env file. We will be using a MySQL database named 'lara_demo':


DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=lara_demo
DB_USERNAME=root
DB_PASSWORD=

We will create a new table called "applications". We will make some test data in this table using Laravel Factory. Create a migration file for this table using the below command:


php artisan make:model Application -m

The above command will create a migration file <yyyy_mm_dd_xxxxxx>_create_applications_table.php in the database/migrations folder and the model "Application" will be created in the app/Models folder.

Update Laravel migration file

Update the above migration file as below:


public function up(): void
    {
        Schema::create('applications', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->string('address')->nullable();
            $table->timestamps();
        });
    }

Run the migration to create the tables. Run the below artisan command from the project folder:


php artisan migrate

After running the migration see the structure of the 'applications' table.

Laravel generate and download csv file

Update Application model.


<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Application extends Model
{
    use HasFactory;

    protected $fillable = ['name', 'email', 'address'];
}

Add some dummy data using Laravel Faker

We will create some dummy data in the "applications" table. Let us create a factory for the Application model as below:


php artisan make:factory ApplicationFactory --model=Application

Update Application Factory as below:


public function definition(): array
    {
        return [
            'name' => $this->faker->name(),
            'email' => $this->faker->unique()->safeEmail(),
            'address' => $this->faker->address,
        ];
    }

Update the run() method of DatabaseSeeder.php under database/seeders folder to call the factory we just created. We will create 100 rows in the table.


public function run(): void
    {
        \App\Models\Application::factory(100)->create();
      
    }

Now, run the database seeder to create the rows:


php artisan db:seed

Below are 100 rows created in the "applications" table.

Laravel generate and download csv file

Laravel Controller

Let us first take a look at the home page that displays all the applications

Laravel create csv file

It displays the list of applications with a download CSV button. We will create the controller using the artisan command as below:


php artisan make:controller ApplicationController

The controller will have two methods:

  1. index() method to display all the applications.
  2. generateCsv() method for creating a CSV file with the data for all the applications.

index() method

This method selects all records from the Application model and loads the index view.


public function index()
    {
        $data = Application::latest()->paginate(10);
        return view('index',compact('data'));
    }

We have used Laravel pagination to display 10 rows per page.

generateCsv() method


public function generateCsv(request $request)
    {
            $data = Application::latest()->get();
            $filename = "application.csv";
            $handle = fopen($filename, 'w+');
            fputcsv($handle, array(
                            'Name',
                            'Email',
                            'Address',
                           ));

            foreach($data as $row) {
                fputcsv($handle, array( $row['name'],
                                        $row['email'],
                                        $row['address'],
                                        ));
            }
            fclose($handle);
            $headers = array('Content-Type' => 'text/csv');
            return response()->download($filename, 'application.csv', $headers);
    }

Open a file using PHP fopen() function to write the application details. This file has an extension as csv. When a user clicks on the download CSV button, this method will be called and the "application.csv" file will be created in the public folder and downloaded in the user's computer. Note that the header with Content-Type as text/csv has to be sent with the response.

Routes


Route::get('/', [ApplicationController::class, 'index'])->name('application.index');
Route::get('/get-csv', [ApplicationController::class, 'generateCsv'])->name('download.csv');

Create the views

We have one view to display the applications.

We have the below files in the resources/views folder

We will have the header and master layouts

resources/views/layouts/header.blade.php


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Laravel Generate CSV</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">
    <meta name="_token" content="{{ csrf_token() }}">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="{{ asset('css/style.css') }}" />

</head>

resources/views/layouts/master.blade.php


@include('layouts.header')

<body>
    @yield('main-content')
</body>

</html>

resources/views/index.blade.php


@extends('layouts.master')
@section('main-content')
    <h1>Laravel Generate CSV</h1>
    <div class="container">
        <div class="text-end">
            <a href="{{ route('download.csv') }}" class="btn btn-primary">Download CSV</a>
        </div>

        <h4>List of Applications</h4>
        <div class="table-responsive">
            <table class="table table-striped table-bordered mt-5">
                <thead>
                    <tr>
                        <th>#</th>
                        <th>Name</th>
                        <th>Email</th>
                        <th>Address</th>
                    </tr>
                </thead>
                <tbody>
                    @forelse($data as $index => $row)
                        <tr>
                            <td>{{ $index + 1 }}</td>
                            <td>{{ $row->name }}</td>
                            <td>{{ $row->email }}</td>
                            <td>{{ $row->address }}</td>
                        </tr>
                    @empty
                        <tr>
                            <td colspan="6">No Applications Found</td>
                        </tr>
                    @endforelse
                </tbody>
               
            </table>
            {{ $data->links() }}
        </div>
@endsection

Use the below stylesheet:

public/css/style.css


* {box-sizing: border-box;
}
body {
  margin: 0;
  font-family: Helvetica, sans-serif;
  font-size:14px;
}
h1,h4{
  text-align: center;
  margin-bottom: 20px;
  margin-top: 10px;
}
.container{
    min-height: 600px;;
}

table>thead{
  background-color:#2b5171;
  color:#fff;
}

Test the application

Start the PHP development server using the artisan command:


php artisan serve

Run localhost:8000 in the browser. Verify if the application is working correctly. Test the below cases:

  • List Applications with pagination.
  • Download the CSV file and make sure all the rows appear in the CSV file.

Download code from Github.

Post a Comment

Save my Name and Email id for future comments