您现在的位置是:首页 >技术交流 >360极速版无法下载压缩包附件的问题网站首页技术交流
360极速版无法下载压缩包附件的问题
简介360极速版无法下载压缩包附件的问题
Java代码
/**
* 根据合同ID批量下载合同附件
*/
@RequestMapping(value={"/downloadAttachmentByConIds.do"}, method = RequestMethod.POST)
public void downloadAttachmentByConIds(@RequestParam("urls") String urls, HttpServletResponse response) throws IOException {
String contractIds = java.net.URLDecoder.decode(urls,"UTF-8");
String[] conIds = contractIds.split(",");
if(conIds.length== 0) {
try {
response.setCharacterEncoding("UTF-8");
response.getWriter().write("文件不存在");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// 根据合同ID获取文件实体类
List<AttachmentEntry> attachmentEntryList = attachService.getAttachmentList(conIds);
// 通过合同ID获取合同实体列表
List<ContractEntry> contractEntryList = contractService.getContractListByIds(Arrays.asList(conIds));
// 键存放合同ID、值存放合同实体
Map<String,ContractEntry> conMap = new HashMap<>();
for(int k=0;k<contractEntryList.size();k++){
conMap.put(contractEntryList.get(k).getPk(),contractEntryList.get(k));
}
// 服务端创建一个大的文件夹D:IDEAworkspaceJMIS-DHsrcmainwebapp/upload emp
String parentDirPathStr = WebAppUtil.getRealPath(File.separator + "upload" + File.separator + "temp" + File.separator);
Path parentDirPathObj = Paths.get(parentDirPathStr);
Files.createDirectories(parentDirPathObj);
// 文件实体列表按照合同ID进行分组,并放入Map,键为合同ID,值为文件实体
Map<String, List<AttachmentEntry>> stringAttachmentEntryMap = groupByAttribute(attachmentEntryList, "busiId", AttachmentEntry.class);
// 遍历文件实体列表
for(Map.Entry<String,List<AttachmentEntry>> entry : stringAttachmentEntryMap.entrySet()){
// 该合同编号下的所有附件
List<AttachmentEntry> singleAttachmentEntries = entry.getValue();
// 该合同编号关联的合同实体
ContractEntry contractEntry = conMap.get(entry.getKey());
String conName = contractEntry.getName().trim();
String conNo = contractEntry.getNo().trim();
// 拼接小文件夹名称:合同编号+合同名称
String childDirPathStr = conNo + "-" + conName;
// 服务端创建一个小文件夹 D:IDEAworkspaceJMIS-DHsrcmainwebapp/upload emp合同编号-合同名称
Path childDirPathObj = parentDirPathObj.resolve(childDirPathStr);
Files.createDirectories(childDirPathObj);
// 将文件保存到对应的小文件夹
for(AttachmentEntry file : singleAttachmentEntries){
File documentFile = attachService.getDocumentFile(file);
// 源路径 D:IDEAworkspaceJMIS-DHsrcmainwebapp/uploadcontract19347598962.doc
Path filePath = childDirPathObj.resolve(documentFile.getPath());
// 目标路径 D:IDEAworkspaceJMIS-DHsrcmainwebapp/upload emp合同编号-合同名称文件名称.doc
Path resolve = childDirPathObj.resolve(file.getName());
// 源路径文件复制到目标路径
Files.copy(filePath, resolve);
}
}
// 3. 压缩大文件夹为 ZIP
String zipName = "合同附件.zip";
response.setContentType("application/zip");
response.setHeader("Content-disposition", "attachment;filename=" + new String(zipName.getBytes("GBK"), "ISO-8859-1"));
try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
zipFolder(parentDirPathObj.toFile(), parentDirPathObj.getFileName().toString(), zipOut);
}
// 4. 删除临时文件夹
deleteFolder(parentDirPathObj.toFile());
}
/**
* 根据对象的指定属性进行分组。
*
* @param list 要分组的对象列表
* @param attributeName 用于分组的属性名(假设对象有getter方法,如getXXX)
* @param clazz 对象的类类型
* @param <T> 对象的类型
* @return 分组后的Map,键是属性值,值是具有该属性值的对象列表
*/
public static <T> Map<String, List<T>> groupByAttribute(List<T> list, String attributeName, Class<T> clazz) {
Map<String, List<T>> groupedMap = new HashMap<>();
try {
// 通过反射获取getter方法,假设getter方法名为get+属性名首字母大写+剩余部分
Method getter = clazz.getMethod("get" + Character.toUpperCase(attributeName.charAt(0)) + attributeName.substring(1));
for (T obj : list) {
String attributeValue = (String) getter.invoke(obj); // 调用getter方法获取属性值
List<T> listForAttribute = groupedMap.get(attributeValue);
if (listForAttribute == null) {
listForAttribute = new ArrayList<>();
groupedMap.put(attributeValue, listForAttribute);
}
listForAttribute.add(obj);
}
} catch (NoSuchMethodException | IllegalAccessException | java.lang.reflect.InvocationTargetException e) {
e.printStackTrace();
// 处理反射异常
}
return groupedMap;
}
/**
* 递归压缩文件夹(保留目录结构)
*/
private void zipFolder(File folder, String parentPath, ZipOutputStream zipOut) throws IOException {
for (File file : folder.listFiles()) {
String entryName = parentPath + "/" + file.getName();
if (file.isDirectory()) {
zipFolder(file, entryName, zipOut); // 递归处理子文件夹
} else {
ZipEntry zipEntry = new ZipEntry(entryName);
zipOut.putNextEntry(zipEntry);
Files.copy(file.toPath(), zipOut);
zipOut.closeEntry();
}
}
}
/**
* 递归删除文件夹
*/
private void deleteFolder(File folder) {
if (folder.isDirectory()) {
for (File file : folder.listFiles()) {
deleteFolder(file);
}
}
folder.delete();
}
Ext.js代码
PlanContractList.AttachmentDownload = function(cGridList) {
var selectionModel = cGridList.getSelectionModel();
let downIds = [];
if (selectionModel.hasSelection()) {
var selections = selectionModel.getSelections();
for(let k = 0;k<selections.length;k++){
downIds[k] = selections[k].data.pk
}
var winHeight = window.document.documentElement.clientHeight-10;
//doDownload('/contract/downloadAttachmentByConIds.do?contractIds=' + downIds.join(","));
var formStr = '<form style="visibility:hidden;" method="POST" action="' + __ctxPath + '/contract/downloadAttachmentByConIds.do' + '">' +
'<input type="hidden" name="urls" value="' + encodeURIComponent(downIds.join(",")) + '" />' +
'</form>';
var win = window.open("", "_blank", "height=" + winHeight
+ ",top=80,left=80,toolbar=no, menubar=no, scrollbars=yes, resizable=yes");
win.document.body.innerHTML = formStr;
win.document.forms[0].submit();
} else {
Ext.Msg.alert("提示信息:", "至少选中一条记录");
}
};
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。




QT多线程的5种用法,通过使用线程解决UI主界面的耗时操作代码,防止界面卡死。...
U8W/U8W-Mini使用与常见问题解决
stm32使用HAL库配置串口中断收发数据(保姆级教程)
分享几个国内免费的ChatGPT镜像网址(亲测有效)
Allegro16.6差分等长设置及走线总结