3.5.2.1.16. 多文件上传控件

API 文档

FileMultiUploadField 组件允许用户把文件上传到服务器。这个组件是个按钮;用户点击时,系统自带的文件选择器会弹出,此时用户可以选择多个文件来上传。

gui multipleUpload

该组件对应的 XML 名称: multiUpload

下面是一个使用 FileMultiUploadField 的示例。

  • 在界面的 XML 描述中声明这个组件:
  1. <multiUpload id="multiUploadField" caption="Upload Many"/>
  1. @Inject
  2. private FileMultiUploadField multiUploadField;
  3. @Inject
  4. private FileUploadingAPI fileUploadingAPI;
  5. @Inject
  6. private Notifications notifications;
  7. @Inject
  8. private DataManager dataManager;
  9. @Subscribe
  10. protected void onInit(InitEvent event) { (1)
  11. multiUploadField.addQueueUploadCompleteListener(queueUploadCompleteEvent -> { (2)
  12. for (Map.Entry<UUID, String> entry : multiUploadField.getUploadsMap().entrySet()) { (3)
  13. UUID fileId = entry.getKey();
  14. String fileName = entry.getValue();
  15. FileDescriptor fd = fileUploadingAPI.getFileDescriptor(fileId, fileName); (4)
  16. try {
  17. fileUploadingAPI.putFileIntoStorage(fileId, fd); (5)
  18. } catch (FileStorageException e) {
  19. throw new RuntimeException("Error saving file to FileStorage", e);
  20. }
  21. dataManager.commit(fd); (6)
  22. }
  23. notifications.create()
  24. .withCaption("Uploaded files: " + multiUploadField.getUploadsMap().values())
  25. .show();
  26. multiUploadField.clearUploads(); (7)
  27. });
  28. multiUploadField.addFileUploadErrorListener(queueFileUploadErrorEvent -> {
  29. notifications.create()
  30. .withCaption("File upload error")
  31. .show();
  32. });
  33. }

1onInit() 方法里面,添加了事件监听器,这样可以在文件上传成功或者出错时做出反馈。2该组件将所有选择的文件上传到客户端层(client tier) 的临时存储(temporary storage)并且调用通过 addQueueUploadCompleteListener() 方法添加的监听器。3在这个监听器里面,会调用 FileMultiUploadField.getUploadsMap() 方法获得临时存储的文件标识和文件名映射关系的 map。4然后,通过调用 FileUploadingAPI.getFileDescriptor() 为每一条 map 记录创建相应的 FileDescriptor 对象。 com.haulmont.cuba.core.entity.FileDescriptor (别跟 java.io.FileDescriptor 混淆了) 是一个持久化实体,唯一定义一个上传的文件,并且也用这个类从系统下载文件。5FileUploadingAPI.putFileIntoStorage() 方法用来把文件从客户端层的临时存储移动到 FileStorage。这个方法的参数是临时存储中文件的标识符和对应的 FileDescriptor 对象。6在将文件上传到 FileStorage 之后,通过调用 DataManager.commit() 方法将 FileDescriptor 实例存到数据库。这个方法的返回值可以用来设置给一个实体的属性,这个属性关联此文件。这里,FileDescriptor 简单的保存在数据库。上传的文件可以通过 Administration > External Files 界面查看。7完成整个上传过程之后,文件列表需要通过调用 clearUploads() 方法清空以便下一次上传再使用。

下面列出能跟踪上传进度的监听器:

  • FileUploadErrorListener
  • FileUploadStartListener
  • FileUploadFinishListener
  • QueueUploadCompleteListener

最大可上传的文件大小是由 cuba.maxUploadSizeMb 应用程序属性定义的,默认是 20MB。如果用户选择了更大的文件的话,会有相应的提示信息,并且中断上传过程。

multiUpload 属性:

  • accept XML 属性 (或者相应的 setAccept() 方法) 用来设置文件选择对话框里面的文件类型掩码,但是用户还是可以选择“所有文件”来上传任意文件。

这个属性的值需要是以英文逗号分隔的文件后缀名,比如:.jpg,.png

  • fileSizeLimit XML 属性 (或者相应的 setFileSizeLimit() 方法) 用来设置最大允许上传的文件大小。这个设置是针对每一个文件都有效的。
  1. <multiUpload id="multiUploadField" fileSizeLimit="200000"/>
  • permittedExtensions XML 属性 (或者相应的 setPermittedExtensions() 方法) 设置允许的文件扩展名白名单。

这个属性的值需要是字符串的集合,其中每个字符串是以 . 开头的允许的文件扩展名,比如:

  1. uploadField.setPermittedExtensions(Sets.newHashSet(".png", ".jpg"));
  • dropZone XML 属性允许设置一个特殊的 BoxLayout 用来作为从浏览器外部拖拽文件可以放置的目标容器区域。如果这个容器的样式没有特殊设置,当文件被拖拽到这块区域的时候,这个容器会被高亮显示,否则目标区域不会显示。

参考 加载和显示图片 有更多复杂的使用上传文件的例子。


multiUpload 的属性

accept - align - caption - captionAsHtml - css - description - descriptionAsHtml - dropZone - enable - fileSizeLimit - height - box.expandRatio - icon - id - pasteZone - permittedExtensions - stylename - tabIndex - visible - width
multiUpload 监听器

FileUploadErrorListener - FileUploadFinishListener - FileUploadStartListener - QueueUploadCompleteListener