Articles in this section
Category / Section

How to display a Spinner while saving an Angular Spreadsheet?

6 mins read

This knowledge base article explains how to show a spinner during the save action in an Angular Spreadsheet. In the Spreadsheet component, the save action is performed asynchronously on a separate thread. Therefore, any spinner will not be displayed during the save action.

To achieve this, you need to create an own spinner element and append it to the Spreadsheet in the created event, which is triggered once the Spreadsheet is loaded in the UI. Then, while saving the spreadsheet, you should prevent the default save action by setting args.cancel to true and display the spinner in the beforeSave event. After that, you need to call a custom save function to handle the save action in the Spreadsheet.

In the custom save function, you can save the spreadsheet as JSON data using the saveAsJson method. Then, create a formData object by appending the fileName, saveType, and JSON data, and send it to the server in a fetch call. After receiving the server’s response, you can hide the spinner, convert the response to a blob, and download it as an Excel file. And after the custom save action completes, you need to hide the custom spinner. The custom spinner can be showed and hided based on the classname.

[app.component.html]

<div class="control-section">
   <ejs-spreadsheet #default [openUrl]="openUrl" [saveUrl]="saveUrl" (created)="created()" (beforeSave)="beforeSave($event)">
       <e-sheets>
           <e-sheet name="Car Sales Report">
               <e-ranges>
                   <e-range [dataSource]="data"></e-range>
               </e-ranges>
               <e-columns>
                   <e-column [width]=180></e-column>
                   <e-column [width]=130></e-column>
                   <e-column [width]=130></e-column>
                   <e-column [width]=180></e-column>
                   <e-column [width]=130></e-column>
                   <e-column [width]=120></e-column>
               </e-columns>
           </e-sheet>
       </e-sheets>
   </ejs-spreadsheet>
</div> 

[app.component.ts]

import { Component, ViewEncapsulation, Inject, ViewChild } from '@angular/core';
import { getDefaultData } from './data';
import { SpreadsheetComponent, SpreadsheetModule } from '@syncfusion/ej2-angular-spreadsheet';
import { classList, createElement } from '@syncfusion/ej2-base';

@Component({
   selector: 'app-root',
   templateUrl: 'app.component.html',
   styleUrls: ['app.component.css'],
   encapsulation: ViewEncapsulation.None,
   standalone: true,
   imports: [SpreadsheetModule,]
})

export class AppComponent {
   constructor() {

   }
   @ViewChild('default')
   public spreadsheetObj: SpreadsheetComponent;
   public data: Object[] = getDefaultData();
   private loader: HTMLElement;
   public isSave: boolean = true;
   public openUrl = 'https://services.syncfusion.com/angular/production/api/spreadsheet/open';
   public saveUrl = 'https://services.syncfusion.com/angular/production/api/spreadsheet/save';
   created() {
       this.loader = this.spreadsheetObj.createElement('div', { className: 'e-custom-spinner e-spinner-pane e-spin-hide' });
       this.loader.appendChild(this.spreadsheetObj.createElement('div', { className: 'e-ss-custom-loader' }));
       this.spreadsheetObj.element.appendChild(this.loader);
   }
   beforeSave(args) {
       if (this.isSave) {
           args.cancel = true; // Preventing default save action.
           //Show the custom spinner.
           classList(this.loader, ['e-spin-show'], ['e-spin-hide']);
           this.isSave = false; // The beforeSave event will trigger for saveAsJson action also, so we are preventing for the saveAsJson using the variable.
           //Used setTimeout to hide the save dialog and show the spinner.
           setTimeout(() => {
               this.saveExcel(args);
           }, 450)
       }
   }
   saveExcel(args) {
       this.spreadsheetObj.saveAsJson().then((response: any) => {
           this.isSave = true;
           let formData = new FormData();
           formData.append('JSONData', JSON.stringify(response.jsonObject.Workbook));
           formData.append('fileName', args.fileName);
           formData.append('saveType', args.saveType);
           formData.append('pdfLayoutSettings', JSON.stringify({ fitSheetOnOnePage: true, orientation: 'Portrait' }));
           fetch(
               args.url,
               {
                   method: 'POST',
                   body: formData,
               }
           ).then((response) => {
               //To hide the custom spinner.
               classList(this.loader, ['e-spin-hide'], ['e-spin-show']);
               if (response.ok) {
                   response.blob().then((data) => {
                       let anchor: any = createElement('a', {
                           attrs: { download: args.fileName },
                       });
                       const url = URL.createObjectURL(data);
                       anchor.href = url;
                       document.body.appendChild(anchor);
                       anchor.click();
                       URL.revokeObjectURL(url);
                       document.body.removeChild(anchor);
                   });
               }
           });
       });
   }
} 

[app.component.css]

/* Custom spinner styles */
.e-ss-custom-loader {
   border: 3px solid transparent;
   border-radius: 50%;
   border-top: 3px solid #e3165b;
   border-right: 3px solid #e3165b;
   -webkit-animation: spin 2s linear infinite; /* Safari */
   animation: spin 2s linear infinite;
   position: absolute;
   top: 50%;
   left: 50%;
   margin: -15px 0 0 -15px;
   width: 30px;
   height: 30px;
   z-index: 1001;
}
/* Safari */
@-webkit-keyframes spin {
   0% { -webkit-transform: rotate(0deg); }
   100% { -webkit-transform: rotate(360deg); }
}
@keyframes spin {
   0% { transform: rotate(0deg); }
   100% { transform: rotate(360deg); }
}
/* custom code end*/ 

Sample Link: https://stackblitz.com/edit/angular-tkljft-6xp5nh

Output:

Custom_spinner.gif

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please  to leave a comment
Access denied
Access denied