133 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /* sheetjs (C) 2013-present SheetJS -- https://sheetjs.com */
 | |
| /* vim: set ts=2: */
 | |
| import { Component, OnInit } from '@angular/core';
 | |
| import { File } from '@awesome-cordova-plugins/file/ngx';
 | |
| import * as XLSX from 'xlsx';
 | |
| 
 | |
| type AOA = any[][];
 | |
| 
 | |
| @Component({
 | |
|   selector: 'app-home',
 | |
|   //templateUrl: 'home.page.html',
 | |
|   styleUrls: ['home.page.scss'],
 | |
|   standalone: false,
 | |
|   template: `
 | |
| <ion-header>
 | |
|   <ion-toolbar>
 | |
|     <ion-title>SheetJS Ionic Demo</ion-title>
 | |
|   </ion-toolbar>
 | |
| </ion-header>
 | |
| 
 | |
| <ion-content [fullscreen]="true">
 | |
|   <ion-header collapse="condense">
 | |
|     <ion-toolbar>
 | |
|       <ion-title>SheetJS Demo</ion-title>
 | |
|     </ion-toolbar>
 | |
|   </ion-header>
 | |
| 
 | |
|   <ion-grid>
 | |
|     <ion-row *ngFor="let row of data">
 | |
|       <ion-col *ngFor="let val of row">
 | |
|         {{val}}
 | |
|       </ion-col>
 | |
|     </ion-row>
 | |
|   </ion-grid>
 | |
| </ion-content>
 | |
| 
 | |
| <ion-footer padding>
 | |
|   <input type="file" (change)="onFileChange($event)" multiple="false" />
 | |
|   <button ion-button color="secondary" (click)="import()">Import Data</button>
 | |
|   <button ion-button color="secondary" (click)="export()">Export Data</button>
 | |
| </ion-footer>
 | |
| `
 | |
| })
 | |
| 
 | |
| export class HomePage implements OnInit {
 | |
|   data: AOA = [[1,2,3],[4,5,6]];
 | |
|   constructor(public file: File) {}
 | |
| 
 | |
|   async ngOnInit(): Promise<void> {
 | |
|     const res: Response = await fetch("https://docs.sheetjs.com/pres.numbers");
 | |
|     const ab: ArrayBuffer = await res.arrayBuffer();
 | |
|     this.read(ab);
 | |
|   }
 | |
| 
 | |
|   read(ab: ArrayBuffer) {
 | |
|     /* read workbook */
 | |
|     const wb: XLSX.WorkBook = XLSX.read(new Uint8Array(ab), {type: 'array'});
 | |
| 
 | |
|     /* grab first sheet */
 | |
|     const wsname: string = wb.SheetNames[0];
 | |
|     const ws: XLSX.WorkSheet = wb.Sheets[wsname];
 | |
| 
 | |
|     /* save data */
 | |
|     this.data = (XLSX.utils.sheet_to_json(ws, {header: 1}) as AOA);
 | |
|   };
 | |
| 
 | |
|   write(): XLSX.WorkBook {
 | |
|     /* generate worksheet */
 | |
|     const ws: XLSX.WorkSheet = XLSX.utils.aoa_to_sheet(this.data);
 | |
| 
 | |
|     /* generate workbook and add the worksheet */
 | |
|     const wb: XLSX.WorkBook = XLSX.utils.book_new();
 | |
|     XLSX.utils.book_append_sheet(wb, ws, 'SheetJS');
 | |
| 
 | |
|     return wb;
 | |
|   };
 | |
| 
 | |
|   /* File Input element for browser */
 | |
|   onFileChange(evt: any) {
 | |
|     /* wire up file reader */
 | |
|     const target: DataTransfer = (evt.target as DataTransfer);
 | |
|     if (target.files.length !== 1) { throw new Error('Cannot use multiple files'); }
 | |
|     const reader: FileReader = new FileReader();
 | |
|     reader.onload = (e: any) => {
 | |
|       const ab: ArrayBuffer = e.target.result;
 | |
|       this.read(ab);
 | |
|     };
 | |
|     reader.readAsArrayBuffer(target.files[0]);
 | |
|   };
 | |
| 
 | |
|   /* Import button for mobile */
 | |
|   async import() {
 | |
|     try {
 | |
|       const target: string = this.file.documentsDirectory || this.file.externalDataDirectory || this.file.dataDirectory || '';
 | |
|       const dentry = await this.file.resolveDirectoryUrl(target);
 | |
|       const url: string = dentry.nativeURL || '';
 | |
|       alert(`Attempting to read SheetJSIonic.xlsx from ${url}`);
 | |
|       const ab: ArrayBuffer = await this.file.readAsArrayBuffer(url, 'SheetJSIonic.xlsx');
 | |
|       this.read(ab);
 | |
|     } catch(e) {
 | |
|       const m: string = (e as Error).message;
 | |
|       alert(m.match(/It was determined/) ? 'Use File Input control' : `Error: ${m}`);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   /* Export button */
 | |
|   async export() {
 | |
|     const wb: XLSX.WorkBook = this.write();
 | |
|     const filename = 'SheetJSIonic.xlsx';
 | |
|     try {
 | |
|       /* generate Blob */
 | |
|       const wbout: ArrayBuffer = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });
 | |
| 
 | |
|       /* find appropriate path for mobile */
 | |
|       const target: string = this.file.documentsDirectory || this.file.externalDataDirectory || this.file.dataDirectory || '';
 | |
|       const dentry = await this.file.resolveDirectoryUrl(target);
 | |
|       const url: string = dentry.nativeURL || '';
 | |
| 
 | |
|       /* attempt to save blob to file */
 | |
|       await this.file.writeFile(url, filename, wbout, {replace: true});
 | |
|       alert(`Wrote to SheetJSIonic.xlsx in ${url}`);
 | |
|     } catch(e) {
 | |
|       if((e as Error).message.match(/It was determined/)) {
 | |
|         /* in the browser, use writeFile */
 | |
|         XLSX.writeFile(wb, filename);
 | |
|       } else {
 | |
|         alert(`Error: ${(e as Error).message}`);
 | |
|       }
 | |
|     }
 | |
|   };
 | |
| }
 | |
| 
 |