POI 导入、导出Excel
POI,全称Apache POI,是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。项目地址:Apache POI - the Java API for Microsoft Documents
1 导入
使用form表单(enctype="multipart/form-data")上传excel文件,后台接收MultipartFile文件格式。
读取excel
private static final String EXCEL_XLS = "xls";private static final String EXCEL_XLSX = "xlsx";/*** 判断Excel的版本,获取Workbook* @param in* @param file* @return* @throws IOException*/public static Workbook getWorkbok(InputStream in, MultipartFile file) throws IOException {Workbook wb = null;if(file.getOriginalFilename().endsWith(EXCEL_XLS)){ //Excel 2003wb = new HSSFWorkbook(in);}else if(file.getOriginalFilename().endsWith(EXCEL_XLSX)){ // Excel 2007/2010wb = new XSSFWorkbook(in);}return wb;}/*** 判断文件是否是excel* @throws Exception*/public static void checkExcelVaild(MultipartFile file) throws Exception{if(ToolUtil.isEmpty(file)){throw new Exception("文件不存在");}if(!((file.getOriginalFilename().endsWith(EXCEL_XLS) || file.getOriginalFilename().endsWith(EXCEL_XLSX)))){throw new Exception("文件不是Excel");}}/*** 读取Excel,兼容 Excel 2003/2007/2010 * @param excelFile * @param sheetIndex 从第几个sheet开始遍历 * @param dataRowIndex 从第几行开始遍历 * @throws Exception*/public static List<Map<String, Object>> parseExcelObject(MultipartFile excelFile, int sheetIndex, int dataRowIndex) {List<Map<String,Object>> lists = new ArrayList<>();SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");try {// 同时支持Excel 2003、2007FileInputStream is = (FileInputStream) excelFile.getInputStream(); // 文件流 checkExcelVaild(excelFile);Workbook workbook = getWorkbok(is,excelFile);//Workbook workbook = WorkbookFactory.create(is); // 这种方式 Excel2003/2007/2010都是可以处理的/*** 设置当前excel中sheet的下标:sheetIndex*/if(sheetIndex >= 0 && sheetIndex < workbook.getNumberOfSheets()){for (; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++){int rowSize = 0;Sheet sheet = workbook.getSheetAt(sheetIndex);for(int rowIndex = dataRowIndex; rowIndex <= sheet.getLastRowNum(); rowIndex++){Row row = sheet.getRow(rowIndex);if(row == null)continue;int tempRowSize = row.getLastCellNum();if(tempRowSize > rowSize)rowSize = tempRowSize;Map<String, Object> maps = new HashMap<String, Object>();String rowValue = "";for(short columnIndex = 0; columnIndex < row.getLastCellNum(); columnIndex++){Cell cell = row.getCell(columnIndex);if(ToolUtil.isEmpty(cell))continue;int cellType = cell.getCellType();String cellValue = "";switch (cellType){case Cell.CELL_TYPE_STRING: // 文本cellValue = cell.getRichStringCellValue().getString().trim();break;case Cell.CELL_TYPE_NUMERIC: // 数字、日期if (DateUtil.isCellDateFormatted(cell)) {cellValue = fmt.format(cell.getDateCellValue());} else {cell.setCellType(Cell.CELL_TYPE_STRING);cellValue = String.valueOf(cell.getRichStringCellValue().getString());}break;case Cell.CELL_TYPE_BOOLEAN: // 布尔型cellValue = String.valueOf(cell.getBooleanCellValue());break;case Cell.CELL_TYPE_BLANK: // 空白cellValue = cell.getStringCellValue();break;case Cell.CELL_TYPE_ERROR: // 错误cellValue = "";break;case Cell.CELL_TYPE_FORMULA: // 公式// 得到对应单元格的公式//cellValue = cell.getCellFormula() + "#";// 得到对应单元格的字符串 cell.setCellType(Cell.CELL_TYPE_STRING);cellValue = String.valueOf(cell.getRichStringCellValue().getString());break;default:cellValue = "";}// 保存数据if (columnIndex == 0){maps.put("name", cellValue);} // ......其他逻辑...... }lists.add(maps);}}}is.close(); //关闭文件流 } catch (Exception e) {e.printStackTrace();} finally{}return lists;}
控制层
/*** 导入excel** @param multipartFile* @return*/ @RequestMapping(value = "/importExcel", method = RequestMethod.POST) @ResponseBody public void importExcel(@RequestParam("file") MultipartFile multipartFile) {if (multipartFile == null) {throw new Exception("excel文件请求参数错误");}List<Map<String, Object>> list = ExcelUtil.parseExcelObject(multipartFile, 0, 0); // 这里只解析第一个sheet,从第一行开始for(Map<String, Object> map : list){System.out.println(map.getString("name"));} }
1 导出
如果你想看到下载弹框提示,如下图,那么就需要使用form表单提交方式,请求后台接口。接下来会解释为什么。
写入excel
public static XSSFWorkbook createExcelObject(List<ExcelObject> list) {SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");try {// 第一步,创建一个webbook文件,对应一个excel文件XSSFWorkbook wb = new XSSFWorkbook();// 第二部,在excel中添加一个sheet工作簿,参数为该工作簿名字,不写为默认;XSSFSheet sheet = wb.createSheet("sheet1");// 第三部,做sheet中添加表头第0行,注意老版本poi对excel的行数列数有限制shortXSSFRow row = sheet.createRow((int) 0);// 第四部,设置单元格样式XSSFCellStyle style = wb.createCellStyle();style.setAlignment(HorizontalAlignment.CENTER);//创建一个居中格式// 生成字体Font font = wb.createFont();font.setFontHeightInPoints((short) 12);font.setBold(true);// 把字体应用到当前的样式 style.setFont(font);// 第五部,设置好表头内容XSSFCell cell = row.createCell(0);cell.setCelSPUue("name");cell.setCellStyle(style)// 第六部,写入实体数据 实际应用中这些数据应该是从数据库中得到for (int i = 0; i < list.size(); i++) {// 每次新建一行然后在新行中插入list中的数据对象,有点繁琐,也许有更好的封装方法,留待后看row = sheet.createRow((int) i + 1);row.createCell((int) 0).setCellValue(list.get(i).getName());}return wb;} catch (Exception e) {e.printStackTrace();} finally {}return null;}
控制层
/*** 导出商品信息** @param request* @param response* @throws Exception*/ @RequestMapping(value = "/downExcel",method = RequestMethod.POST) @ResponseBody public void downExcel(HttpServletRequest request, HttpServletResponse response){List<ExcelObject> list; // 查询出来的数据// 正确代码顺序//FileInputStream fs=new FileInputStream(excel);//XSSFWorkbook workbook = new XSSFWorkbook(fs);//FileOutputStream out=new FileOutputStream(excel);//workbook.write(out); XSSFWorkbook wb = ExcelUtil.createExcelObject(list);if (wb == null)throw new Exception("excel文件解析异常");try {// 设置输出的格式response.reset();// 清空输出流response.setHeader("Content-Disposition", "attachment; filename=" + new String(("excel.xlsx").getBytes(), "iso-8859-1"));// 设定输出文件头response.setContentType("application/x-download;charset=GBK");// 定义输出类型//创建输出流OutputStream outputStream = response.getOutputStream();wb.write(outputStream);outputStream.close();}catch (Exception e){e.printStackTrace();} }
3 疑难解答
1、为什么一定要form表单请求,才会出现下载弹框?而ajax请求方式却不会出现
因为,导出excel,在通过后台生成excel文件,并且以文件流的形式传递给前端,而ajax接收的返回数据类型只能是:字符串、xml。所以ajax处理不了返回的文件流。而浏览器可以处理。
2、注意,导出时的代码顺序,否则报错NotOfficeXmlFileException?
假如,你直接先把输入流,输出流建立好了以后,再创建新对象,就会报错。错误信息为: org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException: No valid entries or contents found, this is not a valid OOXML (Office Open XML) file。
导出->控制层代码,已经给出了正确的顺序。
欢迎大家评论与交流,加油!!
【参考】
- https://blog.csdn.net/phil_jing/article/details/78307819
- https://www.cnblogs.com/xbq8080/p/7344258.html ajax请求导出excel的问题
- https://blog.csdn.net/anlian523/article/details/72268347 XSSFWorkbook的顺序问题
转载于:https://www.cnblogs.com/pan1042/p/10710900.html
POI 导入、导出Excel相关推荐
- POI导入导出excel表
在企业办公系统中,常常有客户这样子要求:你要把我们的报表直接用Excel打开(电信系统.银行系统).或者是:我们已经习惯用Excel打印. Apache POI是Apache软件基金会 ...
- POI导入导出Excel(HSSF格式,User Model方式)
1.POI说明 Apache POI是Apache软件基金会的开源代码库, POI提供对Microsoft Office格式档案读和写的功能. POI支持的格式: HSSF - 提供读写Microso ...
- POI导入导出Excel数据(IDEA版)简单运用
一.POI Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能,简单来说就是能在Java程序中导入导出W ...
- POI导入导出EXCEL经典实现
1.Apache POI简介 Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程式对Microsoft Office格式档案读和写的功能. .NET的开发人员则 ...
- springboot使用 poi 导入导出Excel工具类
转载的一个比较好用的工具类 import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOE ...
- 使用poi导入导出Excel(实测有效)
1. 导入Excel将数据转换为对象: /*** 传入一Excel表格,创建出对应的类集合 要求:类的字段名必须和Excel的首行的标题相同** @param filePath* @param cls ...
- Struts2 POI 导入导出Excel数据
页面端: <html> <head> <title>导入数据</title> </head> <body> <h1> ...
- POI实现导入导出excel
poi在日常的导入导出中是比较常用到的,最近也总结了下接触到的poi相关的导入导出的一些代码,有问题可以指出: package com.poi;import km.org.apache.poi.hss ...
- SpringBoot使用poi或EasyExcel导入导出Excel文件
使用poi导入导出Excel 首先引入poi依赖包 03版本的Excel和07版本的Excel所需要的依赖不同,都需要导入. 记录问题: 最初导入的poi包为3.6版本.WorkBook类和Sheet ...
- java导入导出excel文件
前言:该文章使用java集成poi来操作excel文件,此处只对poi相关api进行代码编写,对于poi的理论性知识,可在学习完这篇文章后,自行百度学习.建议大家跟着文章敲一遍代码. 创建一个mave ...
最新文章
- Cisco交换机解决网络蠕虫病毒***问题
- 20110625 AD下DFS实现冗余文件服务器,加密软件等
- axure 导入元件库显示不出白框_AXURE免费元件库分享-web
- xampp mysql.sock_解决xampp自启动和mysql.sock问题
- POJ3045 Cow Acrobats —— 思维证明
- Java中Dom解析XML
- solr服务器的查询过程
- PMCAFF微课堂 | 阿里高级产品专家: 揭秘B类App如何在高速生长期凝结含金量
- STM32串口中断实验总结函数的初始化必须在变量的初始化之后在进行!
- Unity学习日志_NGUI简介
- NAND FLASH简介
- 如何修改jar包并重新打包
- 认识uclinux(与LINUX区别)
- it人才外包公司招人真的很难吗?
- 区块链大咖谈之董天一:深度理解IPFS与Filecoin应用的几个关键点
- 02.使用fmod实现QQ变声效果
- 谷粒商城高级篇(38)——异步编排之商品详情查询
- VM 虚拟机网络配置
- RK3399 Android7/8 system vendor分区挂载参数
- js 延期执行_如何用javascript设置延时执行
热门文章
- Spark 学习入门教程
- 近十年计算机病毒侵害柱形图,全国2002年10月自学考试计算机应用基础真题
- sqlserver字符串转日期
- SDN 教程[2]: SDN基础操作
- c语言的中打印出鸟图形,教你画出一只萌萌哒小鸟【PS教程】
- javascript读取本地文件打印到浏览器中
- 【ArnoldC4D】6.ArnoldToC4D_光泽和反射光线深度(glossy_and_reflection)
- 点击input时,不显示边框!
- 录屏软件哪个好用?10个免费好用的「录屏软件」推荐
- html如何让table表格垂直(上下)居中