Reputation: 223
I am trying to create a JSON file from the data received from a CSV file uploaded using a file uploader input.
I have found lots of posts doing this in Javascript but they just aren't quite working for me in Typescript.
The error I get when running the below code is csv.Split is not a function, does anyone have any ideas how I can alter my code to work.
Let me know if you need more information and Thanks in advance.
component.ts
public testFile() {
var file = (<HTMLInputElement>document.getElementById('fileInput')).files[0];
var jsonFile = this.csvJSON(file);
// Set Http POST options
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
// Call Api with test connection data
this.http
.post('/api/TestConnection/TestConnection', jsonFile, options)
.subscribe(data => {
// alert request ok
alert('ok');
}, error => {
// Log error
console.log(error.json());
});
}
public csvJSON(csv) {
var lines = csv.split("\n");
var result = [];
var headers = lines[0].split(",");
for (var i = 1; i < lines.length; i++) {
var obj = {};
var currentline = lines[i].split(",");
for (var j = 0; j < headers.length; j++) {
obj[headers[j]] = currentline[j];
}
result.push(obj);
}
//return result; //JavaScript object
return JSON.stringify(result); //JSON
}
Upvotes: 15
Views: 43737
Reputation: 1
import * as XLSX from 'xlsx'
uploadCSVFile(event) {
const target: DataTransfer = <DataTransfer>(event.target);
if (target.files.length !== 1) {
throw new Error('Cannot use multiple files');
}
const filereader: FileReader = new FileReader();
const selectedfile = event.target.files[0];
filereader.readAsBinaryString(selectedfile);
filereader.onload = (event:any)=>{
let binarydata = event.target.result;
let workbook = XLSX.read (binarydata,{type:'binary'})
workbook.SheetNames.forEach(sheet=>{
const data = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]);
console.log(data);
})
}
}
do npm install xlsx;
in html
<input type="file" class="upload" (change)="uploadCSVFile($event)">
Upvotes: 0
Reputation: 1116
Here is my work on CSV to JSON worked perfectly.
contact-imports.component.ts
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { ToastrService } from 'ngx-toastr';
@Component({
selector: 'app-contact-imports',
templateUrl: './contact-imports.component.html',
styleUrls: ['./contact-imports.component.scss']
})
export class ContactImportsComponent implements OnInit {
csvContent: string;
contacts: Array<any> = [];
properties:any = "";
flag:boolean = false;
constructor( private toastr: ToastrService) { }
ngOnInit() {
}
onFileLoad(fileLoadedEvent) {
const textFromFileLoaded = fileLoadedEvent.target.result;
this.csvContent = textFromFileLoaded;
//Flag is for extracting first line
let flag = false;
// Main Data
let objarray: Array<any> = [];
//Properties
let prop: Array<any> = [];
//Total Length
let size: any = 0;
for (const line of this.csvContent.split(/[\r\n]+/)) {
if (flag) {
let obj = {};
for (let k = 0; k < size; k++) {
//Dynamic Object Properties
obj[prop[k]] = line.split(',')[k]
}
objarray.push(obj);
} else {
//First Line of CSV will be having Properties
for (let k = 0; k < line.split(',').length; k++) {
size = line.split(',').length;
//Removing all the spaces to make them usefull, also removing any " characters
prop.push(line.split(',')[k].replace(/ /g, '').replace(/"/g, ""));
}
flag = true;
}
}
this.contacts = objarray;
this.properties = [];
this.properties = prop;
console.log(this.properties);
console.log(this.contacts);
this.flag = true;
// console.log(this.csvContent);
}
onFileSelect(input: HTMLInputElement) {
const files = input.files;
var fileTypes = ['csv']; //acceptable file types
if (files && files.length) {
var extension = input.files[0].name.split('.').pop().toLowerCase(), //file extension from input file
isSuccess = fileTypes.indexOf(extension) > -1; //is extension in acceptable types
//console.log(isSuccess);
// console.log("Filename: " + files[0].name);
// console.log("Type: " + files[0].type);
// console.log("Size: " + files[0].size + " bytes");
if(isSuccess){
const fileToRead = files[0];
const fileReader = new FileReader();
fileReader.onload = this.onFileLoad;
fileReader.readAsText(fileToRead, "UTF-8");
}else{
this.toastr.error("Invalid File Type", 'Failed');
}
}
}
}
contact-imports.component.html
<div class="container-fluid">
<div class="col-md-6">
<img src="https://img.icons8.com/color/48/000000/csv.png"/>
<span class="text-muted" style="font-size: 22px;">Import Contacts From CSV</span>
<div class="form-group">
<input class="form-control" accept=".csv" id="csv" type="file" (change)="onFileSelect($event.target)" name="myfile">
</div>
</div>
</div>
Upvotes: 5
Reputation: 677
HTML
<input type="file" accept=".csv (change)="csv2Array($event)">
Typescript
csv2Array(fileInput: any){
//read file from input
this.fileReaded = fileInput.target.files[0];
let reader: FileReader = new FileReader();
reader.readAsText(this.fileReaded);
reader.onload = (e) => {
let csv: string = reader.result;
let allTextLines = csv.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
console.log(tarr);
lines.push(tarr);
}
}
// all rows in the csv file
console.log(">>>>>>>>>>>>>>>>>", lines);
}
}
Upvotes: 2
Reputation: 37918
You are passing File
to csvJSON
method instead of file's text. You can use FileReader
to read its content. Here's an example
const convertFile = () => {
const input = document.getElementById('fileInput');
const reader = new FileReader();
reader.onload = () => {
let text = reader.result;
console.log('CSV: ', text.substring(0, 100) + '...');
//convert text to json here
//var json = this.csvJSON(text);
};
reader.readAsText(input.files[0]);
};
<input type='file' onchange='convertFile(event)' id='fileInput'>
Upvotes: 15