Parsing CSV file in background

  csv, laravel, php

I currently have the following code which works fine, but processing the file takes a long time, and if the file has more than about 8000 rows it will timeout. I want to be able to process the CSV file in the background so the user can leave or go to other pages while the csv file processes and injects into the database.

Thank you!

          <!--CSV UPLOAD BUTTON-->
          <button type="button" class="btn btn-primary float-right" data-toggle="modal" data-target="#exampleModal" style="height:48px;width:150px;">
            CSV Upload
          </button>

          <!-- CSV MODAL -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">Upload Customers CSV file</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
      </div>
      <form action="{{ url('contacts/upload-csv') }}" method="POST" enctype="multipart/form-data" id="csv-upload">
        <input name="_token" type="hidden" value="{{ csrf_token() }}"/>
        <input name="customers" type="hidden">
        <div class="modal-body">
          <div class="row" width="100%" height="80px">
            <div class="col-md-6">
              <input type="file" name="csv_customers">
              <br><strong>*</strong><small> = REQUIRED</small><br>
            </div>
          </div>
          <div id="dvCSV" class="table-responsive" style="max-height: 600px; display:none;"></div>
          <div id="fieldsCSV" style="display:none ">
          <div class="row" style="margin-top: 1px">
            <p class="col-sm-6" style="padding-top:5px">Customer Email<strong>*</strong></p>
            <select class="col-sm-6" data-style="btn btn-link" name="customer_email" id="customer_email" ></select>
          </div>
          <div class="row" style="margin-top: 1px">
            <p class="col-sm-6" style="padding-top:5px">Customer First Name<strong>*</strong></p>
            <select class="col-sm-6" data-style="btn btn-link" name="customer_firstname" id="customer_firstname" ></select>
          </div>
          <div class="row" style="margin-top: 1px">
            <p class="col-sm-6" style="padding-top:5px">Customer Last Name</p>
            <select class="col-sm-6" data-style="btn btn-link" name="customer_lastname" id="customer_lastname" ></select>
          </div>
          <div class="row" style="margin-top: 1px">
            <p class="col-sm-6" style="padding-top:5px">Customer Phone<strong>*</strong></p>
            <select class="col-sm-6" data-style="btn btn-link" name="customer_phone" id="customer_phone" ></select>
          </div>
          <div class="row" style="margin-top: 1px">
            <p class="col-sm-6" style="padding-top:5px">Customer Address<strong>*</strong></p>
            <select class="col-sm-6" data-style="btn btn-link" name="customer_address" id="customer_address" ></select>
          </div>
          <div class="row" style="margin-top: 1px">
            <p class="col-sm-6" style="padding-top:5px">Customer City<strong>*</strong></p>
            <select class="col-sm-6" data-style="btn btn-link" name="customer_city" id="customer_city" ></select>
          </div>
          <div class="row" style="margin-top: 1px">
            <p class="col-sm-6" style="padding-top:5px">Customer State<strong>*</strong></p>
            <select class="col-sm-6" data-style="btn btn-link" name="customer_state" id="customer_state" ></select>
          </div>
          <div class="row" style="margin-top: 1px">
            <p class="col-sm-6" style="padding-top:5px">Customer Zip<strong>*</strong></p>
            <select class="col-sm-6" data-style="btn btn-link" name="customer_zip" id="customer_zip" ></select>
          </div>
          <div class="row" style="margin-top: 1px">
        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
        <button type="submit" class="btn btn-primary">Submit</button>
      </div>
      </form>
    </div>
  </div>
<div>

<script>
  var uploadedData = ''
  $('input[name="csv_customers"]').change(function() {
    var regex = /^([a-zA-Z0-9s_.-:])+(.csv|.txt)$/
    var option = ''
    if (regex.test($(this).val().toLowerCase())) {
      if (typeof (FileReader) != "undefined") {
        $('body').removeClass('loaded');
        var reader = new FileReader()
        reader.onload = function (e) {
          var table = $("<table class='table table-hover'/>")
          var rows = e.target.result.split("n")
          uploadedData = rows
          console.log(rows.length)
          var cells = rows[0].split(",")
          option += "<option value=-1>--</option>"
          for (var j = 0; j < cells.length; j++) {
            option += "<option value="+j+">"+cells[j]+"</option>"
          }
          $('select').append(option)
          $('#fieldsCSV').show()
          $('body').addClass('loaded');
        }
        reader.readAsText($('input[name="csv_customers"]')[0].files[0])
      } else {
        md.showNotification('top','right', 'This browser does not support HTML5.')
      }
    }
  })

  $('#csv-upload').submit(function(){
    $('body').removeClass('loaded');
    let customer_email_index = $('#customer_email').find('option:selected').val()
    let customer_firstname_index = $('#customer_firstname').find('option:selected').val()
    let customer_lastname_index = $('#customer_lastname').find('option:selected').val()
    let customer_phone_index = $('#customer_phone').find('option:selected').val()
    let customer_address_index = $('#customer_address').find('option:selected').val()
    let customer_city_index = $('#customer_city').find('option:selected').val()
    let customer_state_index = $('#customer_state').find('option:selected').val()
    let customer_zip_index = $('#customer_zip').find('option:selected').val()

    var real_data = []
    for (var i = 1; i < uploadedData.length; i++) {
      var cell_ori = uploadedData[i].replace('r', '')
      var cells = cell_ori.split(",")
      let customer_info = {
        customer_email: customer_email_index>=0 ? cells[customer_email_index] : null,
        customer_firstname: customer_firstname_index>=0 ? cells[customer_firstname_index] : null,
        customer_lastname: customer_lastname_index>=0 ? cells[customer_lastname_index] : null,
        customer_phone: customer_phone_index>=0 ? cells[customer_phone_index] : null,
        customer_address: customer_address_index>=0 ? cells[customer_address_index] : null,
        customer_city: customer_city_index>=0 ? cells[customer_city_index] : null,
        customer_state: customer_state_index>=0 ? cells[customer_state_index] : null,
        customer_zip: customer_zip_index>=0 ? cells[customer_zip_index] : null,
      }
      real_data.push(customer_info)
    }
    console.log(real_data)
    $('input[name="customers"]').val(JSON.stringify(real_data))
    if (real_data.length > 0) return
    else {
      $('body').addClass('loaded');
      md.showNotification('top','right', 'Please check your CSV filename does not have any special characters or spaces.')
    }
  })
</script>

Source: Laravel

Leave a Reply