POI导出excel的几种方式及HSSFWorkbook的代码实现

由于时间问题,文中代码没有进行细致的分析讲解 ?POI是Apache软件基金会的开放源码函式库是Apache下的顶级项目,提供API给Java程序对Microsoft Office格式档案读和写的功能。即通过简单的代码和后端流程即可实现指定数据导出Excel格式文件,便于企业进行数据分析备份等. ?POI导出Excel最常用的是第一种方式HSSFWorkbook,不过这种方式数据量大的话会产生报错问题,SXSSFWorkbook是一种大数据量导出格式,XSSFWorkbook介于两者之前大量数据伴随OOM内存溢出问题,csv是另一种excel导出的一种轻快的实现。在这里主要介绍前三种 ![在这里插入图片描述](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9jbmZveC5vc3MtY24tYmVpamluZy5hbGl5dW5jcy5jb20vaWNuZm94L2ltZy9ibG9nL3Byb2plY3QtaGVhZGVyLnBuZw?x-oss-process=image/format,png) 区别 ?用JavaPOI导出Excel时,我们需要考虑到Excel版本及数据量的问题。针对不同的Excel版本,要采用不同的工具类,如果使用错了,会出现错误信息。
HSSFWorkbook:

  1. poi导出excel最常用的方式
  2. 操作Excel2003以前(包括2003)的版本,扩展名是.xls
  3. 导出的行数至多为65535行,超出65536条后系统就会报错。此方式因为行数不足七万行所以一般不会发生内存不足的情况(OOM)
XSSFWorkbook:
  1. 操作Excel2007的版本,扩展名是.xlsx
  2. 这种形式的出现是为了突破HSSFWorkbook的65535行局限。其对应的是excel2007(1048576行,16384列)扩展名为“.xlsx”,最多可以导出104万行,不过这样就伴随着一个问题—OOM内存溢出,原因是你所创建的book
    sheet row cell等此时是存在内存的并没有持久化。
SXSSFWorkbook
  1. 从POI 3.8版本开始,提供了一种基于XSSF的低内存占用的SXSSF方式。对于大型excel文件的创建,一个关键问题就是,要确保不会内存溢出。其实,就算生成很小的excel(比如几Mb),它用掉的内存是远大于excel文件实际的size的。如果单元格还有各种格式(比如,加粗,背景标红之类的),那它占用的内存就更多了。对于大型excel的创建且不会内存溢出的,就只有SXSSFWorkbook了。它的原理很简单,用硬盘空间换内存(就像hashmap用空间换时间一样)。
  2. SXSSFWorkbook是streaming版本的XSSFWorkbook,它只会保存最新的excelrows在内存里供查看,在此之前的excelrows都会被写入到硬盘里(Windows电脑的话,是写入到C盘根目录下的temp文件夹)。被写入到硬盘里的rows是不可见的/不可访问的。只有还保存在内存里的才可以被访问到。当数据量超出65536条后,
当数据量超出65536条后,在使用HSSFWorkbook或XSSFWorkbook,程序会报OutOfMemoryError:Javaheap space; 内存溢出错误。这时应该用SXSSFworkbook。
SXSSF Beta 3.8下临时文件删除方法"
注意:针对 SXSSF Beta 3.8下,会有临时文件产生,比如:
poi-sxssf-sheet4654655121378979321.xml
文件位置:java.io.tmpdir这个环境变量下的位置
Windows 7下是C:\Users\xxxxxAppData\Local\Temp
Linux下是 /var/tmp/
要根据实际情况,看是否删除这些临时文件
HSSFWorkbook-SXSSFWorkbook导出excel文件获取大小记录 ?偶然发现HSSSFWorkbook 和SXSSFWorkbook workbook对象在执行write方法写入数据到ServletOutputStream(输出流)时 是有点区别的
?HSSFWorkbook在write方法执行完的时候并没有关闭流 ,所以我们可以对这个流统计大小来获取导出文件的大小,并且最后需要我们手动关闭
而SXSSFWorkbook的write方法流关闭,write方法执行完之后流就拿不到大小了
POI导出excel的几种方式及HSSFWorkbook的代码实现
文章图片

?HSSFWorkbook可以通过拿到流写入到文件里来获取文件的大小来获取导出excel的大小
?如下面这个controller例子:
/** * 导出文件 * @param request * @param response */ @RequestMapping("/salesQuery/modelSalesAmountFaw/exportExcelMap") public void exportExcel(HttpServletRequest request,HttpServletResponse response){Map, Object> paramsMap = getPageParams(request); try { Workbook wb = modelSalesAmountFawManager.exportExcel(request, paramsMap); String excelName = null; String languageType = request.getParameter("languageType"); System.out.println("languageType==="+languageType); if("EN".equals(languageType)){ excelName = java.net.URLEncoder.encode(moduleNameEn, "UTF-8"); } else{ excelName = java.net.URLEncoder.encode(moduleName, "UTF-8"); } response.setContentType("application/vnd.ms-excel; charset=utf-8"); SimpleDateFormat dateFormater = new SimpleDateFormat("yyyyMMddHHmmss"); Date date=new Date(); response.setHeader("Content-Disposition", "attachment; filename="+excelName+dateFormater.format(date)+".xls" ); ServletOutputStream out = response.getOutputStream(); wb.write(out); //先把EXCEL写到临时目录,用来获取文件大小,最后删除 File f = new File(request.getSession().getServletContext().getRealPath("/") + "/demoExcel/demo.xls"); if(!f.exists()) { f.createNewFile(); } BufferedOutputStream s = new BufferedOutputStream(new FileOutputStream(f)); wb.write(s); //关闭流 s.flush(); s.close(); out.flush(); out.close(); //记录导出日志,并删除临时文件 paramsMap.put("exportSize", AppFrameworkUtil.getNum(f.length()/1024, 0)); logManager.updateModuleLog(paramsMap); f.delete(); } catch (Exception e) { e.printStackTrace(); } }

HSSFWorkbook的代码实现 引入Maven坐标
org.apache.poi poi 3.9

前端绑定
导出Excel

后端Controller层
package cn.icnfox.crmpro.customer.controller; import cn.icnfox.crmpro.common.controller.BaseController; import cn.icnfox.crmpro.common.pojo.QueryObj; import cn.icnfox.crmpro.common.pojo.Result; import cn.icnfox.crmpro.customer.pojo.Customer; import cn.icnfox.crmpro.customer.service.CustomerService; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; @RestController @RequestMapping("/cus") public class CustomerController extends BaseController {@Autowired private CustomerService customerService; /*分页查询*/ @GetMapping("findByPage") public Result findByPage(QueryObj queryObj, @RequestParam (value="https://www.it610.com/article/pageNum",required = false,defaultValue = "https://www.it610.com/article/1") int pageNum, @RequestParam(value="https://www.it610.com/article/pageSize",required = false,defaultValue = "https://www.it610.com/article/5") int pageSize){PageHelper.startPage(pageNum,pageSize); List customers = customerService.findAll(queryObj); PageInfo pageInfo = new PageInfo<>(customers); if(customers!= null && customers.size()>0){ return getRightResult(pageInfo); }else{ return getWrongResult(); } }@GetMapping("findAll") public Result findAll(){ List customers = customerService.findAll(null); return getRightResult(customers); } /*保存*/ @PostMapping("save") public Result save(Customer customer){ customer.setAddtime(new Date()); boolean status = customerService.save(customer); if(status){ return getRightResult(); }else{ return getWrongResult(); } } /*通过id查询*/ @GetMapping("/findById/{id}") public Result findById(@PathVariable Integer id){ //健壮性判断 if(id==0||id==null){ return getWrongResult("the parameter(id) is not found !"); } Customer customer = customerService.findById(id); if(customer==null){ return getWrongResult("the result is null"); } return getRightResult(customer); } /*更新操作*/ @PostMapping("update") public Result update(Customer customer){ if(customer.getId()==0||customer.getId()==null){ return getWrongResult("the parameter(id) is not found !"); } boolean status = customerService.update(customer); if(!status){ return getWrongResult("修改失败..."); } return getRightResult(); } /*删除指定id*/ @PostMapping("deleteByIds") public Result deleteByIds(@RequestParam("ids") List ids){ if(ids==null||ids.size()==0){ return getWrongResult("please give me the ids !!"); } boolean status = customerService.deleteByIds(ids); if(status){ return getRightResult(); }else{ return getWrongResult("删除失败"); } }@GetMapping("exportXls") public ResponseEntity exportXls() throws IOException {//创建工作簿 Workbook workbook = new HSSFWorkbook(); //创建工作表 Sheet sheet = workbook.createSheet("new sheet"); //标题 Row title = sheet.createRow(0); title.createCell(0).setCellValue("编号"); title.createCell(1).setCellValue("公司名称"); title.createCell(2).setCellValue("联系人"); title.createCell(3).setCellValue("公司地址"); title.createCell(4).setCellValue("联系方式"); title.createCell(5).setCellValue("座机号码"); title.createCell(6).setCellValue("公司简介"); title.createCell(7).setCellValue("备注"); title.createCell(8).setCellValue("添加时间"); //内容检索注入 List all = customerService.findAll(null); for (Customer customer : all) { Row row = sheet.createRow(sheet.getLastRowNum() + 1); row.createCell(0).setCellValue(customer.getId()); row.createCell(1).setCellValue(customer.getComname()); row.createCell(2).setCellValue(customer.getCompanyperson()); row.createCell(3).setCellValue(customer.getComaddress()); row.createCell(4).setCellValue(customer.getComphone()); row.createCell(5).setCellValue(customer.getCamera()); row.createCell(6).setCellValue(customer.getPresent()); row.createCell(7).setCellValue(customer.getRemark()); row.createCell(8).setCellValue(new SimpleDateFormat("yyyy-MM-dd").format(customer.getAddtime())); }//byte数组 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); workbook.write(byteArrayOutputStream); byte[] bytes = byteArrayOutputStream.toByteArray(); //header HttpHeaders headers = new HttpHeaders(); headers.setContentDispositionFormData("attchment","customer.xls"); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); return new ResponseEntity(bytes,headers, HttpStatus.OK); } }

后端sercice层
package cn.icnfox.crmpro.customer.service; import cn.icnfox.crmpro.common.pojo.QueryObj; import cn.icnfox.crmpro.customer.pojo.Customer; import java.util.List; public interface CustomerService { List findAll(QueryObj queryObj); boolean save(Customer customer); Customer findById(Integer id); boolean update(Customer customer); boolean deleteByIds(List ids); }

package cn.icnfox.crmpro.customer.service.impl; import cn.icnfox.crmpro.common.pojo.QueryObj; import cn.icnfox.crmpro.customer.dao.CustomerDao; import cn.icnfox.crmpro.customer.pojo.Customer; import cn.icnfox.crmpro.customer.service.CustomerService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service @Transactional public class CustomerServiceImpl implements CustomerService {@Autowired @SuppressWarnings("all") private CustomerDao customerDao; @Override public List findAll(QueryObj queryObj) { return customerDao.findAll(queryObj); }@Override public boolean save(Customer customer) { return customerDao.save(customer)>0; }@Override public Customer findById(Integer id) { return customerDao.findById(id); }@Override public boolean update(Customer customer) { return customerDao.update(customer)>0; }@Override public boolean deleteByIds(List ids) { return customerDao.deleteByIds(ids)>0; } }

后端dao层
package cn.icnfox.crmpro.customer.dao; import cn.icnfox.crmpro.common.pojo.QueryObj; import cn.icnfox.crmpro.customer.pojo.Customer; import java.util.List; public interface CustomerDao {List findAll(QueryObj queryObj); int save(Customer customer); Customer findById(Integer id); int update(Customer customer); int deleteByIds(List ids); }

id="findAll" parameterType="queryObj" resultType="customer"> select * from customer comname like '%${keyword}%' companyperson like '%${keyword}%' order by id desc insert into customer values (null,#{comname},#{companyperson},#{comaddress},#{comphone},#{camera},#{present},#{remark},#{addtime}) id="findById" parameterType="int" resultType="customer"> select * from customer where id = #{id} update customer > comname=#{comname}, companyperson=#{companyperson}, comaddress=#{comaddress}, comphone=#{comphone}, camera=#{camera}, present=#{present}, remark=#{remark}, addtime=#{addtime}, where id = #{id} delete from customer where #{id}

【POI导出excel的几种方式及HSSFWorkbook的代码实现】本人个人网站: https://www.icnfox.cn 欢迎来访
有任何问题可以在个人网站的评论区留言,看到就会第一时间回复 啾咪ヾ(≧▽≦*)o

    推荐阅读