本功能描述,在前端页面点击下载按钮,开始下载所需数据,效果图如下:
Google浏览器效果如下:
打开Excel如下:
Firefox浏览器效果如下:
首先要导入POI的jar包,我的工程采用maven管理,所以添加比较简单,如下代码
找到项目的pom.xml文件在<dependencies>中加入
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.11</version> </dependency>
如果需要手动导入可以去官网自己下载:https://poi.apache.org/
然后就可以开始写代码了,我先写的后端代码,本地环境测试:
//列出部分引用 import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.util.CellRangeAddress; String timeStamp= new SimpleDateFormat("yyyy-MM-dd").format(new Date()); //创建工作表,sheet对象,行以及单元格。 HSSFWorkbook wb=new HSSFWorkbook(); HSSFSheet sheet=wb.createSheet("History"); HSSFRow row=sheet.createRow(0); //字体居中 HSSFCellStyle style = wb.createCellStyle(); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); HSSFCell cell=row.createCell(0); cell.setCellStyle(style); cell.setCellValue("validatorHistory"+timeStamp); sheet.addMergedRegion(new CellRangeAddress(0,0,0,5));//合并单元格参数为起始行,截至行,起始列, 截至列 //在sheet中创建第二行 HSSFRow row2=sheet.createRow(1); //创建单元格并设置单元格内容 row2.createCell(0).setCellValue("Name1"); row2.createCell(1).setCellValue("Name2"); row2.createCell(2).setCellValue("Time1"); row2.createCell(3).setCellValue("Time2"); row2.createCell(4).setCellValue("person1"); row2.createCell(5).setCellValue("iscomplete"); // 调整列宽 sheet.setColumnWidth(0, (short)5500); sheet.setColumnWidth(1, (short)5500); sheet.setColumnWidth(2, (short)5500); sheet.setColumnWidth(3, (short)5500); sheet.setColumnWidth(4, (short)6000); sheet.setColumnWidth(5, (short)4000); //取出数据库中的值放入表格中 int rowNum = 2; List<类> history=*****Repository.get*****;//从数据库取出数据 if(history!=null && history.size()>0){ for(ValidatorTrigger vt:history){ HSSFRow vtrow=sheet.createRow(rowNum); vtrow.createCell(0).setCellValue(vt.getName1()); vtrow.createCell(1).setCellValue(vt.getName2()); vtrow.createCell(2).setCellValue(vt.getTime1()); vtrow.createCell(3).setCellValue(vt.getTime2()); vtrow.createCell(4).setCellValue(vt.getPerson1()); vtrow.createCell(5).setCellValue(vt.isComplete()); rowNum++; } } //输出Excel文件 FileOutputStream output=new FileOutputStream("d:\\workbook.xls"); wb.write(out); out.flush();
运行后就可以在D盘下看到workbook.xls文件了
测试POI可用,开始整体写,首先是前端代码,前端使用的是bootstrap:
//只贴了相关代码 <div class="down col-xs-6 col-md-offset-3"> <a id="download" href="#" class="btn btn-info btn-sm"> <span class="glyphicon glyphicon-download-alt"></span>DownloadHistory</a> </div> $(‘#download‘).click(function(){ var name1=$("select[id=name1]").val(); var name2=$("select[id=name2]").val(); location.href="/history/download?name1="+name1+"&name2="+name2; });
这里有个比较坑的地方,我之前使用的ajax方式,无论我怎样debug后台都没有下载的影子,后来我终于对我的前端产生了怀疑,网上查了一下,发现ajax请求只是个“字符型”的请求,即请求的内容是以文本类型存放的。这个link:https://blog.csdn.net/fan510988896/article/details/71520390 所以这里采用location.href方式(特意选了带参数的)
然后是controller部分:接收参数,调用Service
@ResponseBody @RequestMapping(value = "/history/download", method = RequestMethod.GET) public void download(HttpServletRequest request, HttpServletResponse response) throws IOException{ String name1=request.getParameter("name1"); String name2=request.getParameter("name2"); request.setCharacterEncoding("UTF-8"); //防止字体乱码 response.setCharacterEncoding("UTF-8"); this.***Service.downloadHistory(name1,name2,request,response); }
Service代码如下:
public void downloadHistory(String name1, String name2,HttpServletRequest request, HttpServletResponse response) throws IOException{ OutputStream out = null; String timeStamp= new SimpleDateFormat("yyyy-MM-dd").format(new Date()); //创建工作表,sheet对象,行以及单元格。 //在sheet中创建第二行 //创建单元格并设置单元格内容 // 调整列宽 //取出数据库中的值放入表格中 //上面部分代码和之前的一样,在输出Excel文件开始不同,如下 //输出Excel文件 try{ response.reset(); response.setContentType("application/x-download"); response.setCharacterEncoding("utf-8"); String fname = "history" + timeStamp;// Excel文件名 response.setHeader("Content-disposition", "attachment; filename="+fname+".xls"); out = response.getOutputStream(); wb.write(out); out.flush(); }catch(IOException e) { e.printStackTrace(); }finally { out.close(); } }
然后就大功告成了。
如果你想了解的更多可以参考:
https://blog.csdn.net/dcb_ripple/article/details/65435181
https://blog.csdn.net/szl13722587073/article/details/78663076
https://blog.csdn.net/m0_37899388/article/details/72778348?locationNum=5&fps=1
https://blog.csdn.net/u010251278/article/details/53491258
https://blog.csdn.net/LM5463640/article/details/53432364
https://blog.csdn.net/qinyf2015/article/details/78810622
https://blog.csdn.net/qq_33547950/article/details/54375399
原文地址:https://www.cnblogs.com/haiyuhappy/p/8797171.html