SAPUI5中如何基于JSZip在浏览器端打包选中的待下载附件为ZIP文件
SAPUI5 批量打包选中附件为ZIP的实现问题
我找到已亲自测试验证可行的实现方案,可通过JSZip将自定义内容打包为ZIP,参考示例代码如下:
onPress: function(oControlEvent) { var zip = new JSZip(); zip.file("Hello.txt", "Hello World\n"); // 在此处定义需要打包的文件内容 zip.generateAsync({ type: "blob" }) .then(function(content) { saveAs(content, "example.zip"); }); },
目前我编写了如下函数,可直接遍历上传集合组件的选中项,逐个打开新窗口触发附件下载:
downloadAttachments:function(){ this.byId("UploadCollection").getSelectedItems().map(object => window.open(object.mProperties.url)); },
我需要调整代码逻辑,让最终生成的ZIP包含所有选中的待下载附件,而非示例中手动创建的Hello.txt文件。
调整方案
核心改动点:原示例中是直接把字符串写入zip,要打包远程附件,必须先通过请求拿到每个附件的二进制流,再写入zip实例,等所有附件都写入完成后再触发打包下载。
实现步骤
- 遍历UploadCollection的选中项,校验是否有选中的附件
- 初始化JSZip实例
- 对每个选中附件,通过fetch请求获取对应的Blob格式内容
- 将获取到的附件内容,以原始文件名写入JSZip实例
- 等待所有附件内容获取完成后,生成ZIP文件并触发浏览器下载
完整修改后代码
// 确保项目已引入JSZip、FileSaver(saveAs方法)依赖 downloadAttachments: async function() { const selectedItems = this.byId("UploadCollection").getSelectedItems(); // 空选中判断 if (!selectedItems.length) { MessageToast.show("请先选择需要打包下载的附件"); return; } const zip = new JSZip(); // 并发获取所有附件内容 const attachmentFetchTasks = selectedItems.map(async(item) => { const fileUrl = item.mProperties.url; // 优先取UploadCollection自带的文件名,避免从url拆分不准 const fileName = item.mProperties.fileName || decodeURIComponent(fileUrl.split('/').pop().split('?')[0]); // 跨域、带鉴权请求时可补充配置:{ credentials: "include" } const fileResponse = await fetch(fileUrl); if (!fileResponse.ok) throw new Error(`附件${fileName}获取失败`); const fileBlob = await fileResponse.blob(); // 重名文件自动加后缀,避免覆盖 const finalFileName = zip.files[fileName] ? `${fileName.split('.')[0]}_${Date.now()}.${fileName.split('.').pop()}` : fileName; zip.file(finalFileName, fileBlob); }); try { // 等待所有附件获取完成 await Promise.all(attachmentFetchTasks); // 生成ZIP并下载 const zipFile = await zip.generateAsync({ type: "blob" }); saveAs(zipFile, `批量附件打包_${new Date().toLocaleDateString()}.zip`); } catch (error) { MessageBox.error(`打包下载失败:${error.message}`); } }
常见问题注意点
- 不要直接把附件url传给JSZip:JSZip无法远程拉取文件,必须拿到实际的文件二进制流才能打包
- 跨域问题:如果附件存储服务和当前SAPUI5应用不同源,需要在存储服务端配置CORS规则,允许应用跨域读取文件
- 鉴权问题:如果附件下载需要携带登录态,需要在fetch请求中加上
credentials: "include"配置,避免拿到401未授权响应 - 大文件提示:如果可能存在大附件,建议在获取文件的过程中添加BusyIndicator加载提示,避免用户无感知重复点击
内容的提问来源于stack exchange,提问作者Fotios Tragopoulos
相关产品推荐
相关产品推荐

