业务需求:将需求方要的数据导出excel表中。
1.只发出一次请求
2.每个excel表中到数据记录不能超过50条
碰过的坑:原先我发出的是ajax请求,然后请求成功却返回的都是乱码!我是想要下载文件啊!!!
ajax请求,响应的是文本数据,所以下载文件不能用ajax请求!用什么呢?用链接就行了
location.href= "../../aliGoodsOrder/export?startDate="+app.startDate+"&endDate="+app.endDate;
后台怎么导出excel呢,分享一个特别简单的工具类给大家:
@Log4j
public class Excel {
public static HSSFWorkbook createExcel(String sheetName, List 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 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;
}
}
org.apache.poi
poi-ooxml
3.16
怎么使用呢:
/**
* @ Date :2018/11/05
* @ Description:将1688商品订单导出Excel
*/
private HSSFWorkbook exportExcel(List allList,String name){
log.info("|createdExcel================start!============|");
HSSFWorkbook excel = null;
try{
List 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 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 getExcelByPagination(String startDate, String endDate){
List list = getOrderByDate(startDate,endDate);
int totalPage = list.size()%50 == 0 ? list.size()/50 : list.size()/50 + 1;
List 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 excels,String fileName){
try {
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
ZipOutputStream zipOut = new ZipOutputStream(toClient);
for(int i=0;i
用法---》下载的实现服务类
/**
* @ Date :2018/11/05
* @ Description:一个excel表中导出50条记录,打包放入zip文件中并下载
*/
@Override
public void downLoadZip(HttpServletResponse response,String startDate, String endDate) {
try {
List 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 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就行了。。。
这篇博客就这样粗略的贴代码放功能把,下篇了再讲讲遇到的新知识点