一、背景 本地浏览器导出功能因数据量大,出现浏览器卡顿、崩溃的情况下,我们可以通过优化代码、sql来缓解,当出现非代码优化所能处理卡顿的情况时,就需要换种思路处理导出功能了,那就是 实现异步导出(浏览器点击导出时,执行异步方法,边写入处理任务、边执行导出功能,这时很慢的导出在后台运行,前台客户无感知,等异步下载完成后,更薪任务状态,通知客户下载完毕,可以下载了。这条任务需要存入数据表里)。实现思路就是:后端生成文件后上传至阿里云OSS空间,上传完成后,更新任务状态,通知客户去下载文件,此时下载的文件是从阿里云OSS上下载的。
Java处理文件上传OSS 可参考官方文档: 阿里云OSS官方手册 里面有示例工程,可下载。
Java生成Excel文件可参考:Java处理数据导出功能
二、实现思路 需要配置 阿里云oss的 endpoint、key、secret、bucket、folder文件夹 思路:将后端生成的文件 存至本地目录下的临时文件夹中(./localFolder),然后执行上传方法,上传成功后,删除本地临时文件夹中的文件,返回OSS中的文件下载地址即可。
/**
* 上传文件
* @param fileName 文件名
* @param workbook 生成的Excel流
* @return 上传文件地址
* @throws IOException
*/
public String getFileUrl(String fileName, Workbook workbook) throws IOException {
// 将文件写入本地文件夹
String filePath = "."+ File.separator + orderFolder;
File dir = new File(filePath);
if (!dir.exists()) {
dir.mkdir();
log.info("orderFolder 文件夹创建完毕!");
}
String filePathName = filePath + File.separator + fileName;
FileOutputStream output = new FileOutputStream(filePathName);
workbook.write(output);//写入磁盘
output.close();
log.info("文件已存入!");
// 如果文件写入成功,则上传至 OSS
File file = new File(filePathName);
String fileUrl = "";
if (file.exists()) {
fileUrl = ossUtil.UploadFile(file, fileName);
}
// 上传成功后,删除本地文件
if (AirUtils.hv(fileUrl)) {
file.delete();
}
System.out.println("下载地址:" + fileUrl);
return fileUrl;
}
/**
* 上传文件
* @param fileName 文件名
* @param bytes 生成的Excel字节
* @return 上传文件地址
* @throws IOException
*/
public String getFileUrl(String fileName, byte[] bytes) throws IOException {
// 将文件写入本地文件夹
String filePath = "."+ File.separator + orderFolder;
File dir = new File(filePath);
if (!dir.exists()) {
dir.mkdir();
log.info("orderFolder 文件夹创建完毕!");
}
String filePathName = filePath + File.separator + fileName;
FileOutputStream output = new FileOutputStream(filePathName);
output.write(bytes);//写入磁盘
output.close();
log.info("文件已存入!");
// 如果文件写入成功,则上传至 OSS
File file = new File(filePathName);
String fileUrl = "";
if (file.exists()) {
fileUrl = ossUtil.UploadFile(file, fileName);
}
// 上传成功后,删除本地文件
if (AirUtils.hv(fileUrl)) {
file.delete();
}
System.out.println("下载地址:" + fileUrl);
return fileUrl;
}
/**
* 上传Excel文件
* @param file
* @return
*/
public String UploadFile(File file, String localFileName) {
try {
// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "http://"+ossProperies.getDomain();
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
String accessKeyId = ossProperies.getKey();
String accessKeySecret = ossProperies.getSecret();
// 创建OSSClient实例。
OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
// 上传文件
String fileName = ossProperies.getFolderOrder() + "/" + localFileName;
ossClient.putObject(ossProperies.getBucket(), fileName, file);
// 关闭OSSClient。
ossClient.shutdown();
return "http://"+ossProperies.getBucket()+"."+ossProperies.getDomain()+"/"+fileName;
}catch (Exception e){
logger.error("oss上传失败",e);
return null;
}
}