- 前端只要将要导出的数据的ids传回后端就行了
比如
handleExportApp(row) {
const ids = row ? [row.id] : this.checkedRows.map(v => v.id);
//exportApp为后端导出接口
exportApp(ids.join(","));
},
- 后端接口
public void exportApp(String ids, HttpServletResponse response) {
if (StringUtils.isBlank(ids)) {
throw new BusinessException("参数不能为空");
}
List<String> idsList = Arrays.asList(ids.split(","));
List<App> list = appService.findAppAllListByIds(idsList);
//创建HttpServerResponse的输出流
OutputStream out = null;
try {
out = response.getOutputStream();
BufferedInputStream bis;
File file = new File("应用数据包.zip");
//通过ZipOutputStream定义要写入的对象
ZipOutputStream zos = null;
zos = new ZipOutputStream(new FileOutputStream(file));
writeZos(list, zos);
zos.close();
//定义返回类型
response.setContentType("text/html; charset=UTF-8");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode("应用数据包.zip", "UTF-8"))));
bis = new BufferedInputStream(new FileInputStream(file));
//定义byte,长度就是要转成zip文件的byte长度,避免浪费资源
byte[] buffer = new byte[bis.available()];
bis.read(buffer);
out.flush();
out.write(buffer);
file.delete();
} catch (IOException e) {
logger.error("应用数据包流写入异常{}", e.getMessage());
throw new BusinessException("系统异常");
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void writeZos(List<App> list, ZipOutputStream zos) {
list.forEach(a -> {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
byteArrayOutputStream.write(JSONUtil.toJsonStr(a).getBytes());
zos.putNextEntry(new ZipEntry(a.getName() + ".json"));
byte[] excelStream = byteArrayOutputStream.toByteArray();
zos.write(excelStream);
zos.closeEntry();
} catch (IOException e) {
logger.error("应用数据包流写入异常{}", e.getMessage());
throw new BusinessException("系统异常");
}
});
}
拓展
如果只是导出json文件,不需要压缩包的话
前端
handleExportApp(row) {
this.ids = row ? [row.id] : this.checkedRows.map(v => v.id);
this.loading = true;
this.exportData(this.ids);
},
exportData(ids) {
if (ids.length > 0) {
const currentId = ids.shift(); // 取出数组中的第一个id
simulateClick(exportApp(currentId)); // 导出单个数据
setTimeout(() => {
this.exportData(ids); // 递归调用导出函数,继续下一个数据
}, 10000); // 设置递归的间隔时间,以免处理过多数据造成性能问题
}
},
后端
if (StringUtils.isBlank(ids)) {
throw new BusinessException("参数不能为空");
}
List<String> idsList = Arrays.asList(ids.split(","));
for (String id : idsList) {
App app = appService.getById(id);
// 忽略未找到的应用程序
if (app == null) {
continue;
}
ObjectMapper objectMapper = new ObjectMapper();
try {
//把对象转成json字符串
String jsonString = objectMapper.writeValueAsString(app);
// 设置响应头部信息
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode("应用_" + app.getName() + ".json", "UTF-8"))));
// 获取输出流并写入JSON字符串
PrintWriter writer = response.getWriter();
writer.write(jsonString);
writer.flush();
writer.close();
} catch (IOException e) {
logger.error("导出应用数据异常:{}", e.getMessage());
throw new BusinessException("系统异常");
}
}
但是这样有一个不好的地方,就是前端用户体验感不是很好,需要等待前端一个个文件导出。