一、Apache POI是一种流行的API,它允许程序员使用Java程序创建,修改和显示MS Office文件。这由Apache软件基金会开发使用Java分布式设计或修改Microsoft Office文件的开源库。它包含类和方法对用户输入数据或文件到MS Office文档进行解码。

  二、基本结构

  HSSF - 提供读写Microsoft Excel格式档案的功能。
  XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。
  HWPF - 提供读写Microsoft Word格式档案的功能。
  HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
  HDGF - 提供读写Microsoft Visio格式档案的功能。
  三、这里我们只介绍xls,2003版的excel导入导出
  1)导入需要的依赖包(pom.xml)
      <dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>

  2)简单介绍一下excel的导入方式

 public static void main(String[] args) throws Exception {
//读取文件
File file = new File("d:\\test.xls");
InputStream inputStream = new FileInputStream(file);
//使用POI的流处理数据
POIFSFileSystem poifsFileSystem = new POIFSFileSystem(inputStream);
//声明2003版excel的文件读取方式
HSSFWorkbook hssfWorkbook = new HSSFWorkbook(poifsFileSystem);
//获取第一个sheet页
HSSFSheet sheetAt = hssfWorkbook.getSheetAt(0);
//获取数据总行数
int rows = sheetAt.getPhysicalNumberOfRows();
//每行数据处理
for (int i = 0; i < rows; i++) {
//获取一行数据
HSSFRow row = sheetAt.getRow(i);
if (i == 0) {
//这个主要用于标题
System.out.println(row.getCell(0));
continue;
}
//获取一行数据
Iterator<Cell> cellIterator = row.cellIterator();
List<Cell> cells = IteratorUtils.toList(cellIterator);
System.out.println(cells);
} }

  3)根据上面的基本实现功能封装了一些,工具类,主要目的是方便应用

  a、加入需要的工具依赖包(pom.xml)

    <dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>

  说明:这个东西主要是用来做数据对考的

  b、需要的实体类(这个类的目的就是用来保存excel中需要修改的一些参数位置)

import java.util.List;
import java.util.Map; public class ExcelParams { //sheet页数目
private Integer sheetNum = 0;
//实体名称
private String entityName;
//保存实体名称行数
private Integer clazzNum = 0;
//字段行数
private Integer columnNum = 1;
//开始数据读取的行数
private Integer dataNum = 3;
//开始读取列
private Integer readColNum = 0;
//读取的excel数据
private List<Map<String, Object>> excelList;
//最终数据处理
private List<Map<String, Object>> excelHandleList; public Integer getSheetNum() {
return sheetNum;
} public void setSheetNum(Integer sheetNum) {
this.sheetNum = sheetNum;
} public String getEntityName() {
return entityName;
} public void setEntityName(String entityName) {
this.entityName = entityName;
} public Integer getClazzNum() {
return clazzNum;
} public void setClazzNum(Integer clazzNum) {
this.clazzNum = clazzNum;
} public Integer getColumnNum() {
return columnNum;
} public void setColumnNum(Integer columnNum) {
this.columnNum = columnNum;
} public Integer getDataNum() {
return dataNum;
} public void setDataNum(Integer dataNum) {
this.dataNum = dataNum;
} public Integer getReadColNum() {
return readColNum;
} public void setReadColNum(Integer readColNum) {
this.readColNum = readColNum;
} public List<Map<String, Object>> getExcelList() {
return excelList;
} public void setExcelList(List<Map<String, Object>> excelList) {
this.excelList = excelList;
} public List<Map<String, Object>> getExcelHandleList() {
return excelHandleList;
} public void setExcelHandleList(List<Map<String, Object>> excelHandleList) {
this.excelHandleList = excelHandleList;
} }

  excel模板的基本方式:

  

  说明:1、前面的序列号,是我为了方便理解加上去的,实际中不用加

      2、第一行中的数据为需要保存的实体名路径,后续再保存的时候需要用到

      3、第二行是字段主要用于数据的对考,对考到具体的实体中

      4、第三行就是给输入数据的人员展示的,第四行开始就是具体的数据了

  c、数据处理接口

import com.troy.excel.domain.ExcelParams;

public interface ExcelHandle {

    ExcelParams excelDataHanle(ExcelParams excelParams);
}

  说明:这个接口目前没有实现方法。提供出来的目前是用于数据处理。自己在处理数据的时候写入数据处理的方式

  d、具体的解析过程和实体保存过程

  /**
* excel导入功能
* @param file
* @param excelParams
* @param excelHandle
* @return
* @throws Exception
*/
public static ExcelParams excelImport(File file, ExcelParams excelParams, ExcelHandle excelHandle) throws Exception {
//获取文件流
InputStream inputStream = new FileInputStream(file);
//通过poi的方式进行读取
POIFSFileSystem poifsFileSystem = new POIFSFileSystem(inputStream);
//声明工作簿
HSSFWorkbook hssfWorkbook = new HSSFWorkbook(poifsFileSystem);
//进入sheet页
HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(excelParams.getSheetNum());
//读取实体名称数据
HSSFRow entityRow = hssfSheet.getRow(excelParams.getClazzNum());
HSSFCell entityName = entityRow.getCell(excelParams.getReadColNum());
excelParams.setEntityName(entityName.getStringCellValue());
//读取数据保存到list中
List<Map<String,Object>> excelList = new ArrayList<>();
//获取字段数据
HSSFRow colunmRow = hssfSheet.getRow(excelParams.getColumnNum());
List<Cell> colums = IteratorUtils.toList(colunmRow.cellIterator());
//读取excel数据
for (int i = excelParams.getDataNum(); i < hssfSheet.getPhysicalNumberOfRows(); i++) {
//获取某一行的数据
HSSFRow excelRow = hssfSheet.getRow(i);
Map<String, Object> map = new HashMap<>();
for (int j = 0; j < excelRow.getPhysicalNumberOfCells(); j++) {
if (colums != null && colums.size() > j) {
HSSFCell rowCell = excelRow.getCell(j);
//设置类型的目的方便数据装换
rowCell.setCellType(CellType.STRING);
map.put(colums.get(j).getStringCellValue(), rowCell.getStringCellValue());
}
}
excelList.add(map);
}
//放入数据放入下一步处理
excelParams.setExcelList(excelList);
//ExcelHandle接口用来做进一步数据处理,要求必须重写
excelHandle.excelDataHanle(excelParams);
return excelParams;
}

  说明:ExcelHandle 为接口在使用的时候必须重写才可以实现

  /**
* 保存excel数据
* @param excelParams
* @return
*/
public static void saveExcelList(ExcelParams excelParams, EntityManager entityManager) throws Exception {
//1、获取保存的对象
Class<?> clazz = Class.forName(excelParams.getEntityName());
//2、保存数据
for (Map<String, Object> map:excelParams.getExcelHandleList()) {
//对考数据
Object object = clazz.newInstance();
BeanUtils.populate(object, map);
//保存数据
entityManager.persist(object);
}
}

  说明:BeanUtils提供了map到实体的拷贝,当然其他Gson,Fastjson也是可以实现的。

       entityManager.persist(object)是hibernate中保存对象的方法

  e、测试方法

public static void main(String[] args) throws Exception {
//读取文件
File file = new File("d:\\test.xls");
//声明参数
ExcelParams excelParams = new ExcelParams();
excelParams.setSheetNum(0);
excelParams.setClazzNum(0);
excelParams.setColumnNum(1);
excelParams.setDataNum(3);
excelParams.setReadColNum(0);
//导如数据
ExcelParams excelData = ExcelUtil.excelImport(file, excelParams, (ep) -> {
//重写具体的实现方法
ep.setExcelHandleList(excelParams.getExcelList());
return ep;
});
//保存实体,这里需要加入到事物中,我这里没有具体测试
ExcelUtil.saveExcelList(excelData, null);
System.out.println(excelParams.getExcelList());
}

  4)导出功能,导出功能相对简单。我就写了一个简单的实现过程,供理解。当然里面的样式这些,我不细说,自己研究

  /**
* excel数据导出
* @param title
* @param datas
* @param out
* @param <T>
* @throws Exception
*/
public static <T> void excelExport(String title, List<T> datas, OutputStream out) throws Exception {
//声明一个工作簿
HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
//设置一个sheet名词
HSSFSheet hssfSheet = hssfWorkbook.createSheet(title);
//数据处理,通过out写出
for (int i = 0; i < datas.size(); i++) {
//创建行数,主要是创建在第几行
HSSFRow hssfRow = hssfSheet.createRow(i);
//获取T的字段数
Field[] fields = datas.get(i).getClass().getDeclaredFields();
for (int j = 0; j < fields.length; j++) {
//获取字段名称
String fieldName = fields[j].getName();
//获取get方法
String methodName = "get"+ fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
Method method = datas.get(i).getClass().getMethod(methodName);
//执行get方法获取对应数据
Object text = method.invoke(datas.get(i));
//加入到对应单元格
HSSFCell hssfCell = hssfRow.createCell(j);
if (text != null) {
hssfCell.setCellValue(text.toString());
}
}
}
//写入到输出流中
hssfWorkbook.write(out);
}

  测试方法:

   public static void main(String[] args) throws Exception {
OutputStream outputStream = new FileOutputStream("d:\\1.xls");
String title = "用户数据";
List<User> users = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
User user = new User();
user.setId(i);
user.setName("name"+i);
users.add(user);
}
ExcelUtil.excelExport(title, users, outputStream);
}

  四、基本上实现过程都在里面,具体的封装过程可以自己参考一下

  五、源码下载:https://pan.baidu.com/s/1dahdRS

Java之POI的excel导入导出的更多相关文章

  1. SpringBoot集成文件 - 集成POI之Excel导入导出

    Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能.本文主要介绍通过Spr ...

  2. Java 使用 Jxl 实现 Excel 导入导出

    开发过程中经常需要用到数据的导入导出功能,之前用的是POI,这次使用JXL,JXL相对于POI来说要轻量简洁许多,在数据量不大的情况下还是非常实用的.这里做一下使用JXL的学习记录.首先需要导入相应的 ...

  3. 基于POI的Excel导入导出(JAVA实现)

    今天做了个excel的导入导出功能,在这记录下. 首先现在相关poi的相关jar包,资源链接:http://download.csdn.net/detail/opening_world/9663247 ...

  4. apache POI 操作excel<导入导出>

    1.首先导入maven依赖 <!-- POI核心依赖 --> <dependency> <groupId>org.apache.poi</groupId> ...

  5. 【原创】POI操作Excel导入导出工具类ExcelUtil

    关于本类线程安全性的解释: 多数工具方法不涉及共享变量问题,至于添加合并单元格方法addMergeArea,使用ThreadLocal变量存储合并数据,ThreadLocal内部借用Thread.Th ...

  6. Spring Boot学习笔记----POI(Excel导入导出)

    业务:动态生成模板导出Excel,用户修改完再导入Excel. Spring boot + bootstrap + poi 1.添加Dependence <dependency> < ...

  7. POI实现Excel导入导出

    我们知道要创建一张excel你得知道excel由什么组成,比如说sheet也就是一个工作表格,例如一行,一个单元格,单元格格式,单元格内容格式…这些都对应着poi里面的一个类. 一个excel表格: ...

  8. java简易excel导入导出工具(封装POI)

    Octopus 如何导入excel 如何导出excel github项目地址 Octopus Octopus 是一个简单的java excel导入导出工具. 如何导入excel 下面是一个excel文 ...

  9. 一个基于POI的通用excel导入导出工具类的简单实现及使用方法

    前言: 最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据.网上关于excel导入导出的例子很多,但大多相互借鉴. ...

随机推荐

  1. Python os.system()调用.sh脚本

    参考: python调用shell脚本的两种方法| Jeff的妙想奇境 已解决--求教python如何调用.sh文件- 查看主题• Ubuntu中文论坛 CODE #!/usr/bin/env pyt ...

  2. OpenGL超级宝典笔记——遮挡查询 [转]

    目录[-] 遮挡查询之前 包围体 遮挡查询 在一个场景中,如果有有些物体被其他物体遮住了不可见.那么我们就不需要绘制它.在复杂的场景中,这可以减少大量的顶点和像素的处理,大幅度的提高帧率.遮挡查询就是 ...

  3. rxjava rxandroid使用遇到的坑

    今天在解决一个界面加载本地数据库数据的时候,使用rxjava在指定io线程操作是遇到一个问题,即使指定了在io线程操作,可是界面还是卡顿,最后通过打印线程Thread.currentThread(). ...

  4. java线程中的interrupt,isInterrupt,interrupted方法

    在java的线程Thread类中有三个方法,比较容易混淆,在这里解释一下 (1)interrupt:置线程的中断状态 (2)isInterrupt:线程是否中断 (3)interrupted:返回线程 ...

  5. PHP-----------HTTP请求的第三方接口

    开发中常常遇到接口请求这个功能,后台也不例外,因为遇到了,所以写一篇. 前段时间做商城后台时,需要用到第三方物流接口查询物流信息. post: /**** * @param $url * @param ...

  6. Apereo CAS - 1

    1. download  cas 4.2.2 from https://github.com/apereo/cas/releases 2. eclipse import cas 4.2.2 eclip ...

  7. [批处理]Oracle启动助手

    前段日子开始学Oracle数据库,但是由于Oracle数据库的服务启动时间很长 所以机房的里面所有电脑的Oracle服务全部是被禁用的 所以每次上机使用的时候都要先进服务管理,然后把禁用更改为手动模式 ...

  8. 伴随我整十个年头的校内网,现名 人人网, 是不是要shut down 了

    如题: 每天我都习惯性的登录人人网,虽然现在基本上已经看不到曾经的同学上线了,不过我还是有事没事的往上面post 一些出行的照片,没事无聊的时候上这个网上看看自己曾经的照片,虽然已经无人在线,但是自己 ...

  9. IO的概念

    什么是IO: 在内存中存在数据交换的操作都可以认为是IO操作 和终端交互:input print 和磁盘交互:read write 和网络交互:recv send IO密集型程序:在程序执行过程中存在 ...

  10. ajax向后台请求数据,后台接收到数据并进行了处理,但前台就是调用error方法

    如果你的前台页面书写正确的情况下,并且运行情况和本文题目类似,那不妨试试这个: 在ajax方法中加上:async:false,让ajax同步执行. 因为ajax默认是异步的,至于为什么会不执行succ ...