简体   繁体   中英

Want to show loading spinner in angular 8

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM