Sunday, 16 July 2017

Read local csv file in Angular2

Reading local csv file in Angular2.


Read local csv file in Angular2 with example. upload .csv file in javascript. Display CSV or text file using JavaScript, JQuery, Bootstrap and Angular2.


We will Read, Parse and Display .csv file records in Angular2.



Download the sample application from below link,

Github page: https://github.com/javabypatel/Angular2-Read-CSV-File
Download Sample application: Download

Sample applicaton features:
  1. Sample application provides simple and easy to use UI to play with application as shown below,

  2. It provides configurable on/off validations feature as shown below.
        
    //keep the flag true if csv contains header else not, this falg will help in validations.
    static isHeaderPresentFlag = true; 
    
    //keep the flag true if you want to validate each records length to match with header length, false otherwise.
    static validateHeaderAndRecordLengthFlag = true;
    
    //keep the flag true if you want file with only .csv extensions should be read, false otherwise.
    static valildateFileExtenstionFlag = true;
    

  3. Configurable token delimeter.
        
    static tokenDelimeter = ",";
    

Lets start with steps to start the sample application.
 
STEP 1:  
Download the sample application from here

STEP 2:  
Open command prompt, navigate to application folder and run "npm install" command.

(This step will download all development dependencies. It may take some time to dowload all dependencies. if you face any issue while downloading, open the command prompt as "Run as Administrator" and then execute "npm install")

STEP 3
Open command prompt, navigate to application folder and run "npm run server" command.
This step will start the server. 

STEP 4: 
After server starts, start the application by hitting "http://localhost:8080/" in browser.

STEP 5: 
Application will get started and you can play with application by importing sample csv files present along with bundle.

Screen will look like below,

Github page: https://github.com/javabypatel/Angular2-Read-CSV-File
Download Sample application: Download

Note:  
In this sample application, we are simply displaying the contents of uploaded csv file, 
If required you can also send the csv data to backend server.

Explanation

test.component.html
<input type="file" 
 #fileImportInput
 name="File Upload" 
 id="txtFileUpload" 
 class="btn btn-primary" 
 (change)="fileChangeListener($event)" 
 accept=".csv"/>

test.component.ts
import { Component, OnInit, ViewChild } from "@angular/core";
import { Router }                       from "@angular/router";
import { FileUtil }                     from './file.util';
import { Constants }                    from './test.constants';

@Component({
  template: require('./test.component.html')
})

export class TestComponent implements OnInit {

  @ViewChild('fileImportInput')
  fileImportInput: any;

  csvRecords = [];

  constructor(private _router: Router,
    private _fileUtil: FileUtil
  ) { }

  ngOnInit() { }

  // METHOD CALLED WHEN CSV FILE IS IMPORTED
  fileChangeListener($event): void {

    var text = [];
    var files = $event.srcElement.files;

    if(Constants.validateHeaderAndRecordLengthFlag){
      if(!this._fileUtil.isCSVFile(files[0])){
        alert("Please import valid .csv file.");
        this.fileReset();
      }
    }

    var input = $event.target;
    var reader = new FileReader();
    reader.readAsText(input.files[0]);

    reader.onload = (data) => {
      let csvData = reader.result;
      let csvRecordsArray = csvData.split(/\r\n|\n/);

      var headerLength = -1;
      if(Constants.isHeaderPresentFlag){
        let headersRow = this._fileUtil.getHeaderArray(csvRecordsArray, Constants.tokenDelimeter);
        headerLength = headersRow.length; 
      }
      
      this.csvRecords = this._fileUtil.getDataRecordsArrayFromCSVFile(csvRecordsArray, 
          headerLength, Constants.validateHeaderAndRecordLengthFlag, Constants.tokenDelimeter);
      
      if(this.csvRecords == null){
        //If control reached here it means csv file contains error, reset file.
        this.fileReset();
      }    
    }

    reader.onerror = function () {
      alert('Unable to read ' + input.files[0]);
    };
  };

  fileReset(){
    this.fileImportInput.nativeElement.value = "";
    this.csvRecords = [];
  }

}


file.util.ts
import { Injectable }       from '@angular/core';

@Injectable()
export class FileUtil {

    constructor() {}

    isCSVFile(file) {
        return file.name.endsWith(".csv");
    }

    getHeaderArray(csvRecordsArr, tokenDelimeter) {        
        let headers = csvRecordsArr[0].split(tokenDelimeter);
        let headerArray = [];
        for (let j = 0; j < headers.length; j++) {
            headerArray.push(headers[j]);
        }
        return headerArray;
    }

    validateHeaders(origHeaders, fileHeaaders) {
        if (origHeaders.length != fileHeaaders.length) {
            return false;
        }

        var fileHeaderMatchFlag = true;
        for (let j = 0; j < origHeaders.length; j++) {
            if (origHeaders[j] != fileHeaaders[j]) {
                fileHeaderMatchFlag = false;
                break;
            }
        }
        return fileHeaderMatchFlag;
    }

    getDataRecordsArrayFromCSVFile(csvRecordsArray, headerLength, 
        validateHeaderAndRecordLengthFlag, tokenDelimeter) {
        var dataArr = []

        for (let i = 0; i < csvRecordsArray.length; i++) {
            let data = csvRecordsArray[i].split(tokenDelimeter);
            
            if(validateHeaderAndRecordLengthFlag && data.length != headerLength){
                if(data==""){
                    alert("Extra blank line is present at line number "+i+", please remove it.");
                    return null;
                }else{
                    alert("Record at line number "+i+" contain "+data.length+" tokens, and is not matching with header length of :"+headerLength);
                    return null;
                }
            }

            let col = [];
            for (let j = 0; j < data.length; j++) {
                col.push(data[j]);
            }
            dataArr.push(col);
        }   
        return dataArr;
    }

}


test.constants.ts
import { Injectable } from '@angular/core';

@Injectable()
export class Constants {
    static tokenDelimeter = ",";
    static isHeaderPresentFlag = true;
    static validateHeaderAndRecordLengthFlag = true;
    static valildateFileExtenstionFlag = true;
}

Please drop a comment if you see any error in sample application.

You may also like to see


Download binary file AngularJS + REST service

Configure Angular2 + Webpack + Maven Sample + Sample WebApp in Java

Number Range Spinner in Angular JS

Using JQuery Datatable with AngularJS 

What is Websocket. Use of Websocket. Client server example using Websockets, AngularJS and Java.

Enjoy !!!! 

If you find any issue in post or face any error while implementing, Please comment.

No comments:

Post a Comment