Upload上传

    上传是将信息(网页、文字、图片、视频等)通过网页或者上传工具发布到远程服务器上的过程。

    • 当需要上传一个或一些文件时。
    • 当需要展现上传的进度时。
    • 当需要使用拖拽交互时。

    点击上传

    经典款式,用户点击按钮弹出文件选择框。

    1. import { NzMessageService } from 'ng-zorro-antd/message';
    2. import { NzUploadChangeParam } from 'ng-zorro-antd/upload';
    3. @Component({
    4. selector: 'nz-demo-upload-basic',
    5. template: `
    6. <nz-upload
    7. nzAction="https://www.mocky.io/v2/5cc8019d300000980a055e76"
    8. [nzHeaders]="{ authorization: 'authorization-text' }"
    9. (nzChange)="handleChange($event)"
    10. >
    11. <button nz-button><i nz-icon nzType="upload"></i>Click to Upload</button>
    12. </nz-upload>
    13. `
    14. })
    15. export class NzDemoUploadBasicComponent {
    16. constructor(private msg: NzMessageService) {}
    17. handleChange(info: NzUploadChangeParam): void {
    18. if (info.file.status !== 'uploading') {
    19. console.log(info.file, info.fileList);
    20. }
    21. if (info.file.status === 'done') {
    22. this.msg.success(`${info.file.name} file uploaded successfully`);
    23. } else if (info.file.status === 'error') {
    24. this.msg.error(`${info.file.name} file upload failed.`);
    25. }
    26. }
    27. }

    Upload上传 - 图4

    已上传的文件列表

    使用 nzFileList 设置已上传的内容。

    1. import { Component } from '@angular/core';
    2. import { NzUploadFile } from 'ng-zorro-antd/upload';
    3. @Component({
    4. selector: 'nz-demo-upload-default-file-list',
    5. template: `
    6. <nz-upload nzAction="https://www.mocky.io/v2/5cc8019d300000980a055e76" [nzFileList]="fileList">
    7. <button nz-button><i nz-icon nzType="upload"></i>Upload</button>
    8. </nz-upload>
    9. `
    10. })
    11. export class NzDemoUploadDefaultFileListComponent {
    12. fileList: NzUploadFile[] = [
    13. {
    14. uid: '1',
    15. name: 'xxx.png',
    16. status: 'done',
    17. response: 'Server Error 500', // custom error message to show
    18. url: 'http://www.baidu.com/xxx.png'
    19. },
    20. {
    21. uid: '2',
    22. name: 'yyy.png',
    23. status: 'done',
    24. url: 'http://www.baidu.com/yyy.png'
    25. },
    26. {
    27. uid: '3',
    28. name: 'zzz.png',
    29. status: 'error',
    30. response: 'Server Error 500', // custom error message to show
    31. url: 'http://www.baidu.com/zzz.png'
    32. }
    33. ];
    34. }

    完全控制的上传列表

    使用 nzFileList 对列表进行完全控制,可以实现各种自定义功能,以下演示二种情况:

    1. 上传列表数量的限制。

    2. 读取远程路径并显示链接。

    1. import { Component } from '@angular/core';
    2. import { NzUploadChangeParam, NzUploadFile } from 'ng-zorro-antd/upload';
    3. @Component({
    4. selector: 'nz-demo-upload-file-list',
    5. template: `
    6. <nz-upload nzAction="https://www.mocky.io/v2/5cc8019d300000980a055e76" [nzFileList]="fileList" (nzChange)="handleChange($event)">
    7. <button nz-button><i nz-icon nzType="upload"></i>Upload</button>
    8. </nz-upload>
    9. `
    10. })
    11. export class NzDemoUploadFileListComponent {
    12. fileList: NzUploadFile[] = [
    13. {
    14. uid: '-1',
    15. name: 'xxx.png',
    16. status: 'done',
    17. url: 'http://www.baidu.com/xxx.png'
    18. }
    19. ];
    20. handleChange(info: NzUploadChangeParam): void {
    21. let fileList = [...info.fileList];
    22. // 1. Limit the number of uploaded files
    23. // Only to show two recent uploaded files, and old ones will be replaced by the new
    24. fileList = fileList.slice(-2);
    25. // 2. Read from response and show file link
    26. fileList = fileList.map(file => {
    27. if (file.response) {
    28. // Component will show file.url as link
    29. file.url = file.response.url;
    30. }
    31. return file;
    32. });
    33. this.fileList = fileList;
    34. }
    35. }

    Upload上传 - 图6

    文件夹上传

    支持上传一个文件夹里的所有文件。

    1. import { Component } from '@angular/core';
    2. @Component({
    3. selector: 'nz-demo-upload-directory',
    4. template: `
    5. <nz-upload nzAction="https://www.mocky.io/v2/5cc8019d300000980a055e76" nzDirectory>
    6. <button nz-button><i nz-icon nzType="upload"></i> Upload Directory</button>
    7. </nz-upload>
    8. `
    9. })
    10. export class NzDemoUploadDirectoryComponent {}

    图片列表样式

    上传文件为图片,可展示本地缩略图。IE8/9 不支持浏览器本地缩略图展示(Ref),可以写 thumbUrl 属性来代替。

    上传前转换文件

    使用 nzTransformFile 转换上传的文件(例如添加水印)。

    1. import { Component } from '@angular/core';
    2. import { NzUploadFile } from 'ng-zorro-antd/upload';
    3. import { Observable, Observer } from 'rxjs';
    4. @Component({
    5. selector: 'nz-demo-upload-transform-file',
    6. template: `
    7. <nz-upload nzAction="https://www.mocky.io/v2/5cc8019d300000980a055e76" [nzTransformFile]="transformFile">
    8. <button nz-button><i nz-icon nzType="upload"></i> Upload</button>
    9. </nz-upload>
    10. `
    11. })
    12. export class NzDemoUploadTransformFileComponent {
    13. transformFile = (file: NzUploadFile) => {
    14. return new Observable((observer: Observer<Blob>) => {
    15. const reader = new FileReader();
    16. // tslint:disable-next-line:no-any
    17. reader.readAsDataURL(file as any);
    18. reader.onload = () => {
    19. const canvas = document.createElement('canvas');
    20. const img = document.createElement('img');
    21. img.src = reader.result as string;
    22. img.onload = () => {
    23. const ctx = canvas.getContext('2d')!;
    24. ctx.drawImage(img, 0, 0);
    25. ctx.fillStyle = 'red';
    26. ctx.textBaseline = 'middle';
    27. ctx.fillText('Ant Design', 20, 20);
    28. canvas.toBlob(blob => {
    29. observer.next(blob!);
    30. observer.complete();
    31. };
    32. };
    33. });
    34. };
    35. }

    Upload上传 - 图9

    用户头像

    点击上传用户头像,并使用 nzBeforeUpload 限制用户上传的图片格式和大小。

    1. import { Component } from '@angular/core';
    2. import { NzMessageService } from 'ng-zorro-antd/message';
    3. import { NzUploadFile } from 'ng-zorro-antd/upload';
    4. import { Observable, Observer } from 'rxjs';
    5. @Component({
    6. selector: 'nz-demo-upload-avatar',
    7. template: `
    8. <nz-upload
    9. class="avatar-uploader"
    10. nzAction="https://www.mocky.io/v2/5cc8019d300000980a055e76"
    11. nzName="avatar"
    12. nzListType="picture-card"
    13. [nzShowUploadList]="false"
    14. [nzBeforeUpload]="beforeUpload"
    15. (nzChange)="handleChange($event)"
    16. >
    17. <ng-container *ngIf="!avatarUrl">
    18. <i class="upload-icon" nz-icon [nzType]="loading ? 'loading' : 'plus'"></i>
    19. <div class="ant-upload-text">Upload</div>
    20. </ng-container>
    21. <img *ngIf="avatarUrl" [src]="avatarUrl" style="width: 100%" />
    22. </nz-upload>
    23. `,
    24. styles: [
    25. `
    26. :host ::ng-deep .avatar-uploader > .ant-upload {
    27. width: 128px;
    28. height: 128px;
    29. }
    30. ]
    31. })
    32. export class NzDemoUploadAvatarComponent {
    33. loading = false;
    34. avatarUrl?: string;
    35. constructor(private msg: NzMessageService) {}
    36. beforeUpload = (file: NzUploadFile, _fileList: NzUploadFile[]) => {
    37. return new Observable((observer: Observer<boolean>) => {
    38. const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
    39. if (!isJpgOrPng) {
    40. this.msg.error('You can only upload JPG file!');
    41. observer.complete();
    42. return;
    43. }
    44. const isLt2M = file.size! / 1024 / 1024 < 2;
    45. if (!isLt2M) {
    46. this.msg.error('Image must smaller than 2MB!');
    47. observer.complete();
    48. return;
    49. }
    50. observer.next(isJpgOrPng && isLt2M);
    51. observer.complete();
    52. });
    53. };
    54. private getBase64(img: File, callback: (img: string) => void): void {
    55. const reader = new FileReader();
    56. reader.addEventListener('load', () => callback(reader.result!.toString()));
    57. reader.readAsDataURL(img);
    58. }
    59. handleChange(info: { file: NzUploadFile }): void {
    60. switch (info.file.status) {
    61. case 'uploading':
    62. this.loading = true;
    63. break;
    64. case 'done':
    65. // Get this url from response in real world.
    66. this.getBase64(info.file!.originFileObj!, (img: string) => {
    67. this.loading = false;
    68. this.avatarUrl = img;
    69. });
    70. break;
    71. case 'error':
    72. this.msg.error('Network error');
    73. this.loading = false;
    74. break;
    75. }
    76. }
    77. }

    照片墙

    用户可以上传图片并在列表中显示缩略图。当上传照片数到达限制后,上传按钮消失。

    1. import { Component } from '@angular/core';
    2. import { NzUploadFile } from 'ng-zorro-antd/upload';
    3. function getBase64(file: File): Promise<string | ArrayBuffer | null> {
    4. return new Promise((resolve, reject) => {
    5. const reader = new FileReader();
    6. reader.readAsDataURL(file);
    7. reader.onload = () => resolve(reader.result);
    8. reader.onerror = error => reject(error);
    9. });
    10. }
    11. @Component({
    12. selector: 'nz-demo-upload-picture-card',
    13. template: `
    14. <div class="clearfix">
    15. <nz-upload
    16. nzAction="https://www.mocky.io/v2/5cc8019d300000980a055e76"
    17. nzListType="picture-card"
    18. [(nzFileList)]="fileList"
    19. [nzShowButton]="fileList.length < 8"
    20. [nzPreview]="handlePreview"
    21. >
    22. <i nz-icon nzType="plus"></i>
    23. <div class="ant-upload-text">Upload</div>
    24. </nz-upload>
    25. <nz-modal [nzVisible]="previewVisible" [nzContent]="modalContent" [nzFooter]="null" (nzOnCancel)="previewVisible = false">
    26. <ng-template #modalContent>
    27. <img [src]="previewImage" [ngStyle]="{ width: '100%' }" />
    28. </ng-template>
    29. </nz-modal>
    30. </div>
    31. `,
    32. styles: [
    33. `
    34. i[nz-icon] {
    35. font-size: 32px;
    36. color: #999;
    37. }
    38. .ant-upload-text {
    39. margin-top: 8px;
    40. color: #666;
    41. }
    42. `
    43. ]
    44. })
    45. export class NzDemoUploadPictureCardComponent {
    46. fileList: NzUploadFile[] = [
    47. {
    48. uid: '-1',
    49. name: 'image.png',
    50. status: 'done',
    51. url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
    52. },
    53. {
    54. uid: '-2',
    55. name: 'image.png',
    56. status: 'done',
    57. url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
    58. },
    59. {
    60. uid: '-3',
    61. name: 'image.png',
    62. status: 'done',
    63. url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
    64. },
    65. {
    66. uid: '-4',
    67. name: 'image.png',
    68. status: 'done',
    69. },
    70. {
    71. uid: '-5',
    72. name: 'image.png',
    73. status: 'error'
    74. }
    75. ];
    76. previewImage: string | undefined = '';
    77. previewVisible = false;
    78. handlePreview = async (file: NzUploadFile) => {
    79. if (!file.url && !file.preview) {
    80. file.preview = await getBase64(file.originFileObj!);
    81. }
    82. this.previewImage = file.url || file.preview;
    83. this.previewVisible = true;
    84. };
    85. }

    Upload上传 - 图11

    拖拽上传

    把文件拖入指定区域,完成上传,同样支持点击上传。

    1. import { Component } from '@angular/core';
    2. import { NzMessageService } from 'ng-zorro-antd/message';
    3. import { NzUploadChangeParam } from 'ng-zorro-antd/upload';
    4. @Component({
    5. selector: 'nz-demo-upload-drag',
    6. template: `
    7. <nz-upload
    8. nzType="drag"
    9. [nzMultiple]="true"
    10. nzAction="https://www.mocky.io/v2/5cc8019d300000980a055e76"
    11. (nzChange)="handleChange($event)"
    12. >
    13. <p class="ant-upload-drag-icon">
    14. <i nz-icon nzType="inbox"></i>
    15. </p>
    16. <p class="ant-upload-text">Click or drag file to this area to upload</p>
    17. <p class="ant-upload-hint">
    18. Support for a single or bulk upload. Strictly prohibit from uploading company data or other band files
    19. </p>
    20. </nz-upload>
    21. `
    22. })
    23. export class NzDemoUploadDragComponent {
    24. constructor(private msg: NzMessageService) {}
    25. handleChange({ file, fileList }: NzUploadChangeParam): void {
    26. const status = file.status;
    27. if (status !== 'uploading') {
    28. console.log(file, fileList);
    29. }
    30. if (status === 'done') {
    31. this.msg.success(`${file.name} file uploaded successfully.`);
    32. } else if (status === 'error') {
    33. this.msg.error(`${file.name} file upload failed.`);
    34. }
    35. }
    36. }

    手动上传

    nzBeforeUpload 返回 false 后,手动上传文件。

    Upload上传 - 图13

    自定义预览

    自定义本地预览,用于处理非图片格式文件(例如视频文件)。

    1. import { HttpClient } from '@angular/common/http';
    2. import { Component } from '@angular/core';
    3. import { NzUploadFile } from 'ng-zorro-antd/upload';
    4. import { map } from 'rxjs/operators';
    5. @Component({
    6. template: `
    7. <div class="clearfix">
    8. <nz-upload nzAction="https://www.mocky.io/v2/5cc8019d300000980a055e76" nzListType="picture" [nzPreviewFile]="previewFile">
    9. <button nz-button><i nz-icon nzType="upload"></i> Upload</button>
    10. </nz-upload>
    11. </div>
    12. `
    13. })
    14. export class NzDemoUploadPreviewFileComponent {
    15. constructor(private http: HttpClient) {}
    16. previewFile = (file: NzUploadFile) => {
    17. console.log('Your upload file:', file);
    18. return this.http
    19. .post<{ thumbnail: string }>(`https://next.json-generator.com/api/json/get/4ytyBoLK8`, {
    20. method: 'POST',
    21. body: file
    22. })
    23. .pipe(map(res => res.thumbnail));
    24. };
    25. }

    阿里云 OSS

    使用阿里云 OSS 上传示例.

    1. import { Component } from '@angular/core';
    2. import { NzUploadChangeParam, NzUploadFile } from 'ng-zorro-antd/upload';
    3. @Component({
    4. selector: 'nz-demo-upload-upload-with-aliyun-oss',
    5. template: `
    6. <nz-upload
    7. nzName="file"
    8. [(nzFileList)]="files"
    9. [nzTransformFile]="transformFile"
    10. [nzData]="getExtraData"
    11. [nzAction]="mockOSSData.host"
    12. (nzChange)="onChange($event)"
    13. >
    14. Photos: <button nz-button><i nz-icon nzType="upload"></i> Click to Upload</button>
    15. </nz-upload>
    16. `
    17. })
    18. export class NzDemoUploadUploadWithAliyunOssComponent {
    19. files: NzUploadFile[] = [];
    20. mockOSSData = {
    21. dir: 'user-dir/',
    22. expire: '1577811661',
    23. host: '//www.mocky.io/v2/5cc8019d300000980a055e76',
    24. accessId: 'c2hhb2RhaG9uZw==',
    25. policy: 'eGl4aWhhaGFrdWt1ZGFkYQ==',
    26. signature: 'ZGFob25nc2hhbw=='
    27. };
    28. transformFile = (file: NzUploadFile) => {
    29. const suffix = file.name.slice(file.name.lastIndexOf('.'));
    30. const filename = Date.now() + suffix;
    31. file.url = this.mockOSSData.dir + filename;
    32. return file;
    33. };
    34. getExtraData = (file: NzUploadFile) => {
    35. const { accessId, policy, signature } = this.mockOSSData;
    36. return {
    37. key: file.url,
    38. OSSAccessKeyId: accessId,
    39. policy: policy,
    40. Signature: signature
    41. };
    42. };
    43. onChange(e: NzUploadChangeParam): void {
    44. console.log('Aliyun OSS:', e.fileList);
    45. }
    46. }

    nzChange

    文件状态改变的回调,返回为:

    1. {
    2. file: { /* ... */ },
    3. fileList: [ /* ... */ ],
    4. event: { /* ... */ },
    5. }
    1. file 当前操作的文件对象。

      1. {
      2. uid: 'uid', // 文件唯一标识
      3. name: 'xx.png' // 文件名
      4. status: 'done', // 状态有:uploading done error removed
      5. response: '{"status": "success"}', // 服务端响应内容
      6. linkProps: '{"download": "image"}', // 下载链接额外的 HTML 属性
      7. }
    2. fileList 当前的文件列表。

    3. event 上传中的服务端响应内容,包含了上传进度等信息,高级浏览器支持。

    nzCustomRequest

    nzCustomRequest 回调传递以下参数:

    • onProgress: (event: { percent: number }): void
    • onError: (event: Error): void
    • onSuccess: (body: Object, xhr?: Object): void
    • data: Object
    • filename: String
    • file: File
    • withCredentials: Boolean
    • headers: Object