Java實現匯出多個excel表打包到zip檔案中->供客戶端下載
阿新 • • 發佈:2018-12-04
業務需求:將需求方要的資料匯出excel表中。
1.只發出一次請求
2.每個excel表中到資料記錄不能超過50條
碰過的坑:原先我發出的是ajax請求,然後請求成功卻返回的都是亂碼!我是想要下載檔案啊!!!
ajax請求,響應的是文字資料,所以下載檔案不能用ajax請求!用什麼呢?用連結就行了
location.href= "../../aliGoodsOrder/export?startDate="+app.startDate+"&endDate="+app.endDate;
或者一個<a href=""></a> 標籤。
後臺怎麼匯出excel呢,分享一個特別簡單的工具類給大家:
@Log4j public class Excel { public static HSSFWorkbook createExcel(String sheetName, List<String> cellNameList) { HSSFWorkbook excel = new HSSFWorkbook(); HSSFSheet sheet = excel.createSheet(sheetName); HSSFRow row = sheet.createRow(0); int cellIndex = 0; for (String cellName : cellNameList) { HSSFCell cell = row.createCell(cellIndex); cell.setCellValue(cellName); cellIndex++; } return excel; } public static HSSFWorkbook createExcelData(HSSFWorkbook excel, List<String> excelData,int rowIndex ,int columnSum){ HSSFRow row=excel.getSheetAt(0).createRow(rowIndex); for(int i = 0; i < columnSum; i++){ row.createCell(i).setCellValue(excelData.get(i)); } return excel; } }
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.16</version>
</dependency>
怎麼使用呢:
/**
* @ Date :2018/11/05
* @ Description:將1688商品訂單匯出Excel
*/
private HSSFWorkbook exportExcel(List<AliGoodsOrder> allList,String name){
log.info("|createdExcel================start!============|");
HSSFWorkbook excel = null;
try{
List<String> cellNameList = new ArrayList<>();
cellNameList.add("訂單號");
cellNameList.add("商品名稱");
cellNameList.add("商品數量(件)");
cellNameList.add("商品規格1(如:顏色)");
cellNameList.add("商品規格2(如:尺碼)");
cellNameList.add("收件人-姓名");
cellNameList.add("收件人-手機");
cellNameList.add("收件人-省");
cellNameList.add("收件人-市");
cellNameList.add("收件人-區");
cellNameList.add("收件人-詳細地址");
cellNameList.add("買家留言");
cellNameList.add("1688商品id");
String fileName = name;
String sheetName = name;
excel = Excel.createExcel(sheetName,cellNameList);
int rowIndex = 1;
for (AliGoodsOrder order:
allList ) {
List<String> excelDate = new ArrayList<>();
excelDate.add("");//訂單號設定為空
excelDate.add(order.getTitle()+"");
excelDate.add(order.getNum()+"");
excelDate.add(order.getSku1()+"");
excelDate.add(order.getSku2()+"");
excelDate.add(order.getReceiverName()+"");
excelDate.add(order.getReceiverTel()+"");
excelDate.add(order.getDeliveryProvince()+"");
excelDate.add(order.getDeliveryCity()+"");
excelDate.add(order.getDeliveryDistrict()+"");
excelDate.add(order.getDeliveryAddress()+"");
excelDate.add(order.getBuyerMessage()+"");
excelDate.add(order.getAliId()+"");
excel = Excel.createExcelData(excel,excelDate,rowIndex,13);
rowIndex++;
}
log.info("|createdExcel================end!============|");
}catch (Exception e){
log.error(ExceptionUtils.getTraceInfo(e));
}
return excel;
}
目前位置,excel的匯出完成了呢?想要客戶端下載的小寶貝們,可以把以下方法放入工具類中哦
//匯出excel檔案
public static void downLoad(HttpServletResponse response, String fileName, HSSFWorkbook wb){
try {
response.reset();
response.setContentType("application/ms-excel;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode(fileName+".xls", "UTF-8"))));
try {
wb.write(response.getOutputStream());
response.getOutputStream().flush();
} catch (Exception e) {
log.error("Excel匯出出錯", e);
throw e;
}finally{
if(response.getOutputStream()!=null){
response.getOutputStream().close();
}
}
}catch (Exception e){
log.error("downLoadExcel-------fail!");
log.error(ExceptionUtils.getTraceInfo(e));
}
}
如果你是需要客戶端請求下載一個excle檔案,到這裡就可以結束咯(ps只要在控制類中呼叫此類就完成了)
如果你是想要將多個excel表打包成zip後再下載,請繼續看
程式碼不必看懂!!!!你只要知道以下是為了獲取一個excel表的列表(這裡還有個小小知識點就是列表的子列表哦)
/**
* 分頁獲取Excel的list列表
* @param startDate
* @param endDate
* @return
*/
private List<HSSFWorkbook> getExcelByPagination(String startDate, String endDate){
List<AliGoodsOrder> list = getOrderByDate(startDate,endDate);
int totalPage = list.size()%50 == 0 ? list.size()/50 : list.size()/50 + 1;
List<HSSFWorkbook> hssfWorkbookList = new ArrayList<>();
String fileName = startDate+"至"+endDate+"1688商品貨單資訊";
for(int page = 1; page <= totalPage; page++){
int fromIndex = (page-1)*50;
int toIndex;
if(page == totalPage && list.size()%50!= 0){
toIndex = fromIndex + list.size()%50;
}else{
toIndex = fromIndex + 50;
}
HSSFWorkbook hssfWorkbook = exportExcel(list.subList(fromIndex,toIndex),fileName);
if(hssfWorkbook != null){
hssfWorkbookList.add(hssfWorkbook);
}
}
return hssfWorkbookList;
}
下載zip的工具類要貼出來了~
//直接下載
public static void downFileByStream(HttpServletResponse response,List<HSSFWorkbook> excels,String fileName){
try {
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
ZipOutputStream zipOut = new ZipOutputStream(toClient);
for(int i=0;i<excels.size();i++){
ZipEntry entry = new ZipEntry(fileName+i+".xls");
zipOut.putNextEntry(entry);
excels.get(i).write(zipOut);
}
zipOut.flush();
zipOut.close();
}catch (Exception e){
log.error("downFileByStream==========fail");
log.error(ExceptionUtils.getTraceInfo(e));
}
}
用法---》下載的實現服務類
/**
* @ Date :2018/11/05
* @ Description:一個excel表中匯出50條記錄,打包放入zip檔案中並下載
*/
@Override
public void downLoadZip(HttpServletResponse response,String startDate, String endDate) {
try {
List<HSSFWorkbook> hssfWorkbookList = getExcelByPagination(startDate,endDate);
String fileName = startDate+"至"+endDate+"1688商品貨單資訊";
// File temp = File.createTempFile("temp",".zip");
// FileUtil.zipFiles(hssfWorkbookList,temp,fileName);
// response = FileUtil.downFile(response, temp);
// temp.deleteOnExit();
FileUtil.downFileByStream(response,hssfWorkbookList,fileName);
}catch (Exception e){
log.error("downLoadZip=======fail!"+ExceptionUtils.getTraceInfo(e));
}
}
從前端至後臺的程式碼就貼完了
為啥上面程式碼有幾行程式碼註釋了呢?因為之前的想法是將excel匯出後打包為zip檔案,然後客戶端就可以請求檔案下載了。
但是之後發現多此一舉了,直接將檔案流存到response.getOutputStream()裡面就行了
也貼下這個冗餘的程式碼把。
/**
* 將多個Excel打包成zip檔案
* @param srcfile
* @param zipfile
*/
public static void zipFiles(List<HSSFWorkbook> srcfile, File zipfile,String fileName) {
try {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipfile));
for (int i = 0; i < srcfile.size(); i++) {
out.putNextEntry(new ZipEntry(fileName+i+".xls"));
srcfile.get(i).write(out);
}
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 下載檔案
* @param response
* @param file
* @return
*/
public static HttpServletResponse downFile(HttpServletResponse response, File file) {
try {
// 以流的形式下載檔案。
InputStream fis = new BufferedInputStream(new FileInputStream(file.getPath()));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/x-zip-compressed");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
toClient.write(buffer);
toClient.flush();
toClient.close();
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
看到這個下載檔案的程式碼,我又要多叨嘮一句了,為啥我最後又是返回的null呢?因為返回response報錯了呀,看網上大家都說
response.getOutputStream()和伺服器裡的out.write()衝突了啥啥啥反正我是沒看懂,只記住了一個可愛的小朋友說,你只要返回null就行了。。。
這篇部落格就這樣粗略的貼程式碼放功能把,下篇了再講講遇到的新知識點