Zip 操作

一个基于 jszip 的Zip文件操作。

依赖

由于 jszip 脚本大小以及对 Zip 的操作并不是刚需的原因,因此采用一种延迟加载脚本的形式,可以通过全局配置配置来改变默认 CDN 路径,默认情况下使用 https://cdn.jsdelivr.net/npm/jszip@3/dist/jszip.min.js

使用本地路径

// angular.json
{
  "glob": "**/jszip.min.js",
  "input": "./node_modules/jszip/dist",
  "output": "assets/jszip/"
}
// global-config.module.ts
const yunzaiConfig: YunzaiConfig = {
  zip: {
    url: '/assets/jszip/jszip.min.js'
  }
};

代码演示

    解压

    读取Zip文件信息(含内容),支持 File、URL 形式。

    expand code expand code
    import { JsonPipe } from '@angular/common';
    import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject } from '@angular/core';
    
    import type jsZipType from 'jszip';
    
    import { ZipService } from '@yelon/abc/zip';
    import { NzButtonModule } from 'ng-zorro-antd/button';
    
    @Component({
      selector: 'components-zip-read',
      template: `
        <button nz-button (click)="url()">Via Url</button>
        <input type="file" (change)="change($event)" multiple="false" class="ml-sm" />
        <ol>
          @for (i of data; track $index) {
            <li>{{ i | json }}</li>
          }
        </ol>
      `,
      changeDetection: ChangeDetectionStrategy.OnPush,
      standalone: true,
      imports: [NzButtonModule, JsonPipe]
    })
    export class ComponentsZipReadComponent {
      private readonly zip = inject(ZipService);
      private readonly cdr = inject(ChangeDetectorRef);
      data: Array<{ name: string; dir: boolean; date: Date }> = [];
    
      private format(data: jsZipType): void {
        const files = data.files;
        this.data = Object.keys(files).map(key => ({
          name: key,
          dir: files[key].dir,
          date: files[key].date
        }));
        this.cdr.detectChanges();
      }
    
      url(): void {
        this.zip.read(`./assets/demo.zip`).then(res => this.format(res));
      }
    
      change(e: Event): void {
        const file = (e.target as HTMLInputElement).files![0];
        this.zip.read(file).then(res => this.format(res));
      }
    }
    压缩

    通过 pushUrl 可以快速将URL资源写入 Zip 实例。

    expand code expand code
    import { ChangeDetectorRef, Component } from '@angular/core';
    import { FormsModule } from '@angular/forms';
    
    import type jsZipType from 'jszip';
    
    import { ZipService } from '@yelon/abc/zip';
    import { NzButtonModule } from 'ng-zorro-antd/button';
    import { NzInputModule } from 'ng-zorro-antd/input';
    import { NzMessageService } from 'ng-zorro-antd/message';
    import { NzTableModule } from 'ng-zorro-antd/table';
    
    @Component({
      selector: 'components-zip-save',
      template: `
        @if (instance) {
          <button nz-button (click)="add()" [nzType]="'primary'">new</button>
          <button nz-button (click)="download()" class="ml-sm">download</button>
          <nz-table [nzData]="data" [nzFrontPagination]="false" [nzShowPagination]="false" class="mt-sm">
            <thead>
              <tr>
                <th><span>path</span></th>
                <th><span>url</span></th>
              </tr>
            </thead>
            <tbody>
              @for (i of data; track $index) {
                <tr>
                  <td><input nz-input [(ngModel)]="i.path" name="path{{ $index }}" /></td>
                  <td><input nz-input [(ngModel)]="i.url" name="url{{ $index }}" /></td>
                </tr>
              }
            </tbody>
          </nz-table>
        }
      `,
      standalone: true,
      imports: [NzButtonModule, NzTableModule, FormsModule, NzInputModule]
    })
    export class ComponentsZipSaveComponent {
      instance: jsZipType | null = null;
      data: Array<{ path: string; url: string }> = [
        { path: '小程序标志.zip', url: 'https://wximg.gtimg.com/shake_tv/mina/standard_logo.zip' }
      ];
    
      constructor(
        private zip: ZipService,
        private msg: NzMessageService,
        cdr: ChangeDetectorRef
      ) {
        this.zip.create().then(ret => {
          this.instance = ret;
          cdr.detectChanges();
        });
      }
    
      add(): void {
        this.data.push({ path: '', url: '' });
      }
    
      download(): void {
        const promises: Array<Promise<void>> = [];
        this.data.forEach(item => {
          promises.push(this.zip.pushUrl(this.instance, item.path, item.url));
        });
        Promise.all(promises).then(
          () => {
            this.zip.save(this.instance).then(() => {
              this.msg.success('download success');
              this.data = [];
            });
          },
          (error: {}) => {
            console.warn(error);
            this.msg.error(JSON.stringify(error));
          }
        );
      }
    }

    API

    ZipService

    成员说明类型默认值
    read(fileOrUrl: File | string, options?: JSZip.JSZipLoadOptions)解压Promise<JSZip>-
    create()创建 Zip 实例,用于创建压缩文件Promise<JSZip>-
    pushUrl(zip: JSZip, path: string, url: string)下载URL资源并写入 zipPromise<void>-
    save(zip: JSZip, options?: ZipWriteOptions)保存ZipPromise<void>-
    Loading...