一、背景
本地瀏覽器導出功能因數據量大,出現瀏覽器卡頓、崩潰的情況下,我們可以通過優化代碼、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;
}
}