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。

导出->控制层代码,已经给出了正确的顺序。

欢迎大家评论与交流,加油!!

【参考】

  1. https://blog.csdn.net/phil_jing/article/details/78307819
  2. https://www.cnblogs.com/xbq8080/p/7344258.html    ajax请求导出excel的问题
  3. https://blog.csdn.net/anlian523/article/details/72268347    XSSFWorkbook的顺序问题

转载于:https://www.cnblogs.com/pan1042/p/10710900.html

POI 导入、导出Excel相关推荐

  1. POI导入导出excel表

            在企业办公系统中,常常有客户这样子要求:你要把我们的报表直接用Excel打开(电信系统.银行系统).或者是:我们已经习惯用Excel打印. Apache POI是Apache软件基金会 ...

  2. POI导入导出Excel(HSSF格式,User Model方式)

    1.POI说明 Apache POI是Apache软件基金会的开源代码库, POI提供对Microsoft Office格式档案读和写的功能. POI支持的格式: HSSF - 提供读写Microso ...

  3. POI导入导出Excel数据(IDEA版)简单运用

    一.POI Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能,简单来说就是能在Java程序中导入导出W ...

  4. POI导入导出EXCEL经典实现

    1.Apache POI简介 Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程式对Microsoft Office格式档案读和写的功能. .NET的开发人员则 ...

  5. springboot使用 poi 导入导出Excel工具类

    转载的一个比较好用的工具类 import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOE ...

  6. 使用poi导入导出Excel(实测有效)

    1. 导入Excel将数据转换为对象: /*** 传入一Excel表格,创建出对应的类集合 要求:类的字段名必须和Excel的首行的标题相同** @param filePath* @param cls ...

  7. Struts2 POI 导入导出Excel数据

    页面端: <html> <head> <title>导入数据</title> </head> <body> <h1> ...

  8. POI实现导入导出excel

    poi在日常的导入导出中是比较常用到的,最近也总结了下接触到的poi相关的导入导出的一些代码,有问题可以指出: package com.poi;import km.org.apache.poi.hss ...

  9. SpringBoot使用poi或EasyExcel导入导出Excel文件

    使用poi导入导出Excel 首先引入poi依赖包 03版本的Excel和07版本的Excel所需要的依赖不同,都需要导入. 记录问题: 最初导入的poi包为3.6版本.WorkBook类和Sheet ...

  10. java导入导出excel文件

    前言:该文章使用java集成poi来操作excel文件,此处只对poi相关api进行代码编写,对于poi的理论性知识,可在学习完这篇文章后,自行百度学习.建议大家跟着文章敲一遍代码. 创建一个mave ...

最新文章

  1. Cisco交换机解决网络蠕虫病毒***问题
  2. 20110625 AD下DFS实现冗余文件服务器,加密软件等
  3. axure 导入元件库显示不出白框_AXURE免费元件库分享-web
  4. xampp mysql.sock_解决xampp自启动和mysql.sock问题
  5. POJ3045 Cow Acrobats —— 思维证明
  6. Java中Dom解析XML
  7. solr服务器的查询过程
  8. PMCAFF微课堂 | 阿里高级产品专家: 揭秘B类App如何在高速生长期凝结含金量
  9. STM32串口中断实验总结函数的初始化必须在变量的初始化之后在进行!
  10. Unity学习日志_NGUI简介
  11. NAND FLASH简介
  12. 如何修改jar包并重新打包
  13. 认识uclinux(与LINUX区别)
  14. it人才外包公司招人真的很难吗?
  15. 区块链大咖谈之董天一:深度理解IPFS与Filecoin应用的几个关键点
  16. 02.使用fmod实现QQ变声效果
  17. 谷粒商城高级篇(38)——异步编排之商品详情查询
  18. VM 虚拟机网络配置
  19. RK3399 Android7/8 system vendor分区挂载参数
  20. js 延期执行_如何用javascript设置延时执行

热门文章

  1. Spark 学习入门教程
  2. 近十年计算机病毒侵害柱形图,全国2002年10月自学考试计算机应用基础真题
  3. sqlserver字符串转日期
  4. SDN 教程[2]: SDN基础操作
  5. c语言的中打印出鸟图形,教你画出一只萌萌哒小鸟【PS教程】
  6. javascript读取本地文件打印到浏览器中
  7. 【ArnoldC4D】6.ArnoldToC4D_光泽和反射光线深度(glossy_and_reflection)
  8. 点击input时,不显示边框!
  9. 录屏软件哪个好用?10个免费好用的「录屏软件」推荐
  10. html如何让table表格垂直(上下)居中