java實現(xiàn)異步導(dǎo)出數(shù)據(jù)
問題概述:
使用java作為后臺語言,用poi導(dǎo)出數(shù)據(jù)時無法異步導(dǎo)出,當數(shù)據(jù)量稍微大點,就會出現(xiàn)頁面傻瓜式等待 (點擊導(dǎo)出后,頁面無任何反應(yīng)和提示,還以為此功能無效。然則幾秒后瀏覽器才響應(yīng)。)這樣體驗非常 不好。
解決辦法:
很簡單,將下載數(shù)據(jù)分離為一個單獨方法。在觸發(fā)導(dǎo)出后,先獲取并封裝數(shù)據(jù)(數(shù)據(jù)量大的話這個過程正好給頁面做一個等待框,提示正在下載數(shù)據(jù)),完成后給前臺返回一個狀態(tài),當前臺收到返回正確返回狀態(tài)后再關(guān)閉等待框并調(diào)用下載方法。
demo:
1、獲取并封裝數(shù)據(jù)
@RequestMapping("exportExcel") //用戶數(shù)據(jù)導(dǎo)出
public void exportExcel(HttpServletRequest request, HttpServletResponse response) {
Map<String,Object> map = new HashMap<String,Object>();
try{
EquipmentAccident search=(EquipmentAccident)
request.getSession().getAttribute("equipmentAccident1"); //獲取保存在session中的查詢條件
if(search !=null ){
if(Str.isNotNull(search.getName())){ //名稱
map.put("name", search.getName());
}
if(Str.isNotNull(search.getRemark())){ //備注
map.put("remark", search.getRemark());
}
}
List<User> list=userService.selectExcel(map); //查詢數(shù)據(jù)
XSSFWorkbook wb = new XSSFWorkbook(); // 聲明一個工作薄
XSSFSheet sheet = wb.createSheet("用戶信息"); // 生成一個表格
Integer columnIndex = 0;
sheet.setColumnWidth(columnIndex++, 3 * 512); // 設(shè)置表格第一列寬度為3個字節(jié)
sheet.setColumnWidth(columnIndex++, 10 * 512); //名稱
sheet.setColumnWidth(columnIndex++, 10 * 512); //年齡
sheet.setColumnWidth(columnIndex++, 10 * 512); //備注
// 生成一個樣式
XSSFCellStyle style1 = wb.createCellStyle();
// 設(shè)置這些樣式
style1.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
// 生成一個字體
XSSFFont font1 = wb.createFont();
font1.setFontHeightInPoints((short) 11);
font1.setFontName("黑體"); // 字體
// 把字體應(yīng)用到當前的樣式
style1.setFont(font1);
//在sheet里增加合并單元格
CellRangeAddress cra = new CellRangeAddress(0, 0, 0, 7);
sheet.addMergedRegion(cra);
int rowInt = 0; //列號
XSSFRow row = sheet.createRow(rowInt++);
XSSFCell cell = row.createCell(0);
cell.setCellStyle(style1);
cell.setCellValue("用戶信息");
int cellInt = 0;
row = sheet.createRow(rowInt++);
cell = row.createCell(cellInt++);
cell.setCellStyle(style1);
cell.setCellValue("序號");
cell = row.createCell(cellInt++);
cell.setCellStyle(style1);
cell.setCellValue("名稱");
cell = row.createCell(cellInt++);
cell.setCellStyle(style1);
cell.setCellValue("年齡");
cell = row.createCell(cellInt++);
cell.setCellStyle(style1);
cell.setCellValue("備注");
int index = 0;
if(list!=null && !list.isEmpty()){
for(User obj:list){
index++;
cellInt = 0;
row = sheet.createRow(rowInt++);
cell = row.createCell(cellInt++);
cell.setCellValue(index);
cell = row.createCell(cellInt++);
cell.setCellValue(obj.getName());
cell = row.createCell(cellInt++);
cell.setCellValue(obj.getAge());
cell = row.createCell(cellInt++);
cell.setCellValue(obj.getRemark());
}
}
//反饋給前臺狀態(tài)
response.getWriter().append("ok");
//XSSFWorkbook對象保持到session里,供下載使用
request.getSession().setAttribute("XSSFWorkbook",wb);
} catch (Exception e) {
e.printStackTrace();
}
}
2、分離出來的下載方法
/**
* @param fileName 下載文件名稱
* @param request 請求對象
* @param response 響應(yīng)對象
* 2020-11-10 新增
*/
@RequestMapping("downloadExcel")
public void downloadExcel(String fileName,HttpServletRequest request,HttpServletResponse response) {
if(Str.isNotNull(fileName)){
User loginUser = (User) request.getSession().getAttribute("loginUser");
//檢驗下載路徑并返回url
String url = FileTool.getdownLoadUrl(loginUser, fileName, request);
//從url里截取出文件全名
fileName = url.substring(url.lastIndexOf("/")+1);
//創(chuàng)建文件輸出流
FileOutputStream fileOut = null;
try {
fileOut = new FileOutputStream(url);
//獲取保存在session中的待下載數(shù)據(jù)
XSSFWorkbook wb = (XSSFWorkbook) request.getSession().getAttribute("XSSFWorkbook");
wb.write(fileOut);
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
finally{
if(fileOut != null){
try {
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
System.out.println("------------開始下載文件---------------");
File file = new File(url);
// 以流的形式下載文件。
InputStream fis = new BufferedInputStream(new FileInputStream(url));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
// 設(shè)置response的Header
response.addHeader("Content-Disposition", "attachment;filename=" + new
String(fileName.getBytes("UTF-8"),
"ISO8859-1"));
response.addHeader("Content-Length", "" + file.length());
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
toClient.write(buffer);
toClient.flush();
toClient.close();
//清除session里的數(shù)據(jù)
request.getSession().removeAttribute("XSSFWorkbook");
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
3、前臺調(diào)用導(dǎo)出數(shù)據(jù)
//導(dǎo)出請求
function exportExcel(){
var load = saveLoad("導(dǎo)出中,請稍后...",1); //打開一個等待框
$.ajax({
type: "post",
url: "exportExcel",
dataType:"text",
error: function(request) {
closeSaveLoad(load,1);
return false;
},
success: function(msg) {
if(msg=='ok'){
closeSaveLoad(load,1); //關(guān)閉等待框
//下載請求地址
window.location.href="downloadExcel?fileName=用戶信息" rel="external nofollow" ;
}else{
closeSaveLoad(load,1); //關(guān)閉等待框
layer.msg("導(dǎo)出失敗,刷新頁面重試",{icon:2});
return false;
}
}
});
}
效果如下:

總結(jié):
以前是將封裝數(shù)據(jù)和下載數(shù)據(jù)放一個方法里面,導(dǎo)致下載需要等待很久,而等待的時候,無法提示用戶后臺正在處理數(shù)據(jù)。將數(shù)據(jù)和下載分開后就可以達到等待時提示,加載完下載。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Java實現(xiàn)從數(shù)據(jù)庫導(dǎo)出大量數(shù)據(jù)記錄并保存到文件的方法
- Java數(shù)據(jù)導(dǎo)出功能之導(dǎo)出Excel文件實例
- Java實現(xiàn)Excel導(dǎo)入導(dǎo)出數(shù)據(jù)庫的方法示例
- java導(dǎo)出數(shù)據(jù)庫的全部表到excel
- Java使用poi組件導(dǎo)出Excel格式數(shù)據(jù)
- Java使用easyExcel導(dǎo)出excel數(shù)據(jù)案例
- java從mysql導(dǎo)出數(shù)據(jù)的具體實例
- java web將數(shù)據(jù)導(dǎo)出為pdf格式文件代碼片段
- Java樹形結(jié)構(gòu)數(shù)據(jù)生成導(dǎo)出excel文件方法記錄
- JAVA實現(xiàn)億級千萬級數(shù)據(jù)順序?qū)С龅氖纠a
相關(guān)文章
Java多線程實現(xiàn)TCP網(wǎng)絡(luò)Socket編程(C/S通信)
這篇文章主要介紹了Java多線程實現(xiàn)TCP網(wǎng)絡(luò)Socket編程(C/S通信),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
關(guān)于Spring的@Transaction導(dǎo)致數(shù)據(jù)庫回滾全部生效問題(又刪庫跑路)
使用@Transactional一鍵開啟聲明式事務(wù), 這就真的事務(wù)生效了?過于信任框架總有“意外驚喜”。本文通過案例給大家詳解關(guān)于Spring的@Transaction導(dǎo)致數(shù)據(jù)庫回滾全部生效問題,感興趣的朋友一起看看吧2021-05-05
IDEA創(chuàng)建SpringBoot的maven項目的方法步驟
這篇文章主要介紹了IDEA創(chuàng)建SpringBoot的maven項目的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
IDEA項目的依賴(pom.xml文件)導(dǎo)入問題及解決
這篇文章主要介紹了IDEA項目的依賴(pom.xml文件)導(dǎo)入問題及解決,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08

