如何将结果正确保存到变量中? XLSX角度

问题描述

我正在尝试使用Angular从输入中读取一个Excel文件,并将该文件的数据转换为对象数组。我的组件是这样的:

import * as XLSX from 'xlsx';
import { Injectable } from '@angular/core';

@Injectable({ providedIn:'root' })
export class ExcelService {

    arrayBuffer: any;

    constructor() {}

    xlsxToJSON(event) {
        let arreglo;   
        let fileReader = new FileReader();    
        fileReader.readAsArrayBuffer(event);
        fileReader.onload = async(e)  => {    
            this.arrayBuffer = fileReader.result;    
            let data = new Uint8Array(this.arrayBuffer);    
            let arr = new Array();    
            for(let i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);    
            let bstr = arr.join("");    
            let workbook = XLSX.read(bstr,{type:"binary"});    
            let first_sheet_name = workbook.SheetNames[0];    
            let worksheet = workbook.Sheets[first_sheet_name];    
            // console.log(XLSX.utils.sheet_to_json(worksheet,{raw:true}));
            // arraylist es el JSON después de tratar la data del excel
            let arraylist = XLSX.utils.sheet_to_json(worksheet,{raw:true});
            arreglo = arraylist;
            console.log('El arraylist'+ arraylist);
            console.log(typeof arraylist);
            console.log('Excel Service: '+arraylist);
            console.log(arreglo);
            return arraylist;
        }
        console.log('ULTIMO LOG'+arreglo);
    } 
}

我有一项服务可以从其他组件中使用它:

import { Component,OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { ExcelService } from '../services/excel.service';

@Component({
  selector: 'app-Zorro',templateUrl: './Zorro.component.html',styleUrls: ['./Zorro.component.css']
})
export class ZorroComponent implements OnInit {

  file: File;

  ngOnInit() {}
  
  async importExcel (event) {
    this.file = (event.target as HTMLInputElement).files[0]; 
    const result = await this.excelService.xlsxToJSON(this.file);
    console.log('Result: '+result);
  }
}

然后是我的HTML组件:

<div class="container">
  <div class="row">
    <div class="col-md-12 form-group">        
      <input 
        type="file" 
        class="form-control" 
        (change)="importExcel($event)" 
        placeholder="Upload file" 
        accept=".csv,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel">        
    </div>
  </div>
</div>

我使用许多“ console.log()”来查看得到的内容,直到现在我可以将该文件转换为JS对象,但是当我需要使用结果时,保存结果的变量是未定义,我想发生这种情况是因为该过程是异步的,我已经尝试了async / await,但是没有成功。目标是采用此对象数组并将其发送到后端,然后发送到数据库

解决方法

import { Component,OnInit } from '@angular/core';
import { DataService } from '../../services/data.service';
import * as jspdf from 'jspdf';
import html2canvas from 'html2canvas';
// import * as XLSX from 'xlsx';

import * as ExcelJS from 'exceljs';
import * as FileSaver from 'file-saver';

import { ViewChild,ElementRef } from '@angular/core';

@Component({
  selector: 'app-items-report',templateUrl: './items-report.component.html',styleUrls: ['./items-report.component.css']
})
export class ItemsReportComponent implements OnInit {

  purchases: any;
  constructor(private dataService: DataService) {
    this.GetPurchases();
  }

  ngOnInit(): void {
  }

  async GetPurchases() {
    const response = await this.dataService.GetPurchases();
    const dataService = await response.json();
    this.purchases = dataService;
  }


  downloadExcel() {

    // using instead of Date.now()
    const date = new Date().toISOString().slice(0,10).split('-').reverse().join('/');
    console.log(date);

    // get help from here for excel file export using excelJS with alignment
    // in your tsconfig.app.json u must use "types": ["node"] if u use exceljs
    // https://stackoverflow.com/questions/62127452/angular-cant-export-excel-using-exceljs-error-ts2307-cannot-find-module-s/62128182?noredirect=1#comment109909862_62128182

    const workbook = new ExcelJS.Workbook();
    const worksheet = workbook.addWorksheet('My Sheet');

    worksheet.columns = [
      { header: 'Id',key: 'id',width: 10},{ header: 'Name',key: 'name',width: 32 },{ header: 'Quantity',key: 'quantity',width: 15 },{ header: 'Rate',key: 'rate',{ header: 'Date',key: 'date',{ header: 'Total',key: 'total',width: 15 }
    ];

    // get help from here for excel cell alignment
    // https://openbase.io/js/exceljs#alignment


    for (const purchase of this.purchases) {
      worksheet.addRow({
        id: purchase.item_id,date: purchase.item_purchase_date.toString().slice(0,10).split('-').reverse().join('/'),name: purchase.item_name,quantity: purchase.item_quantity,rate: purchase.item_rate,total: purchase.item_rate * purchase.item_quantity
       })
      .alignment = { horizontal: 'left' };
    }

    worksheet.getRow(1).font = { bold: true };

    // get help from here
    // https://stackoverflow.com/questions/62149358/exceljs-iterate-each-cell-of-each-row-and-column/62149808#62149808
    worksheet.columns.forEach(column => {
      // for each non empty cell
      column.eachCell((cell,rowNumber) => {
        cell.border = {
          top: { style: 'thick' },left: { style: 'thick' },bottom: { style: 'thick' },right: { style: 'thick' }
        };
      });
    });





    // save under export.xlsx,dont use writeFile see the above stackoverflow question
    // await workbook.xlsx.writeFile('export.xlsx');
    // await maybe optional here
    workbook.xlsx.writeBuffer()
      .then(buffer => FileSaver.saveAs(new Blob([buffer]),`${date}_feedback.xlsx`))
      .catch(err => console.log('Error writing excel export',err));

}

使用exceljs。您可以看到我使用异步数据来构建excel文件