javascript - 如何正确地将结果保存在变量中?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', width: 15 },
{ header: 'Date', key: 'date', width: 15 },
{ 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 文件
推荐阅读
- python - 如何使用boto3的export_image?
- javascript - 在我期待测试中的某些内容之前,如何等待“finally”块运行?
- python-3.x - 绘制聚合日期时间索引,错误轴必须设置“频率”以转换为周期
- javascript - 当某人的数据输入到工作表时,如何在 Google 工作表中自动运行脚本?
- .net - 适用于 MacOS 的 .NET 6 Preview SDK 安装程序是否会删除我以前的 .NET 5 SDK 包?
- api - How to define a field in an object is unique in openapi?
- amazon-web-services - 如何在 AWS 和 Azure 之间集成事件驱动架构
- import - 无法使用自定义道具制作或建造卡拉
- postgresql - 是否可以将查询结果与 WAL 发布相匹配?
- python - 使用熊猫,如何根据另一列的值分配列中的值?