Here's an example I created on stackblitz: https://stackblitz.com/edit/angular-k162aa
The main CSV parsing function is described below with inline comments:
// CSV is assumed to have headers as well
csvToJSON(csv: string) {
const lines: string[] = csv
// escape everything inside quotes to NOT remove the comma there
.replace(/"(.*?)"/gm, (item) => encodeURIComponent(item))
// split by lines
.split('\n');
// separate the headers from the other lines and split them
const headers: string[] = lines.shift().split(',');
// should contain all CSV lines parsed for the html table
const data: any[] = lines.map((lineString, index) => {
const lineObj = {};
const lineValues = lineString.split(',');
headers.forEach((valueName, index) => {
// remove trailing spaces and quotes
lineObj[valueName] = lineValues[index]
// handle quotes
.replace(/%22(.*?)%22/gm, (item) => decodeURIComponent(item))
// trim trailing spaces
.trim();
})
return lineObj; // return lineValues for array representation.
});
return { data, headers };
}
csvToJSON(csv: string) {
const lines: string[] = csv.split('\n');
// separate the headers from the other lines and split them
const headers: string[] = lines.shift().split(',');
// should contain all CSV lines parsed for the html table
const data: string[][] = lines.map((lineString, index) => {
const lineObj = {};
const lineValues = lineString.split(',');
headers.forEach((valueName, index) => {
lineObj[valueName] = lineValues[index];
});
return lineObj; // return lineValues for an array.
});
return { data, headers };
}
Notice that the commented code can give you an array of arrays, while the code as is, returns an array of objects.
In the HTML, this format is easier to render since the index of the headers is the same as the index of each item array:
<table class="table">
<thead>
<tr>
<th *ngFor="let header of headers">{{ header }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of data">
<td *ngFor="let header of headers">
{{ row[header] }}
</td>
</tr>
</tbody>
</table>
To support row headers, you can use the following html snippet for the table body section:
<tr *ngFor="let row of data">
<ng-container *ngFor="let attribute of row; let i = index">
<td *ngIf="i">{{ attribute }}</td>
<th *ngIf="!i">{{ attribute }}</th>
</ng-container>
</tr>