22

i have a requirement of uploading a .CSV file and read them inside my component, i have gone through this blog but it has a .CSV file stored in a particular loaction, i want to upload the .CSV file and read them inside my component. How can i do it

Do we have any build in plugin which we can use? if not then how can we achieve this goal.

this is code which i have tried

view

<input type="file" name="File Upload" id="txtFileUpload" 
        (change)="changeListener($event)" 
        accept=".csv"/>

component

changeListener($event:Response): void {
    debugger;
   // i am not able to get the data in the CSV file
  }

in the changeListener(), i am not able tom get the content of the .CSV file, can anyone help me on this?

thank you

Lijin Durairaj
  • 3,341
  • 11
  • 31
  • 50
  • This is related to [this question](https://stackoverflow.com/questions/40214772/file-upload-in-angular-2). You can test with [this plunker example](https://plnkr.co/edit/S2jycxeyLLLFu5wFDtA8?p=preview) – 0mpurdy Aug 01 '17 at 15:41
  • 1
    https://coderexample.com/reading-csv-file-using-javascript/ totally use pappa parse to read the csv – jemiloii Aug 01 '17 at 16:12

4 Answers4

37

Upload your csv file to a location and get the csv file data. Please try this:-

Component.html:-

<input type="file" class="upload" (change)="changeListener($event.target.files)">

Component.ts:-

public changeListener(files: FileList){
  console.log(files);
  if(files && files.length > 0) {
     let file : File = files.item(0); 
       console.log(file.name);
       console.log(file.size);
       console.log(file.type);
       let reader: FileReader = new FileReader();
       reader.readAsText(file);
       reader.onload = (e) => {
          let csv: string = reader.result as string;
          console.log(csv);
       }
    }
}
Harleen Kaur Arora
  • 1,949
  • 2
  • 23
  • 55
  • 2
    @Harleen, It's throwing below error ** [ts] Type 'string | ArrayBuffer' is not assignable to type 'string'. Type 'ArrayBuffer' is not assignable to type 'string'.** – Anjali Oct 17 '18 at 11:04
  • @Anjali: Append `as string` so the line reads `let csv: string = reader.result as string;` – cdanzmann Mar 25 '19 at 18:30
  • this worked for me after a few modifications. I changed the parameter to be only `$event.target`. converted EventTarget to HTMLInputElement before getting files. and of course I returned after a null check for `inputFiles` and `inputFiles.files[0]`. Other than that, it worked flawlessly! – Rstar37 Aug 25 '22 at 04:31
3

I made a upload functionality on my app. Hope it helps

Here's my sample upload function inside my component

uploadDatasource(fileInput: any) {

let file = fileInput.target.files[0];
let fileName = file.name;


let payload = {
  file,
}

let formData: FormData = new FormData();
formData.append('file',file,file.name);


this.DsListService.uploadDatasource(formData)
  .subscribe(
    response => { 
      console.log('UPLOADING success');


    },
    error => {
      console.log('error',error)
    });

}

here's my service class

import { Injectable } from '@angular/core';
import { Headers, Http, RequestOptions, Response, URLSearchParams } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { Config } from '../config/config';

@Injectable()
export class DsListService {

  private config = new Config;

  constructor(private http: Http) { }


  uploadDatasource(payload): Observable<any[]> {
    let headers = new Headers();

    headers.append('Accept', 'application/json, text/plain,');
    let options = new RequestOptions({ headers: headers });


    return this.http.post(`API_UPLOAD_PATH`,payload, options)
      .map((res: Response) => {
        let data = res.json();
        return data;
      })
      .catch(error => Observable.throw(error))

  }
}

and here's my html

<input type="file" [(ngModel)]="Model.datasourcelistdata" name="datasource_upload" id="datasource_upload" accept=".xlsx,.xls,.csv" ngf-max-size="20MB" fd-input (change)="uploadDatasource($event)" />
vistajess
  • 667
  • 1
  • 8
  • 23
  • i dont want to upload it in a file location, i want to process the uploadded .CSV file in the angular2 itself. how can i do it? any idea – Lijin Durairaj Aug 02 '17 at 06:44
  • You can't manipulate the uploaded data/csv using Angular2 because frontend stuff cant handle file system. You need to build your logic on your server such as `nodejs`,`php`,`python` etc. – vistajess Aug 03 '17 at 11:05
2

Papa Parse wrapper library for Angular is one of the best solution to parse CSV files in Angular component. You can install the library using following command for Angular 6 and 7:

npm install ngx-papaparse@3 --save

First import the PapaParseModule into your app.

import { PapaParseModule } from 'ngx-papaparse';

@NgModule({
  ...
  imports: [
    ...
    PapaParseModule
  ]
})

In your Component Template:

<input type="file" #fileImportInput name="CSV File Upload" 
(change)="fileChangeListener($event)" accept=".csv">

Then use it in a component or service:

import { Component } from '@angular/core';
import { Papa } from 'ngx-papaparse';

@Component({
  ...
})
export class AppComponent {

    constructor(private papa: Papa) {

        // TEST IF YOUR PARSER IS WORKING FINE
        const csvData = '"Hello","World!"';

        this.papa.parse(csvData,{
            complete: (result) => {
                console.log('Parsed: ', result);
            }
        });
    }

  // LOAD CSV FILE FROM INPUT
  fileChangeListener($event: any): void {

    const files = $event.srcElement.files;

    if (files !== null && files !== undefined && files.length > 0) {
      this.selectedCSVFileName = files[0].name;

      const reader: FileReader = new FileReader();
      reader.readAsText(files[0]);
      reader.onload = e => {

        const csv = reader.result;
        const results = this.papa.parse(csv as string, { header: false });

        // VALIDATE PARSED CSV FILE
        if (results !== null && results !== undefined && results.data !== null &&
          results.data !== undefined && results.data.length > 0 && results.errors.length === 0) {
          this.isCSV_Valid = true;

          // PERFORM OPERATIONS ON PARSED CSV
          let csvTableHeader = results.data[0];

          let csvTableData = [...results.data.slice(1, results.data.length)];

        } else {
          for (let i = 0; i < results.errors.length; i++) {
            console.log( 'Error Parsing CSV File: ',results.errors[i].message);
          }
        }
      };
    } else {
      console.log('No File Selected');
    }

  }
}

*Note: In case you don't want to use a Library and manually want Parse the CSV File you can do that as well.

Here is the reference blog post to parse CSV File without any library: https://blog.developershive.com/how-to-import-csv-file-in-angular-7-no-library-needed/blog/develkwl/

Tofiq Quadri
  • 379
  • 5
  • 16
1

upload your csv file to a location and get the location URL and the uploaded csv file name and use this service i created.

import { Injectable, Inject} from '@angular/core';
import { Http } from '@angular/http';
import {HttpService} from './http.service';
@Injectable()
export class CSVSERVICE {
  csvUrl: string = './csv_upload?id=';  // URL to web API
  csvData: any[] = [];

  constructor (private http: Http) {}

  readCsvData (fileName) {
   return  this.http.get(this.csvUrl + fileName)
    .map(
      (idata) => {
        let csvData = idata['_body'] || '';
    let allTextLines = csvData.split(/\r?\n|\r/);
    let headers = allTextLines[0].split(',');
    let lines = [];

    for ( let i = 0; i < allTextLines.length; i++) {
        // split content based on comma
        let data = allTextLines[i].split(',');
        if (data.length === headers.length) {
            let tarr = [];
            for ( let j = 0; j < headers.length; j++) {
                tarr.push(data[j]);
            } 

// log each row to see output and 
            console.log(tarr);
            lines.push(tarr);
        }
    }
    return lines;
      }, // this.extractData,
      err => this.handleError(err)
    );
  }



  private handleError (error: any) {
    let errMsg = (error.message) ? error.message :
      error.status ? `${error.status} - ${error.statusText}` : 'Server error';
    console.error(errMsg);
    return errMsg;
  }
}