Reading .xlsx files with the SheetJS library in Aangular

50 views Asked by At

I am a novice developer and am looking to start taking on some slightly more complex projects using the Angular Framework. The intention is to work on a component that takes an external data source in Excel or CSV format and through a Parsing managed by the "XLSX" library, can retrieve the data and manage the display with an Angular Material table (like this one: https://material.angular.io/components/table/overview

However, I am experiencing a lot of problems with the logic part and by debugging, I realised that the file does not even read. I still don't quite understand where the problem lies!!!!

folder structure is as follows

enter image description here

This is the **table.component.ts** This file contains the logic that takes care of linking the data to the table

// dashboard.component.ts
// import { MatTableModule } from '@angular/material/table';
import { MatTableDataSource } from '@angular/material/table';
import * as xlsx from 'xlsx';
import { read, utils, writeFile } from 'xlsx';
import { Component, OnInit } from '@angular/core';
import { FileService } from '../../Services/FileServices';


@Component({
  selector: 'table-basic-example',
  styleUrls: ['table-data.component.css'],
  templateUrl: 'table-data.component.html',
  standalone: false,
  // imports: [MatTableModule],
})
export class TableBasicExample implements OnInit {
  ExcelData: any[] = []; // Usato per la tabella

  constructor(private fileService: FileService) {}

  ngOnInit(): void {
    // Chiamare la funzione per leggere il file quando il componente viene inizializzato
    this.loadExcelData();
  }

  loadExcelData(): void {
    const filePath = 'assets/data.xlsx'; // Percorso del file Excel

    this.fileService.readExcel(filePath)
      .then((data) => {
        // Dati letti con successo
        console.log('Dati letti:', data);
        this.ExcelData = data;
      })
      .catch((error) => {
        // Gestione degli errori
        console.error('Errore durante la lettura del file:', error);
      });
      
  }
}

This is the **table.component.html** This file is the Table Component Template, located in the 'src/app/Components/table-data' folder, and contains the tags to extract the rows from the ExcelData variable and generate the table that will contain the data.

<div class="container m-5">
  <!-- <h1 class="text-primary text-center">Leggi file Excel e mostra nella tabella</h1>
  <input type="file" class="form-control w-50" (change)="ReadExcelFile($event)" > -->
  <table mat-table [dataSource]="ExcelData" *ngIf="ExcelData && ExcelData.length > 0" class="mat-elevation-z8">

    <!--- Note that these columns can be defined in any order.
          The actual rendered columns are set as a property on the row definition" -->
  
    <!-- Position Column -->
    <ng-container matColumnDef="data">
      <th mat-header-cell *matHeaderCellDef> Data </th>
      <td mat-cell *matCellDef="let element"> {{element.data}} </td>
    </ng-container>
  
    <!-- Name Column -->
    <ng-container matColumnDef="tempMedia">
      <th mat-header-cell *matHeaderCellDef> TMedia °C </th>
      <td mat-cell *matCellDef="let element"> {{element.tempMedia}} </td>
    </ng-container>
  
     <!-- Temperatura minima Column -->
     <ng-container matColumnDef="tempMin">
      <th mat-header-cell *matHeaderCellDef> Tmin °C </th>
      <td mat-cell *matCellDef="let element"> {{element.tempMin}} </td>
    </ng-container>

    <!-- Weight Column -->
    <ng-container matColumnDef="tempMax">
      <th mat-header-cell *matHeaderCellDef> TMAX °C </th>
      <td mat-cell *matCellDef="let element"> {{element.tempMax}} </td>
    </ng-container>
  
    <!-- Symbol Column -->
    <ng-container matColumnDef="umiditaRelativa">
      <th mat-header-cell *matHeaderCellDef> UMIDITA % </th>
      <td mat-cell *matCellDef="let element"> {{element.umiditaRelativa}} </td>
    </ng-container>
  
      <!-- Symbol Column -->
      <ng-container matColumnDef="visibilitaKm">
        <th mat-header-cell *matHeaderCellDef> VISIBILITA km </th>
        <td mat-cell *matCellDef="let element"> {{element.visibilitaKm}} </td>
      </ng-container>

        <!-- Symbol Column -->
    <ng-container matColumnDef="ventoMediaSpeed">
      <th mat-header-cell *matHeaderCellDef> VENTOMEDIA km/h </th>
      <td mat-cell *matCellDef="let element"> {{element.ventoMediaSpeed}} </td>
    </ng-container>

      <!-- Symbol Column -->
      <ng-container matColumnDef="ventoMaxSpeed">
        <th mat-header-cell *matHeaderCellDef> VENTOMAX km/h </th>
        <td mat-cell *matCellDef="let element"> {{element.ventoMaxSpeed}} </td>
      </ng-container>

        <!-- Symbol Column -->
    <ng-container matColumnDef="pressioneSlm">
      <th mat-header-cell *matHeaderCellDef> PRESSIONESLM mb </th>
      <td mat-cell *matCellDef="let element"> {{element.pressioneSlm}} </td>
    </ng-container>

      <!-- Symbol Column -->
      <ng-container matColumnDef="pioggiamm">
        <th mat-header-cell *matHeaderCellDef> PIOGGIA mm </th>
        <td mat-cell *matCellDef="let element"> {{element.pioggiamm}} </td>
      </ng-container>

        <!-- Symbol Column -->
    <ng-container matColumnDef="irraggiamento">
      <th mat-header-cell *matHeaderCellDef> Irraggiamento [Wh/m²]  </th>
      <td mat-cell *matCellDef="let element"> {{element.irraggiamento}} </td>
    </ng-container>


    <!-- <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> -->
    <!-- <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> -->
  </table>
  
  

This is the **FileServices.ts**: This file is a Service, located in the 'src/app/Services' folder, and has the function of reading the .xlsx source file, reading internal sheet and field information, and parsing each line.

// file.service.ts
import { Injectable } from '@angular/core';
import * as XLSX from 'xlsx';

@Injectable({
  providedIn: 'root',
})
export class FileService {
  constructor() {}

  // Funzione per leggere e parserizzare il file Excel
  readExcel(filePath: string): Promise<any[]> {
    return new Promise((resolve, reject) => {
      // Sostituire con il percorso del tuo file Excel
      fetch(filePath)
        .then((response) => response.blob())
        .then((blob) => {
          const file = new File([blob], 'assets/data.xlsx', { type: 'application/vnd.ms-excel' });

          const reader = new FileReader();

          reader.onload = (e: any) => {
            const data = new Uint8Array(e.target.result);
            const workbook = XLSX.read(data, { type: 'array' });
            const firstSheetName = workbook.SheetNames[0];
            const worksheet = workbook.Sheets[firstSheetName];
            const jsonData = XLSX.utils.sheet_to_json(worksheet, { raw: true });

            console.log('Dati letti:', jsonData); // Aggiungi questo console.log
            resolve(jsonData);
          };

          reader.onerror = (error) => reject(error);

          reader.readAsArrayBuffer(file);
        })
        .catch((error) => reject(error));
    });
  }
}

Thank you to everyone who would like to help me!!!

I have tried several times to revise the logic by changing the approach.

I also tried loading the file via an

<input type="file"> tag to make sure the path was selected correctly.
0

There are 0 answers