How to Upload and Download CSV Files With AngularJS

This post will show you how to upload CSV files data to AngularJS, read the data, and then convert it to JSON for processing. Then, you’ll see how to do the whole thing in reverse and download a CSV data dump from AngularJS.

How to Upload and Download CSV Files With AngularJS

CSV files are preferred because of their simplicity. They are also widely supported by many types of programs and provide a straightforward way to represent spreadsheet data.

Prerequisites

Before you get started with this tutorial, make sure you have Node.js installed on your computer. If you don’t have it yet, head over to the official website and install it.

You should also have a basic understanding of the following technologies:

  • HTML
  • CSS
  • JavaScript

If you already have Node.js have installed, check if you have the latest versions of Node and NPM.

node -v
npm -v

CSV Modules in Angular

There are several ways of manipulating CSV in Angular, and they include:

  • Papa Parse: Papa Parse is a powerful CSV parser which is capable of parsing CSV strings in small and big files as well as converting back to JSON. We will be using this library in this tutorial.
  • csvtojson: This is a node package which is also simple to use.
  • File Reader: It is used to read the contents of files using File or Blob objects to specify the file to be read. However, this is not an efficient way because you still have to loop through all the lines of the CSV and then JSON.stringify the results.

Getting Started

Our goal is to be able to do the following:

  • download a CSV file on the client side
  • upload a CSV file
  • read a CSV file
  • convert CSV file data to JSON for processing

Our interface should  look something like this:

How to Upload and Download CSV Files With AngularJS

We will first start by writing the HTML code for the interface shown above.

Create a folder named my_project, cd into the project folder, and create two files: home.html and app.js.

mkdir my_project
cd my_project
touch home.html
touch app.js

Since we will be using the Papa Parse module, head over to the official site and download the library. Next, extract the contents and save the papaparse.js and papaparse.min.js files in your project folder. Your project structure should look like this:

my_project/ 
  app.js
  home.html
  papaparse.js
  papaparse.min.js

Below is the  HTML code for creating our interface. Save it as home.html.

<!DOCTYPE html ng-app="myApp" ng-strict-di="true">
<html lang="en" ng-app="myApp" class="no-js"> <!--<![endif]-->

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="papaparse.js"></script>
<script src="papaparse.min.js"></script>
<body ng-controller = "CsvCtrl">

<section class="content">

    <div class="row">
          <div class="col-md-12">
              <div class="panel-heading"><strong>BULK TOP UP</strong> <small></small></div>
              <div class="box box-info">
                <div class =  "instructions"> 
                <ol>
                  <li>The Excel file should contain three columns </li>
                  <li>The first column contains the <strong>Reference</strong></li>
                  <li>The second column contains the <strong>First name</strong></li>
                  <li>The third column contains the <strong>Last name </strong> </li>
                  <li>The second column contains the <strong>Date of Birth</strong></li>
                  <li>The third column contains the <strong>Sex</strong>of the person</li>

              </ol>
                <div class="box-body table-responsive">
                  <p>The column headers should be <strong>Reference</strong> ,<strong>First_name</strong> ,<strong>Last_name</strong>,<strong>Dob</strong>,<strong>Sex</strong></p>
                  <p>  A sample file is available for download</p>
                  <form>
                    <button data-ng-click="download()">Download CSV</button> 
                    </form>
               </div>
             </div>
                <div class="box-body table-responsive">
                    <hr>
                    <hr>
                    <!-- form start -->
                    <p>Your uploaded csv file will be shown to you in a preview  for Confirmation</p>
                    <form role="form" class="form-horizontal" name="bulkDirectForm" method="post" enctype="multipart/form-data" novalidate>
                      <div class="box-body">
                        <div id="messages" class="alert alert-success" data-ng-show="messages" data-ng-bind="messages"></div>
                        <div id="warning" class="alert alert-warning" data-ng-show="warning" data-ng-bind="warning"></div>
                        
                        <div class="form-group">
                          <div class="col-sm-10">
                            <input type="file" class="form-control" id="bulkDirectFile" placeholder="CSV file with phone numbers and amount" ng-model="prd.bulk_direct_file" required accept=".csv">
                          </div>
                          <div class="col-sm-2">
                            <button type="submit" class="btn btn-block btn-info" ng-hide="myVar" data-ng-click="submitForm(bulkDirectForm)">Upload!</button>
                          </div>
                          

                          <br>
                          <br>
                          
                  
                          <div class="col-sm-10" ng-show = title id ="Table">
                          <h5>Confirm file to be uploaded and Click the Proceed Button Below</h5>
                         
              
                          <div id="dvCSV"></div>

                          <br>
                          
                          <button type="button" class="btn btn-success" data-ng-click="add()">Proceed!</button>
                          </div>


                          
                        </div>

                      </div>
                    </form>
                     
                </div>
              </div>
          </div>
     </div>


</section>

</body>
</html>

In the code above, we use the ng-app directive to define our application. We then add the AngularJS and jQuery libraries to our web page as well as the rest of the script files, i.e. app.js, papaparse.js, and papaparse.min.js.

We then define the application’s controller and then bind the HTML controls to the application data.

Download a CSV File

Since we already have the interface with the link where a user will be able to download the CSV file, we now proceed to write the Angular code that will contain the data to be downloaded, and then bind it with the HTML controls.

We then make the CSV available for download on the client side.

In app.js, initialize the Angular app and define the CsvCtrl controller.

'use strict';


/* App Module */
var app = angular.module("myApp", []);

Next, define the sample data in JSON and convert it to a CSV file with the help of the Papa Parse module.

app.controller("CsvCtrl", ["$scope", "$q", function($scope,$q) {
    
    var clearAlerts = function() {
      $scope.error = {}, $scope.warning = null
    };
      
    $scope.download = function(){
      var a = document.createElement("a");
      var json_pre = '[{"Reference":"1","First_name":"Lauri","Last_name":"Amerman","Dob":"1980","Sex":"F"},{"Reference":"2","First_name":"Rebbecca","Last_name":"Bellon","Dob":"1977","Sex":"F"},{"Reference":"3","First_name":"Stanley","Last_name":"Benton","Dob":"1984","Sex":"M"}]'
     
      var csv = Papa.unparse(json_pre);

      if (window.navigator.msSaveOrOpenBlob) {
        var blob = new Blob([decodeURIComponent(encodeURI(csv))], {
          type: "text/csv;charset=utf-8;"
        });
        navigator.msSaveBlob(blob, 'sample.csv');
      } else {

        a.href = 'data:attachment/csv;charset=utf-8,' + encodeURI(csv);
        a.target = '_blank';
        a.download = 'sample.csv';
        document.body.appendChild(a);
        a.click();
      }
    }
}]);

Uploading and Reading a CSV File

Here is the Angular function that uploads and reads a CSV file.

app.controller("CsvCtrl", ["$scope", "$q", function($scope,$q) {
    
    // ...  the rest of the code
    
    // Upload and read CSV function
    $scope.submitForm = function(form) {
        clearAlerts();
        var filename = document.getElementById("bulkDirectFile");
        if (filename.value.length < 1 ){
            ($scope.warning = "Please upload a file");
        } else {
            $scope.title = "Confirm file";
            var file = filename.files[0];
            console.log(file)
            var fileSize = 0;
            if (filename.files[0]) {
                 
                var reader = new FileReader();
                reader.onload = function (e) {
                    var table = $("<table />").css('width','100%');
                    
                    var rows = e.target.result.split("n");
                    for (var i = 0; i < rows.length; i++) {
                        var row = $("<tr  />");
                        var cells = rows[i].split(",");
                        for (var j = 0; j < cells.length; j++) {
                            var cell = $("<td />").css('border','1px solid black');
                            cell.html(cells[j]);
                            row.append(cell);
                        }
                        table.append(row);
                    }
                    $("#dvCSV").html('');
                    $("#dvCSV").append(table);
                }
                
                reader.readAsText(filename.files[0]);
            
            }
            return false;
        }
    }
         
}]);

Here, we confirm if the CSV is valid and not empty. If it is empty or no CSV file has been uploaded, we give the user a warning message: “Please upload a file.” If the CSV is valid, we convert the data to a table format and present it as shown below.

How to Upload and Download CSV Files With AngularJS

Convert a CSV File to JSON

In the last part of this tutorial, will be converting the CSV data to JSON format (a form that can be consumed by an API). Below is the function that converts the CSV data to JSON. We will only print the data to the console since we don’t have an API for consuming the data.

app.controller("CsvCtrl", ["$scope", "$q", function($scope,$q) {
    
    // ...
    
    //   Convert to JSON function
    $scope.add = function(){
        var Table = document.getElementById('Table');
        var file = document.getElementById("bulkDirectFile").files[0];
        $('.loading').show();
        var allResults = [];
        
        Papa.parse(file, {
            download: true,
            header: true,
            skipEmptyLines: true,
            error: function(err, file, inputElem, reason) { },
            complete: function(results) {
                allResults.push(results.data);
                console.log(results.data)
                
            }
          });   
        }
    }    
}]);

In the function above, we get the CSV file and use Papa Parse to convert it to JSON. The complete code in app.js is shown below.

Conclusion

In this post, you saw how to upload and download CSV data, and how to parse CSV data into and out of JSON.

I hope this tutorial has helped you understand how to manipulate CSV files with the Papa Parse module and how powerful that library is. Feel free to experiment with larger files to see the full functionality of the Papa Parse library.