import { HttpClient } from '@angular/common/http' ; import { Injectable , NgZone } from '@angular/core' ; import { saveAs } from 'file-saver' ; import { AlainConfigService , AlainZipConfig } from '@delon/util/config' ; import { ZoneOutside } from '@delon/util/decorator' ; import { LazyResult , LazyService } from '@delon/util/other' ; import type { NzSafeAny } from 'ng-zorro-antd/core/types' ; import { ZipSaveOptions } from './zip.types' ; declare var JSZip ; @ Injectable ( { providedIn : 'root' } ) export class ZipService { private cog : AlainZipConfig ; constructor ( private http , private lazy , configSrv , private ngZone ) { this . cog = configSrv . merge ( 'zip' , { url : 'https://cdn.jsdelivr.net/npm/jszip@3/dist/jszip.min.js' , utils : [ ] } ) ! ; } private init ( ) { return this . lazy . load ( [ this . cog . url ! ] . concat ( this . cog . utils ! ) ) ; } private check ( zip ) { if ( ! zip ) throw new Error ( 'get instance via `ZipService.create()`' ) ; } /** 解压 */ @ ZoneOutside ( ) read ( fileOrUrl , options ? ) { return new Promise < NzSafeAny > ( ( resolve , reject ) => { const resolveCallback = ( data ) : void => { this . ngZone . run ( ( ) => resolve ( data ) ) ; } ; this . init ( ) . then ( ( ) => { if ( typeof fileOrUrl === 'string' ) { this . http . request ( 'GET' , fileOrUrl , { responseType : 'arraybuffer' } ) . subscribe ( { next : ( res ) => { JSZip . loadAsync ( res , options ) . then ( ( ret ) => resolveCallback ( ret ) ) ; } , error : ( err ) => { reject ( err ) ; } } ) ; return ; } const reader = new FileReader ( ) ; reader . onload = ( e ) => { JSZip . loadAsync ( e . target . result , options ) . then ( ( ret ) => resolveCallback ( ret ) ) ; } ; reader . readAsBinaryString ( fileOrUrl as File ) ; } ) ; } ) ; } /** 创建 Zip 实例，用于创建压缩文件 */ create ( ) { return new Promise < NzSafeAny > ( resolve => { this . init ( ) . then ( ( ) => { const zipFile = new JSZip ( ) ; resolve ( zipFile ) ; } ) ; } ) ; } param zip param path param url pushUrl ( zip , path , url ) { this . check ( zip ) ; return new Promise < void > ( ( resolve , reject ) => { this . http . request ( 'GET' , url , { responseType : 'arraybuffer' } ) . subscribe ( { next : ( res ) => { zip . file ( path , res ) ; resolve ( ) ; } , error : ( error ) => { reject ( { url , error } ) ; } } ) ; } ) ; } param zip param options save ( zip , options ? ) { this . check ( zip ) ; const opt = { ... options } as ZipSaveOptions ; return new Promise < void > ( ( resolve , reject ) => { zip . generateAsync ( { type : 'blob' , ... opt . options } , opt . update ) . then ( ( data ) => { if ( opt . callback ) opt . callback ( data ) ; saveAs ( data , opt . filename || 'download.zip' ) ; resolve ( ) ; } , ( err ) => { reject ( err ) ; } ) ; } ) ; } }