LoginSignup
3
2

More than 3 years have passed since last update.

Attaching CSV / Excel import function on Laravel-Admin

Last updated at Posted at 2019-08-31

Why

I wanted to handle many data at one time for updating on Laravel-Admin.
According to my research, we have to take 2 steps.
1. Customize list page to use custom tools which is prepared on Laravel-Admin.
2. Import CSV or Excel file using something.

Custom Tools

Going by documentation, we could custom admin page using custom tool.

model-grid provides custom tool functionality if there are more operational requirements

Import CSV / Excel file

At first, I tried to use Laravel Excel which is powerful library to handle Excel file includes import and export.
However, It's hard to prepare environments for requirements and too powerful for my request, so I decided to use "str_getcsv" which is default function.

Here is the requirements for Laravel-Excel.

PHP: ^7.0
Laravel: ^5.5
PhpSpreadsheet: ^1.6
PHP extension php_zip enabled
PHP extension php_xml enabled
PHP extension php_gd2 enabled

Code

On the condition, please finish to install Laravel-Admin and create some admin page that you'd like to manage at this time.

questions
 CREATE TABLE `questions` (
  `id` bigint(20) unsigned NOT NULL,
  `content` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
import.csv
1, What is your name?
2, How do you do?

You have to make directory at first to use custom tools on Laravel-Admin.

$ mkdir app/Admin/Extensions && mkdir app/Admin/Extensions/Tools

Then, you can create custom tool class.
I decided class name which is "ImportButton" this time.

$ vim app/Admin/Extensions/Tools/ImportButton.php
app/Admin/Extensions/Tools/ImportButton.php
<?php

namespace App\Admin\Extensions\Tools;

use Encore\Admin\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Grid\Tools\AbstractTool;
use Illuminate\Support\Facades\Request;

class ImportButton extends AbstractTool
{

    /**
     * Set up script for import button.
     */
    protected function setUpScripts()
    {
        $script = <<<SCRIPT
function handleFileSelect(evt) {
    var file = evt.target.files; // FileList object
    var fileName = file[0].name;

    $('#input').hide();
    $('#confirm').show();
    $('#confirm .text').text(fileName);
}

$('#files').on('change', handleFileSelect);

$('#confirm').on('click', function() {

    var formData = new FormData();
    if ($("input[name='csvfile']").val()!== '') {
        formData.append( "file", $("input[name='csvfile']").prop("files")[0] );
    }
    formData.append("_token", LA.token);

    $.ajax({
        method: 'POST',
        url: '/admin/questions/csv/import',
        data: formData,
        processData: false,
        contentType: false,
        success: function () {
            $.pjax.reload('#pjax-container');
            toastr.success('Uploading Success');
        }
    });
});
SCRIPT;
        Admin::script($script);
    }

    /**
     * Render Import button.
     *
     * @return string
     */
    public function render()
    {

        $this->setUpScripts();

        $import = 'Import';

        return <<<EOT

            <div class="pull-right" style="margin-right: 10px">
            <label id="input">
            <span class="btn btn-sm btn-twitter">
            <span><i class="fa fa-upload"></i> {$import}</span>
            <input type="file" id="files" name="csvfile" style="display:none">
            </span>
            </label>
            <span id="confirm" class="btn btn-sm btn-twitter" style="display:none">
            <span><i class="fa fa-upload"></i> <span class="text"></span></span>
            </span>
            </div>
EOT;

    }
}
app/Admin/Controllers/QuestionController.php
<?php

namespace App\Admin\Controllers;                                                                                              

use App\Question;                                                                      
use Encore\Admin\Controllers\AdminController;                                      
use Encore\Admin\Form;                                                             
use Encore\Admin\Grid;                                                             
use Encore\Admin\Show;
use Encore\Admin\Controllers\ModelForm;                                            

use App\Admin\Extensions\Tools\ImportButton; // Add
use Encore\Admin\Layout\Content; // Add
use Illuminate\Http\Request; // Add

class QuestionController extends AdminController                                       
{                                                                                  

    .
    .
    .

    /**                                                                            
     * Make a grid builder.   
     *                                                                             
     * @return Grid                                                                
     */                                                                            
    protected function grid()
    {                                                                              
        $grid = new Grid(new Question);                                                

        $grid->column('id', __('Id'));                                             
        $grid->column('content', __('Content'));                               
        $grid->column('created_at', __('Created at'));                             
        $grid->column('updated_at', __('Updated at'));

        // Use custom tools here which you made above.
        $grid->tools(function ($tools) {
            $tools->append(new ImportButton());
        });

        return $grid;                                                              
    } 

    .
    .
    .

    /**                                                                         
     * Import interface.                                                        
     */                                                                         
    protected function import(Content $content, Request $request)               
    {                                                                           
        $file = $request->file('file');
        $csv = array_map('str_getcsv', file($file));                            

        foreach ($csv as $row){                                                 
            $id = (Int) $row[0];                                         
            $content  = $row[1];                                         

            $question = \App\Question::where('id', $id)->first();                       
            if(!$question){                                                         
                $req = new Question();                                              
                $req->id = $id;                                                 
                $req->content = $content;                                   
                $req->save();                                                   
            }else{                                                              
                $question->conetnt = $content;
                $question->save();                                                  
            }                                                                   
        }                                                                       
        return redirect('admin/questions');                                   
    }                                                                           
}                                                            
app/Admin/route.php
$router->post('questions/csv/import', 'QuestionController@import'); // Add this line.

Refs

Custom tools

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2