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

  1. 创建一个maven项目,并在pom文件中导入poi相关依赖。
     <!--xls(03版本)需要的依赖--><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.9</version></dependency><!--xlsx(07版本)需要的依赖--><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.9</version></dependency><!--日期格式化工具--><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>2.10.4</version></dependency>
  1. 在Java中一切皆对象,xlsx各组成部分对于java来说也是对象。对于一个excel文件来说,要先有工作簿,然后有工作表,接着有行,最后有单元格;因此对于java而言,要使用poi先创建工作簿对象,然后创建工作表对象,接着创建行对象,最后创建单元格对象。(注意:这点很重要,因为这关系到后面的代码编写)
  2. 接下来使用代码生成xls和xlsx文件。poi提供HSSFWorkbook对象来操作xls,提供XSSFWorkbook来操作xlsx。注意看注释部分的代码描述。
/*** java生成excel文件*/
public class ExcelWriteTest {//生成xls文件,注意使用HSSFWorkbook对象@Testpublic void testWrite03() throws IOException {//1、创建一个工作簿;注意此处使用HSSFWorkbook对象Workbook workbook = new HSSFWorkbook();//2、通过工作簿来创建工作表,可自定义表名Sheet sheet = workbook.createSheet("测试表");//3、通过工作表来创建行;注意:第一行的下标是0Row row1 = sheet.createRow(0);//4、通过行来创建单元格,即(1,1)单元格;注意:单元格的下标也是从0开始Cell cell_1_1 = row1.createCell(0);//5、给单元格赋值cell_1_1.setCellValue("第1行第1列单元格");//创建(1,2)单元格Cell cell_1_2 = row1.createCell(1);cell_1_2.setCellValue("第1行第2列单元格");//创建第二行Row row2 = sheet.createRow(1);//创建(2,1)和(2,2)单元格,并写入数据Cell cell_2_1 = row2.createCell(0);cell_2_1.setCellValue("第2行第1列单元格");Cell cell_2_2 = row2.createCell(1);cell_2_2.setCellValue("第2行第2列单元格");//创建输出流对象,指定要生成的文件路径,注意格式一定是xls类型的FileOutputStream outputStream = new FileOutputStream("C:\\Users\\admin\\Desktop\\测试.xls");//将workbook对象(工作簿对象)写入流中workbook.write(outputStream);outputStream.close();System.out.println("xls文件生成完毕");}//生成xlsx文件,注意使用XSSFWorkbook对象//此处代码和上面testWrite03()方法除了XSSFWorkbook和xlsx类型不同,其他部分都相同@Testpublic void testWrite07() throws IOException {//创建一个工作簿;注意此处使用XSSFWorkbook对象Workbook workbook = new XSSFWorkbook();Sheet sheet = workbook.createSheet("测试表");Row row1 = sheet.createRow(0);Cell cell_1_1 = row1.createCell(0);cell_1_1.setCellValue("第1行第1列单元格");Cell cell_1_2 = row1.createCell(1);cell_1_2.setCellValue("第1行第2列单元格");Row row2 = sheet.createRow(1);Cell cell_2_1 = row2.createCell(0);cell_2_1.setCellValue("第2行第1列单元格");Cell cell_2_2 = row2.createCell(1);cell_2_2.setCellValue("第2行第2列单元格");//注意格式一定是xlsx类型的FileOutputStream outputStream = new FileOutputStream("C:\\Users\\admin\\Desktop\\测试2.xlsx");workbook.write(outputStream);outputStream.close();System.out.println("xlsx文件生成完毕");}}

到目前为止,已经可以生成简单的excel文件了,接下来介绍下HSSFWorkbook和XSSFWorkbook的区别,以及在面前大数据量情况下生成excel的解决方案。

  1. 以下是HSSF和XSSF各自的优缺点,另外再介绍一下生成xlsx文件更高效的SXSSF

HSSF:先写入缓存,不操作磁盘,最后一次性写入,效率高;但是最多只能处理65536行数据,否则就会报错,因为xls格式的文件最多存放65536行数据。
XSSF:可以写入比较大的数据量,如20万行,甚至更多;但是写数据的速度慢,非常耗内存,也有可能发生内存溢出的情况,如写入100万行数据时。因此在生成xlsx文件时,更推荐使用SXSSF对象,因为效率更高,下面用代码来展示SXSSF对象使用过程。

    //使用SXSSF生成大数据量xlsx文件,10万行@Testpublic void testWriteSXSSF() throws IOException {//开始时间long begin = System.currentTimeMillis();//创建顺序:工作簿-->工作表-->行-->单元格Workbook workbook = new SXSSFWorkbook();Sheet sheet = workbook.createSheet();//生成10万行for (int rowNum = 0; rowNum < 100000; rowNum++) {Row row = sheet.createRow(rowNum);//每行生成10个单元格for (int cellNum = 0; cellNum < 10; cellNum++) {Cell cell = row.createCell(cellNum);cell.setCellValue(cellNum);}}FileOutputStream outputStream = new FileOutputStream("C:\\Users\\admin\\Desktop\\测试3.xlsx");workbook.write(outputStream);outputStream.close();//生成sxls会产生临时文件,所以需要清除临时文件((SXSSFWorkbook) workbook).dispose();//结束时间long end = System.currentTimeMillis();System.out.println("耗时(秒):" + (double) (end - begin) / 1000);}
  1. 以上的内容介绍了使用poi生成excel文件,接下来介绍使用excel读取excel文件,其使用方式与导出类似,使用HSSF对象读取xls文件,使用XSSF读取xlsx文件,下面代码来演示用法:
    /*** 使用HSSF读取xls文件*/@Testpublic void readXls() throws IOException {//创建输入流对象,读取指定文件的内容FileInputStream inputStream = new FileInputStream("C:\\Users\\admin\\Desktop\\测试.xls");//使用流来构造工作簿对象,注意:这里读取xls文件,要构造HSSFWorkbook对象Workbook workbook = new HSSFWorkbook(inputStream);//通过sheet名称或者下标获取要读取的sheet页Sheet sheet = workbook.getSheetAt(0);//根据下标得到第1行Row row = sheet.getRow(0);//根据下标得到(1,1)单元格Cell cell = row.getCell(0);//获取单元格的值String value = cell.getStringCellValue();System.out.println(value);}/*** 使用XSSF读取xlsx文件*/@Testpublic void readXlsx() throws IOException {//创建输入流对象,读取指定文件的内容FileInputStream inputStream = new FileInputStream("C:\\Users\\admin\\Desktop\\测试2.xlsx");//使用流来构造工作簿对象,注意:这里读取xlsx文件,要构造XSSFWorkbook对象Workbook workbook = new XSSFWorkbook(inputStream);//通过sheet名称或者下标获取要读取的sheet页Sheet sheet = workbook.getSheetAt(0);//根据下标得到第1行Row row = sheet.getRow(0);//根据下标得到(1,1)单元格Cell cell = row.getCell(0);//获取单元格的值String value = cell.getStringCellValue();System.out.println(value);}
  1. 上面的代码,介绍了HSSF读取xls文件和XSSF读取xlsx文件的简单用法,但是在实际工作中读取的excel远比demo中的复杂,届时就需要各位大牛们使用代码逻辑来读取相关数据。另外,在excel中单元格的数据可能是字符串、数字、日期、布尔值等格式,下面介绍面对不同格式的数据时的读取方式:
    /*** 读取不同数据类型的单元格*/@Testpublic void readDifferentType() throws IOException {FileInputStream inputStream = new FileInputStream("C:\\Users\\admin\\Desktop\\测试.xls");//因为读取xls,因此此处创建HSSF对象Workbook workbook = new HSSFWorkbook(inputStream);Sheet sheet = workbook.getSheetAt(0);//通过sheet获取总行数int rowCount = sheet.getPhysicalNumberOfRows();for (int rowNum = 0; rowNum < rowCount; rowNum++) {Row row = sheet.getRow(rowNum);if (row != null) {//通过row获取总列数(即每行的单元格)int cellCount = row.getPhysicalNumberOfCells();for (int cellNum = 0; cellNum < cellCount; cellNum++) {Cell cell = row.getCell(cellNum);if (cell != null) {//获取单元格的数据类型int cellType = cell.getCellType();String cellValue = "";switch (cellType) {//字符串类型case HSSFCell.CELL_TYPE_STRING:cellValue = cell.getStringCellValue();break;//布尔类型case HSSFCell.CELL_TYPE_BOOLEAN:cellValue = String.valueOf(cell.getBooleanCellValue());break;//空case HSSFCell.CELL_TYPE_BLANK:break;//数字(日期、普通数字)case HSSFCell.CELL_TYPE_NUMERIC:if (HSSFDateUtil.isCellDateFormatted(cell)) {//日期格式Date date = cell.getDateCellValue();cellValue = new DateTime(date).toString("yyyy-MM-dd");} else {cell.setCellType(HSSFCell.CELL_TYPE_STRING);cellValue = cell.getStringCellValue();}break;//错误case HSSFCell.CELL_TYPE_ERROR:break;}//输出结果。但在工作中,大多是将读取的数据组成对象,存入数据库System.out.println(cellValue);}}}}inputStream.close();}
  1. 以上介绍了在读取不同数据类型数据时的处理方式,除此之外还有一种情况,如果单元格的数据是通过公式计算生成的,如下图所示,那这种情况该如何处理呢?(了解即可)


针对这种情况,poi专门提供了公式对象来解决,请观察以下代码:

    /*** 计算公式*/@SuppressWarnings("all")@Testpublic void readFormula() throws IOException {FileInputStream inputStream = new FileInputStream("C:\\Users\\admin\\Desktop\\公式测试.xls");Workbook workbook = new HSSFWorkbook(inputStream);Sheet sheet = workbook.getSheetAt(0);//(5,1)单元格所在的行是由公式生成Row row = sheet.getRow(4);Cell cell = row.getCell(0);//获取计算公式HSSFFormulaEvaluator formulaEvaluator = new HSSFFormulaEvaluator((HSSFWorkbook) workbook);//获取单元格数据类型int cellType = cell.getCellType();switch (cellType) {case HSSFCell.CELL_TYPE_FORMULA://获取公式字符串,即-->SUM(A2:A4)String cellFormula = cell.getCellFormula();System.out.println(cellFormula);CellValue evaluate = formulaEvaluator.evaluate(cell);String cellValue = evaluate.formatAsString();System.out.println(cellValue);break;}inputStream.close();}
  1. 截止到这里,想必大家已经了掌握poi操作excel的基本用法,但在实际工作中,仅靠这些是远远不够的,当出现一些比较复杂的情况时,如在导出excel时需要合并单元格、改变样式,又该如何处理呢?大家先看下导出excel的效果图。

    从上图中可以发现,有部分单元格是被合并的,接下来通过代码来演示如何合并单元格:
    /*** 导出excel文件*/public void export(HttpServletResponse response) throws IOException {HSSFWorkbook workbook = new HSSFWorkbook();//设置字体大小Font font = workbook.createFont();font.setFontHeightInPoints((short) 18);//定义样式HSSFCellStyle style = workbook.createCellStyle();style.setFont(font);//注意:这里有坑,在不同版本的poi中,设置居中方式不同。style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//水平居中style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直居中style.setWrapText(true);//自动换行//合并单元格的集合List<CellRangeAddress> addressList = new ArrayList<>();//创建sheetHSSFSheet sheet = workbook.createSheet("月报表");//设置第1列的宽度sheet.setColumnWidth(0, 35 * 256);//第一行标题Row row_0 = sheet.createRow(0);//设置行高row_0.setHeight((short) 1500);Cell cell_0_0 = row_0.createCell(0);//设置样式cell_0_0.setCellStyle(style);//注意:这里的值写死了,实际工作中要从数据库读取的cell_0_0.setCellValue("司法鉴定行业党建工作情况月报表\n(2020年7月)");/**使用CellRangeAddress对象合并单元格* CellRangeAddress参数解读:* 第一个参数:合并单元格的起始行下标* 第二个参数:合并单元格的结束行下标* 第三个参数:合并单元格的起始列下标* 第四个参数:合并单元格结束列下标* 最终意思:把从第1行到第1行,从第1列到第37列,合并为一个单元格* 注:参考上面的图片理解这句话的意思*/addressList.add(new CellRangeAddress(0, 0, 0, 36));//第二行Row row_1 = sheet.createRow(1);row_1.setHeight((short) 1000);Cell cell_1_0 = row_1.createCell(0);cell_1_0.setCellStyle(style);cell_1_0.setCellValue("山东省(市、区)");addressList.add(new CellRangeAddress(1, 1, 0, 5));/**因为第二行的第一个单元格合并了从第2行到第2行,从第1列到第6列的所有单元格(注意下标是0开始)*所有第二个单元格从第7列开始*/Cell cell_1_6 = row_1.createCell(6);cell_1_6.setCellStyle(style);cell_1_6.setCellValue("统计期间:截至2021年03月18日");//合并从第2行到第2行,从第7列到第37列的所有单元格addressList.add(new CellRangeAddress(1, 1, 6, 36));//其他单元格代码省略......//合并单元格for (CellRangeAddress address : addressList) {//CellRangeAddress描述单元格的合并信息,使用sheet的addMergedRegion方法执行合并操作sheet.addMergedRegion(address);}//通过response下载excel到客户端OutputStream outputStream = response.getOutputStream();response.reset();response.setHeader("Content-disposition","attachment;filename=" + new String("月报表".getBytes("gbk"), "iso8859-1") + ".xls");response.setContentType("application/msexcel");response.setCharacterEncoding("utf-8");workbook.write(outputStream);outputStream.flush();outputStream.close();}

以上便是使用poi导入导出excel文件的全部内容,满意的小伙伴记得点个赞哦!!>.<

java导入导出excel文件相关推荐

  1. JAVA导入/导出EXCEL文件,自定义校验,错误回写excel,使用简单快捷

    github地址: https://github.com/alan-et/alanpoi/tree/develop/alanpoi-analysis 项目中使用: <dependency> ...

  2. java 导入导出excel表格

    java 导入导出excel表格 业务上有需求上传excel表格并读取内容,本文记录一下该方法 表格导入 引入相应的工具包 <dependency><groupId>cn.af ...

  3. Java分页导出Excel文件

    Java分页导出Excel文件 1.开发微信小程序接入广告获取收益 技术: Springboot + mongodb + maven +Layui + thymeleaf 上一篇博客已经讲解了Java ...

  4. EOS中如何实现导入导出excel文件

    阅读原文 导入导出excel文件 场景描述 将数据库表中的数据按照定义的EXCEL模板进行导出,下载到本地: 将EXCEL中的数据导入数据库相应的表中. 场景目标 通过本场景,解决EXCEL的导入导出 ...

  5. java导入导出excel操作(jxl)

    java导入导出excel操作(jxl) Java解释Excel数据(jxl.jar包的使用) 关键字: java excel jxl.jar jxl.jar 包 下载地址: http://www.a ...

  6. 【转】 (C#)利用Aspose.Cells组件导入导出excel文件

    Aspose.Cells组件可以不依赖excel来导入导出excel文件: 导入: public static System.Data.DataTable ReadExcel(String strFi ...

  7. Java导入导出Excel工具类ExcelUtil

    前段时间做的分布式集成平台项目中,许多模块都用到了导入导出Excel的功能,于是决定封装一个ExcelUtil类,专门用来处理Excel的导入和导出 本项目的持久化层用的是JPA(底层用hiberna ...

  8. 利用java导入导出excel到oracle数据库

    用到的JAR包如下(可以直接到POI官网上下载也可以在文章的附件中下载): poi-3.9-20121203.jar poi-ooxml-3.9-20121203.jar poi-ooxml-sche ...

  9. JAVA工具类(17)--Java导入导出Excel工具类ExcelUtil

    实战 导出就是将List转化为Excel(listToExcel) 导入就是将Excel转化为List(excelToList) 导入导出中会出现各种各样的问题,比如:数据源为空.有重复行等,我自定义 ...

最新文章

  1. [Python]架设python虚拟环境以及部署PythonWeb服务
  2. python项目实战:获取本机所有IP地址的方法
  3. Leetcode-937-Reorder Log Files-(Easy)
  4. 2018前端学习总结
  5. 关于如何收集,标准化和集中化处理Golang日志的一些建议
  6. 【英语学习】【WOTD】trivial 释义/词源/示例
  7. 大数据_Hbase-(知识点回顾)---Hbase工作笔记0010
  8. Google 74版本上传附件没有“选择文件”按钮
  9. 此文已删除,为何删不掉?
  10. 通过tf的tensorboard可视化训练进度
  11. 计算机-计算机发展史
  12. 小哈机器人发布新品_解决孩子学习烦恼 小哈教育机器人二代新品上市
  13. BCD码指令 AAA DAA AAS DAS AAM AAD
  14. 宝塔如何安装多版本php,安装Lnmp(多PHP版本与宝塔)
  15. 外文翻译 《How we decide》多巴胺的预言 第二节
  16. sudo apt-get update报错:W: 校验数字签名时出错。此仓库未被更新,所以仍然使用此前的索引文件。W: 部分索引文件下载失败。如果忽略它们,那将转而使用旧的索引文件
  17. 带你简化理解Spring 基于注解配置的原理
  18. cobol .cpy文件_Visual COBOL R3:“使传统的COBOL能够部署在JVM或.NET上”。
  19. 【Android 电量优化】电量优化 ( 唤醒锁定 | 使用 WeakLock 保持服务唤醒 | 屏幕唤醒 )
  20. mybatis入门实例(xml文件配置)

热门文章

  1. x265 (HEVC编码器,基于x264) 介绍
  2. Centos7操作系统搭建Snipe-IT资产管理系统
  3. 2021中国大学生程序设计竞赛(CCPC)- 网络选拔赛(重赛) Jumping Monkey(并查集,逆向考虑)
  4. 中国移动5G技术概况介绍
  5. Ubuntu更换登录界面壁纸
  6. 112A.Petya and Strings
  7. 红米k30支持html,红米K30S至尊纪念版发布:骁龙865+支持144Hz高刷
  8. 如何更换AirTag电池?
  9. jpi多表联查_使用Mybatis进行多表联查操作
  10. java评论回复表设计_评论回复功能数据表设计