java把多个url压缩成zip, 前端接收返回的字符串并下载
说明: 后端把多个url转成字节数组,并合成zip供前端下载。
1. 把url的转成字节数据
public static byte[] getFileUrlByte(String fileUrl) throws BusException {
try {
URL url = new URL(fileUrl);
HttpURLConnection urlCon = (HttpURLConnection) url.openConnection();
urlCon.setConnectTimeout(6000);
urlCon.setReadTimeout(6000);
int code = urlCon.getResponseCode();
if (code != HttpURLConnection.HTTP_OK) {
throw new BusException("文件读取失败");
}
InputStream is = url.openStream();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[BYTE_LENGTH];
int length = 0;
while ((length = is.read(bytes)) != -1) {
outputStream.write(bytes, 0, length);
}
outputStream.close();
is.close();
return outputStream.toByteArray();
} catch (IOException e) {
log.error("文件下载异常: {}", ExceptionUtil.stacktraceToString(e));
throw new BusException(String.format("文件下载失败, %s", e.getMessage()));
}
}
2.把多个文件流合成zip输出流
public static byte[] regularZipByte(List<FileInfo> fromFiles) throws BusException {
byte[] arr = new byte[0];
try {
Random random = new Random();
@Cleanup
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
@Cleanup
ZipOutputStream zipOut = new ZipOutputStream(outputStream);
// 如果有重复的名称, 则重命名
Set<String> fileNameSet = Sets.newHashSet();
for (FileInfo fileUrl : fromFiles) {
String fileUrlTemp = fileUrl.getFileUrl();
int index = fileUrlTemp.lastIndexOf(ProjectConstant.SLASH);
String urlPrefix = fileUrl.getFileUrl().substring(0, index + 1);
String originalFileName = fileUrl.getFileUrl().substring(index + 1);
String entryName = originalFileName;
if (fileNameSet.contains(entryName)) {
if (entryName.contains(ProjectConstant.POINT)) {
String[] split = entryName.split(ProjectConstant.POINT_ESCAPE);
entryName = split[0] + random.nextInt(9999) + ProjectConstant.POINT + split[1];
} else {
entryName += random.nextInt(9999);
}
}
byte[] fileUrlByte = getFileUrlByte(urlPrefix + URLEncoder.encode(originalFileName, "UTF-8"));
fileNameSet.add(entryName);
zipOut.putNextEntry(new ZipEntry(entryName));
zipOut.write(fileUrlByte);
}
zipOut.finish();
outputStream.flush();
arr = outputStream.toByteArray();
} catch (Exception e) {
e.printStackTrace();
throw new BusException("下载异常");
}
return arr;
}
3. 前端接受接口返回的字节数组, 并解析下载
testBtn4 () {
axios({
method: 'get',
url: 'http://localhost:端口/地址'
}).then((data) => {
var raw = window.atob(data.data)
var uInt8Array = new Uint8Array(raw.length)
for (var i = 0; i < raw.length; i++) {
uInt8Array[i] = raw.charCodeAt(i)
}
const blob = new Blob([uInt8Array], {
type: 'application/octet-stream'
})
const link = document.createElement('a')
link.style.display = 'none'
link.href = URL.createObjectURL(blob)
link.download = '导出文件' + Date.parse(new Date()) + '.zip'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
})
},
备注:
后端返回的格式