由于时间问题,文中代码没有进行细致的分析讲解
?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:
- poi导出excel最常用的方式
- 操作Excel2003以前(包括2003)的版本,扩展名是.xls
- 导出的行数至多为65535行,超出65536条后系统就会报错。此方式因为行数不足七万行所以一般不会发生内存不足的情况(OOM)
XSSFWorkbook:
- 操作Excel2007的版本,扩展名是.xlsx
- 这种形式的出现是为了突破HSSFWorkbook的65535行局限。其对应的是excel2007(1048576行,16384列)扩展名为“.xlsx”,最多可以导出104万行,不过这样就伴随着一个问题—OOM内存溢出,原因是你所创建的book
sheet row cell等此时是存在内存的并没有持久化。
SXSSFWorkbook
- 从POI 3.8版本开始,提供了一种基于XSSF的低内存占用的SXSSF方式。对于大型excel文件的创建,一个关键问题就是,要确保不会内存溢出。其实,就算生成很小的excel(比如几Mb),它用掉的内存是远大于excel文件实际的size的。如果单元格还有各种格式(比如,加粗,背景标红之类的),那它占用的内存就更多了。对于大型excel的创建且不会内存溢出的,就只有SXSSFWorkbook了。它的原理很简单,用硬盘空间换内存(就像hashmap用空间换时间一样)。
- 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方法执行完之后流就拿不到大小了
文章图片
?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
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)