POI简介:Jakarta POI 是一套用于访问微软格式文档的Java API。Jakarta POI有很多组件组成,其中有用于操作Excel格式文件的HSSF和用于操作Word的HWPF,在各种组件中目前只有用于操作Excel的HSSF相对成熟。
官方主页http://poi.apache.org/index.html,
API文档http://poi.apache.org/apidocs/index.html
现在用的比较多的都是用POI技术来导出或者导入Excel,用POI导出Excel我们首先要下载所需的jar包然后导入到我们的项目中,用maven的同学只需找到相关依赖加入到pom.xml里面即可。这里我用maven导包。
1 2 3 4 5 6 |
<!--POI处理EXCEL--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.6</version> </dependency> |
Jakarta POI HSSF API组件:
HSSF(用于操作Excel的组件)提供给用户使用的对象在rg.apache.poi.hssf.usermodel包中,主要部分包括Excel对象,样式和格式,有以下几种常用的对象:
常用组件:
HSSFWorkbook excel的文档对象
HSSFSheet excel的表单
HSSFRow excel的行
HSSFCell excel的格子单元
HSSFFont excel字体
样式:
HSSFCellStyle cell样式
基本操作步骤:
首先,我们应该要知道的是,一个Excel文件对应一个workbook,一个workbook中有多个sheet组成,一个sheet是由多个行(row)和列(cell)组成。那么我们用poi要导出一个Excel表格
的正确顺序应该是:
1、用HSSFWorkbook打开或者创建“Excel文件对象”
2、用HSSFWorkbook对象返回或者创建Sheet对象
3、用Sheet对象返回行对象,用行对象得到Cell对象
4、对Cell对象读写。
5、将生成的HSSFWorkbook放入HttpServletResponse中响应到前端页面
工具类代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
package com.self.util; import org.apache.poi.hssf.usermodel.*; /** * @ClassName ExcelUtil * @Description Excel生成工具类 * @Author zxl * @Date 2019/2/1 10:30 * @Version 1.0 */ public class ExcelUtil { /** *@Author S12434 *@Description 导出Excel *@Date 10:36 2019/2/1 *@Param [sheetName sheet名称, title 标题, values 内容, wb HHSWorkbook对象] *@Return org.apache.poi.hssf.usermodel.HSSFWorkbook */ public static HSSFWorkbook getHHSWorkbook(String sheetName,String[] title,String[][] values,HSSFWorkbook wb ){ //第一步,创建一个HSSFWorkbook,对应一个Excel文件 if(wb==null){ wb=new HSSFWorkbook(); } //第二步,在workbook中添加一个sheet,对应Excel文件中的sheet HSSFSheet sheet=wb.createSheet(sheetName); //第三步,在sheet中添加表头第0行,注意老版本poi对EXCEL的行数列数的限制 HSSFRow row=sheet.createRow(0); //第四步,创建单元格,并设置值表头,设置表头居中 HSSFCellStyle style=wb.createCellStyle(); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); //声明列对象 HSSFCell cell=null; //创建标题 for(int i=0;i<title.length;i++){ cell=row.createCell(i); cell.setCellValue(title[i]); cell.setCellStyle(style); } //创建内容 for(int i=0;i<values.length;i++){ row = sheet.createRow(i + 1); for(int j=0;j<values[i].length;j++){ row.createCell(j).setCellValue(values[i][j]); } } return wb; } } |
控制器代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
package com.self.controller; import com.self.common.Criteria; import com.self.entity.OsInput; import com.self.service.IOsInputService; import com.self.util.ExcelUtil; import com.self.util.QueryUtils; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.*; /** * @ClassName ExcelReportController * @Description Excel报表导出类 * @Author zxl * @Date 2019/2/1 11:10 * @Version 1.0 */ @Controller @RequestMapping("/excel") public class ExcelReportController { @Autowired IOsInputService iOsInputService; @RequestMapping("/inputExport") @ResponseBody public Map<String,String> inputExport(HttpServletRequest request,HttpServletResponse response,String order,String sort) { Map<String,String> map= new HashMap<>(); map.put("statusCode","200"); map.put("message","导出成功!"); Enumeration<?> e = request.getParameterNames(); TreeMap<String, Object> params = new TreeMap<String, Object>(); while (e.hasMoreElements()) { String name = (String) e.nextElement(); Object value = request.getParameter(name); if (value != null && !"".equals(value)) { params.put(name, value); } } String[] sortBy = null;//排序的字段 Sort s=null; if (sort != null) { sortBy = sort.split(","); Sort.Direction direction = Sort.Direction.ASC; if ("desc".equals(order)) { direction = Sort.Direction.DESC; } s = new Sort(direction, sortBy); } Criteria<OsInput> c = new Criteria<OsInput>(); for (Map.Entry<String, Object> entry : params.entrySet()) { // //Map里面有值表示有查询条件 switch (entry.getKey().toString()){ case "conditions": QueryUtils.queryConditions(c, (String)entry.getValue()); break; default: break; } } List<OsInput> list=iOsInputService.findAll(c,s); //excel标题 String[] title = {"编号","用品名称","供应商","规格型号","类别","计量单位","库位","入库数量","单价","税后单价","税","金额","税后金额","入库时间","操作人工号","操作人姓名","备注"}; //excel文件名 String fileName = "办公用品出库记录"+System.currentTimeMillis()+".xls"; //sheet名 String sheetName = "办公用品出库记录表"; String [][] content=new String[list.size()][title.length]; for(int i=0;i<list.size();i++){ OsInput osInput=list.get(i); content[i][0]=osInput.getOsiIndex().toString();//编号 content[i][1]=osInput.getOsiName();//用品名称 content[i][2]=osInput.getOsiSupName();//供应商 content[i][3]=osInput.getOsiModel();//规格型号 content[i][4]=osInput.getOsiTypeName();//类别 content[i][5]=osInput.getOsiUnitName();//计量单位 content[i][6]=osInput.getOsiStorehouse();//库位 content[i][7]=osInput.getOsiInputqty().toString();//入库数量 content[i][8]=osInput.getOsiPrice().toString();//单价 content[i][9]=osInput.getOsiPricetax().toString();//税后单价 content[i][10]=osInput.getOsiTaxname();//税 content[i][11]=osInput.getOsiCost().toString();//金额 content[i][12]=osInput.getOsiCosttax().toString();//税后金额 content[i][13]=osInput.getOsiInputdate().toString();//入库时间 content[i][14]=osInput.getOsiUsercode();//操作人工号 content[i][15]=osInput.getOsiUsername();//操作人姓名 content[i][16]=osInput.getOsiDesc();//备注 } //创建HSSFWorkbook HSSFWorkbook wb= ExcelUtil.getHHSWorkbook(sheetName,title,content,null); try{ this.setResponseHeader(response,fileName); OutputStream os=response.getOutputStream(); wb.write(os); os.flush(); os.close(); return map; }catch (Exception ec){ ec.printStackTrace(); map.put("statusCode","500"); map.put("message","导出失败:"+ec.getMessage()+"!"); return map; } } /** *@Author zxl *@Description 发送响应流方法 *@Date 13:40 2019/2/11 *@Param [response, fileName] *@Return void */ public void setResponseHeader(HttpServletResponse response, String fileName) { try { try { fileName = new String(fileName.getBytes(),"ISO8859-1"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } response.setContentType("application/octet-stream;charset=ISO8859-1"); response.setHeader("Content-Disposition", "attachment;filename="+ fileName); response.addHeader("Pargam", "no-cache"); response.addHeader("Cache-Control", "no-cache"); } catch (Exception ex) { ex.printStackTrace(); } } } |
前端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
function excelExport(){ var osiIndex = $("#osiIndex").combobox("getValue");//办公用品 var osiSupid = $("#osiSupid").combobox("getValue");//供应商 var osiModel = $("#osiModel").textbox("getValue");//规格型号 var osiTypecode = $("#osiTypecode").combobox("getValue");//类别 var startTime = $("#startTime").datebox("getValue").split("-").join("").split(" ").join("").split(":").join("");//入库日期从 var endTime = $("#endTime").datebox("getValue").split("-").join("").split(" ").join("").split(":").join("");//至 var osiUsercode = $("#osiUsercode").combobox("getValue");//操作人 //结束时间不能比开始时间小 if ("" != startTime && "" == endTime) { } else { if (!compareDateTime(endTime, startTime)) { $.messager.alert("警告", "结束时间大于开始时间", "warning"); return; } } var conditions = []; conditions.push("osiIndex_equal:" + osiIndex);//办公用品 conditions.push("osiSupid_equal:" + osiSupid);//供应商 conditions.push("osiModel_like:" + osiModel);//规格型号 conditions.push("osiTypecode_equal:" + osiTypecode);//类别 conditions.push("osiInputdate_startTimeHms:" + startTime);//入库日期从 conditions.push("osiInputdate_endTimeHms:" + endTime);//至 conditions.push("osiUsercode_equalTotal:" + osiUsercode);//操作人 // $.ajax({ // url:'../excel/inputExport?sort=osiInputdate&order=asc&conditions=' + conditions, // dataType:'json', // type:'post', // traditional: true, // success:function(data){ // alert(data.message); // // } // }); window.location.href='../excel/inputExport?sort=osiInputdate&order=asc&conditions=' + conditions; } |
从前端代码可以看到,ajax访问后台的方式被注释了,那是因为$.ajax,$.post 不支持返回二进制文件流的类型,dataType只支持xml,json,script,html这几种格式,没有blob类型。所以若要采用异步导出EXCEL的方式,只能选择使用原生Ajax XMLReques对象进行处理。
原生ajax异步请求参考文档:https://blog.csdn.net/swl979623074/article/details/77855629/
只需要修改前端代码即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
var xhr ; if(window.XMLHttpRequest){//code for IE7+,Firefox,Chrome,Opera,Safari xhr = new XMLHttpRequest(); }else{//code for IE6,IE5 xhr = new ActiveXObject("Microsoft.XMLHTTP"); } var url = '../excel/inputExport?sort=osiInputdate&order=asc&conditions=' + conditions; //设置响应类型为blob类型 xhr.responseType = "blob"; xhr.open("post", url, true); xhr.onload = function () { if (this.status == "200") { //获取响应文件流 var blob = this.response; var reader = new FileReader(); reader.readAsDataURL(blob); // 转换为base64,可以直接放入a表情href reader.onload = function (e) { // 转换完成,创建一个a标签用于下载 var a = document.createElement('a'); a.download = '办公用品.xls'; a.href = e.target.result; $("body").append(a); // 修复firefox中无法触发click a.click(); $(a).remove(); } } } xhr.send(); } |
转自:https://blog.csdn.net/zxl13735005529/article/details/87006714