I have one download button and table that store user data in user.component.html
file and when user clicks on the download button then it exports all the table's data into an Excel file.
I want to display a loading spinner when the download takes longer than 1.5 seconds to start.
I am using angular 8.
user.component.html
file:
<div class ="container">
<button (click)="generateExcel()">
Generate Excel</button>
<table>
-----table related data
<\table>
</div>
user.component.ts
file:
generateExcel() {
//Excel Title, Header, Data
const title = 'Car buyers Report';
const header = ["Year", "Month", "User", "Model"]
const data = [
[2007, 1, "jo", "Volkswagen Passat"],
[2007, 1, "mike ", "Toyota Rav4"],
[2007, 1, "david", "Toyota Avensis"],
[2007, 1, "milenda ", "Volkswagen Gol"]
];
//Create workbook and worksheet
let workbook = new Workbook();
let worksheet = workbook.addWorksheet('Car Data');
//Add Row and formatting
let titleRow = worksheet.addRow([title]);
titleRow.font = { name: 'Comic Sans MS', family: 4, size: 16, underline: 'double', bold: true }
worksheet.addRow([]);
let subTitleRow = worksheet.addRow(['Date : ' + this.datePipe.transform(new Date(), 'medium')])
//Add Image
let logo = workbook.addImage({
base64: logoFile.logoBase64,
extension: 'png',
});
worksheet.addImage(logo, 'E1:F3');
worksheet.mergeCells('A1:D2');
//Blank Row
worksheet.addRow([]);
//Add Header Row
let headerRow = worksheet.addRow(header);
// Cell Style : Fill and Border
headerRow.eachCell((cell, number) => {
cell.fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: 'FFFFFF00' },
bgColor: { argb: 'FF0000FF' }
}
cell.border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } }
})
// worksheet.addRows(data);
// Add Data and Conditional Formatting
data.forEach(d => {
let row = worksheet.addRow(d);
let qty = row.getCell(5);
let color = 'FF99FF99';
if (+qty.value < 500) {
color = 'FF9999'
}
qty.fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: color }
};
});
worksheet.getColumn(3).width = 30;
worksheet.getColumn(4).width = 30;
worksheet.addRow([]);
//Footer Row
let footerRow = worksheet.addRow(['This is system generated excel sheet.']);
footerRow.getCell(1).fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: 'FFCCFFE5' }
};
footerRow.getCell(1).border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } }
//Merge Cells
worksheet.mergeCells(`A${footerRow.number}:F${footerRow.number}`);
//Generate Excel File with given name
workbook.xlsx.writeBuffer().then((data) => {
let blob = new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
fs.saveAs(blob, 'CarData.xlsx');
})
}
I imagine your writeBuffer
call is what takes you the most time.
As writeBuffer
is asynchronous, you could use rxjs observables which allow you to have more complex behaviors than a classic async/await.
First convert your promise to an observable :
// here you have a promise
const wBufferPromise = workbook.xlsx.writeBuffer();
// and here you have an observable, hence the $ char in the variable name
const wBufferObservable = from(wBufferPromise );
You can then probably user timeoutWith
from RxJS (which i never used so I won't be able to help you here.
Another possible solution would be to call setTimeout(myFunc,1500)
where myFunc
sets your spinner visibility if needed.
Edit : Please have a look at Eliseo's comment.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.