废话不多说咱们直接上干货!!!!
首先我们先了解一下POI的一个使用步骤
一.读取Excel表格
【1】使用POI读取excel表格中的数据
POI还可以操作我们这个word文档等等,他不仅仅只能弄Excel,而JXI只能操作excel
1.POI的结构,我们可以更具文件的类去选择 相关的对象我当前是使用的XLSX来操作的
HSSF - 提供读写Microsoft Excel XLS格式档案的功能 XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能 HWPF - 提供读写Microsoft Word DOC格式档案的功能 HSLF - 提供读写Microsoft PowerPoint格式档案的功能 HDGF - 提供读Microsoft Visio格式档案的功能 HPBF - 提供读Microsoft Publisher格式档案的功能 HSMF - 提供读Microsoft Outlook格式档案的功能 |
2.需要引入相关的依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.14</version>
</dependency>
3.实例demo代码(两种方式任由你选择)
方式一:
读取xls类型的excel文件,前提是要创建好一个excel表格,并且里面要存在数据,然后我们尝试读取
//用来测试文档POI来读取excel的数据
@Test
public void Xlstest01() throws IOException {
HSSFWorkbook excel = new HSSFWorkbook(new FileInputStream(new File("d:\\posl.xls")));//实例化我的这个文档对象,通过我的这个输入流来假造我的这个表格 (工作簿)
//读取excel的第一个sheet页来进行读取
HSSFSheet sheet = excel.getSheetAt(0);//他主要是通过我的这个下标来进行读取我的这个页码下面数据
//便利我的这个sheet的这个对象来得到我的这个表格页码中的每一行的数据
for (Row row : sheet) {
//便利每一行 来获取我的这个单元格的数据
for (Cell cell : row) {
System.out.println(cell.getStringCellValue());//输出我的这个excel表格中的这个数据
}
}
excel.close();//关闭我的这个工作簿
}
方式二:
@Test
public void xlsxTest03() throws Exception {
XSSFWorkbook excel = new XSSFWorkbook(new FileInputStream(new File("d:\\mess.xlsx")));//用来读取我的这个excel表格当中的信息
XSSFSheet sheetAt = excel.getSheetAt(0);//用来获得我的这个文件的这个第一个sheet的表格信息
int lastRowNum = sheetAt.getLastRowNum();//用来获得我的最后一个行号,注意我的这个行号是从0开始的
System.out.println("我都这个行号是:"+lastRowNum);
for (int i = 0; i <= lastRowNum; i++) {
XSSFRow row = sheetAt.getRow(i);//更具我的这个行号来 获得我都这个数据
short lastCellNum = row.getLastCellNum();//用来获得我都行最后一个单元格
//用来循环便利我都这个表格的这个行中的所有数据列表
for (int j = 0 ;j < lastCellNum;j++){
XSSFCell cells = row.getCell(j);//得到我都这个行的每一列数据
System.out.println(cells.getStringCellValue());//用来循环遍历我都这一行中的所有数据
}
}
excel.close();//关闭我当前的这个工作流
}
从以上代码可以发现有几个对象那么我们来介绍一下这几个对象
XSSFWorkbook:工作簿 XSSFSheet:工作表 Row:行 Cell:单元格 |
二.写入excel表格
代码如下:
/**
* 用来写入我的这个excel表格的数据
*/
@Test
public void test04() throws IOException {
//闯进啊我的这个excel的文件
XSSFWorkbook excel = new XSSFWorkbook();
XSSFSheet sheet = excel.createSheet("学生信息列表");//用来创建我的这个工作表格的excelshell的名字
XSSFRow title = sheet.createRow(0);//用来创建我的这个工作表sheet表格的第一行的数据
title.createCell(0).setCellValue("姓名");//用来产生我的这个第一个单元格
title.createCell(1).setCellValue("地址");//用来产生我的这个第二个单元格
title.createCell(2).setCellValue("年龄");//用来产生我的这个第三个单元格
XSSFRow dataRow = sheet.createRow(1);//创建第二行表格的第二行数据
dataRow.createCell(0).setCellValue("小明");//用来产生我的这个第一个单元格
dataRow.createCell(1).setCellValue("北京");//用来产生我的这个第二个单元格
dataRow.createCell(2).setCellValue("20");//用来产生我的这个第三个单元格
//创建一个输出流把我的这个数据写入到我的这个磁盘当中
FileOutputStream out = new FileOutputStream("d:\\csexcel\\学生表格信息.xlsx");//将我的这个文件数据写入到我的这个磁盘当中
excel.write(out);//将我的这个数据写入到我的这个文件中
out.flush();//刷新我的这个输出流
excel.close();//关闭我的这个excel的工作簿
}
但是我们在一般的项目开发当中我们不可能按照这样的demo形式去写那么我自己也为大家总结了一个工具类提供给大家使用
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;
public class POIUtils {
private final static String xls = "xls";
private final static String xlsx = "xlsx";
private final static String DATE_FORMAT = "yyyy/MM/dd";
/**
* 读入excel文件,解析后返回
* @param file
* @throws IOException
*/
public static List<String[]> readExcel(MultipartFile file) throws IOException {
//检查文件
checkFile(file);
//获得Workbook工作薄对象
Workbook workbook = getWorkBook(file);
//创建返回对象,把每行中的值作为一个数组,所有行作为一个集合返回
List<String[]> list = new ArrayList<String[]>();
if(workbook != null){
for(int sheetNum = 0;sheetNum < workbook.getNumberOfSheets();sheetNum++){
//获得当前sheet工作表
Sheet sheet = workbook.getSheetAt(sheetNum);
if(sheet == null){
continue;
}
//获得当前sheet的开始行
int firstRowNum = sheet.getFirstRowNum();
//获得当前sheet的结束行
int lastRowNum = sheet.getLastRowNum();
//循环除了第一行的所有行
for(int rowNum = firstRowNum+1;rowNum <= lastRowNum;rowNum++){
//获得当前行
Row row = sheet.getRow(rowNum);
if(row == null){
continue;
}
//获得当前行的开始列
int firstCellNum = row.getFirstCellNum();
//获得当前行的列数
int lastCellNum = row.getPhysicalNumberOfCells();
String[] cells = new String[row.getPhysicalNumberOfCells()];
//循环当前行
for(int cellNum = firstCellNum; cellNum < lastCellNum;cellNum++){
Cell cell = row.getCell(cellNum);
cells[cellNum] = getCellValue(cell);
}
list.add(cells);
}
}
workbook.close();
}
return list;
}
//校验文件是否合法
public static void checkFile(MultipartFile file) throws IOException{
//判断文件是否存在
if(null == file){
throw new FileNotFoundException("文件不存在!");
}
//获得文件名
String fileName = file.getOriginalFilename();
//判断文件是否是excel文件
if(!fileName.endsWith(xls) && !fileName.endsWith(xlsx)){
throw new IOException(fileName + "不是excel文件");
}
}
public static Workbook getWorkBook(MultipartFile file) {
//获得文件名
String fileName = file.getOriginalFilename();
//创建Workbook工作薄对象,表示整个excel
Workbook workbook = null;
try {
//获取excel文件的io流
InputStream is = file.getInputStream();
//根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象
if(fileName.endsWith(xls)){
//2003
workbook = new HSSFWorkbook(is);
}else if(fileName.endsWith(xlsx)){
//2007
workbook = new XSSFWorkbook(is);
}
} catch (IOException e) {
e.printStackTrace();
}
return workbook;
}
public static String getCellValue(Cell cell){
String cellValue = "";
if(cell == null){
return cellValue;
}
//如果当前单元格内容为日期类型,需要特殊处理
String dataFormatString = cell.getCellStyle().getDataFormatString();
if(dataFormatString.equals("m/d/yy")){
cellValue = new SimpleDateFormat(DATE_FORMAT).format(cell.getDateCellValue());
return cellValue;
}
//把数字当成String来读,避免出现1读成1.0的情况
if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
cell.setCellType(Cell.CELL_TYPE_STRING);
}
//判断数据的类型
switch (cell.getCellType()){
case Cell.CELL_TYPE_NUMERIC: //数字
cellValue = String.valueOf(cell.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING: //字符串
cellValue = String.valueOf(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_BOOLEAN: //Boolean
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_FORMULA: //公式
cellValue = String.valueOf(cell.getCellFormula());
break;
case Cell.CELL_TYPE_BLANK: //空值
cellValue = "";
break;
case Cell.CELL_TYPE_ERROR: //故障
cellValue = "非法字符";
break;
default:
cellValue = "未知类型";
break;
}
return cellValue;
}
}
一下是我在项目当中遇到的一些小的差异,在这里给大家分享一下,这个是属于比较基础的内容:
在客户端如果需要下载我的这个excel文件并且需要携带数据的时候那么这个的一个思路就是首先把我的这个excel表格中的数据先查询出来,然后按照我需要填充的位置,锁定我当前的这个excel单元格,最终使用setCellValue来把我的数据进行填充到我的这个单元个中,然后使用输出流把我的这个表格输出到我的这个客户端的磁盘硬盘中,注意我的这个流不能是自己自定义的流,需要通过response来获得我的这个outputStream,并且设置我当前的这个请求头数据的信息
我们一般会按照一下代码的方式来实现,就是用来自定义我们客户端浏览器的这个响应头信息
OutputStream outputStream = respons.getOutputStream();//获得前端的这个下载路径
HttpServletRequest.setContentType("application/vnd.ms-excel");//用来改变我当前的这个请求头的类型,我当前的这个excel文件头所响应的信息
response.setHeader("content-Disposition","attachment;filename=report.xlsx");//用来更改我的这个客户端下载文件的类型,filename的意思是我的这个文件下载下来是什么名字
workbook.write(outputStream);
outputStream.close();
workbook.close();
二.使用我们阿里巴巴的这一套EasyExcel来实现表格的导入导出
1.excel表格的导出
我们在使用POI在导入的时候他实际上在我们的这个系统当中在运行的时候可能会出现一些内存泄露之类的,其实我们的阿里巴巴开发了一套EasyExcel来实现我们的这个Excel的表格写入,他的底层是基于我们的这个POI来实现的,那么我们直接代码
第一步我们需要去导入我们的相关的EasyExcel的依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
等等,我们发现这个依赖里面包含了我们的这个POI的这个依赖
嘿嘿嘿,看来我还是没猜错滴
然后我们需要去准备我们相关的一些实体类,在这个实体类当中我们需要指定我的这个表格第一行的标题,那么我们应该如何去解决呢???我们可以直接在我们的这个实体类上面添加一个@ExcelProperty的这个注解来标识我的这个标题名称
实体类如下
package com.gjh.pojo;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Payment implements Serializable {//用来继承序列化
/**
* 用户逐渐
*/
@ExcelProperty("个人编号")
private Long id;
@ExcelProperty("学生姓名")
private String StudentName;
}
然后我们来实现把我们的这个excel表格导入到我们的这个系统磁盘中,代码如下
/**
* 由于实现关系我们就没有链接数据库了,
* 具体的思路是一样的
* 模拟我们的这个数据
*/
public class EasyExcels {
/**
* 准备我当前的这个相关的数据
* @return
*/
private static List<Payment> Student(){
List<Payment> payments = new ArrayList<>();//创建一个集合用来存储我们的这个学生信息,模拟数据
for (int i = 0; i < 100; i++) {
Payment payment = new Payment();
payment.setId((long) i);
payment.setStudentName("小明"+i+"号");
payments.add(payment);
}
return payments;
}
/**
* 我们现在写demo的场景下来实现EasyExcel的读写操作
*/
public static void main(String[] args) {
String Path = "D:\\学生学号统计表.xlsx";//用来定义我们的这个excel表格存入的路径
//在这里我们需要注意一下的是,write的这里面的参数有:生成excel的磁盘路径,第二个就是我们实体类的类名.class,最后doWrite就是需要写入的数据
EasyExcel.write(Path,Payment.class).sheet("学生信息显示").doWrite(Student());//我们把相关的信息写入到我的这个excel表格当中
}
}
然后我们发现我们的这个文件已经保存到我们的这个磁盘当中了
我们打开表格看一下,结果我们使用@ExcelProperty所定义的这个名称我们也显示出来了
2.使用EasyExcel来实现excel表格的读取
在这里我们的与POI的方式又不想同,我们在这里需要自定义一个工具类,就是需要去继承自AnalysisEventListener,他分别是是利用了反射和AOP的一个原理来实现表格的数据读取,,他的这个工具类如下(这个可以根据我们的这个项目业务来定义,不唯一)
package com.gjh.util;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.gjh.pojo.Payment;
import java.util.ArrayList;
import java.util.List;
public class ExcelRead extends AnalysisEventListener<Payment> {
//定义我们的这个集合用来存储我的这个Excel表格里面的这个数据
List<Payment> paymentList = new ArrayList<>();
/**
* 通过我们的这个反射的思想去读取我们的这个excel表格中的数据
* @param payment 这个是我的这个实体类,指定我的这个读取的类型
* @param analysisContext 这个是我们的这个分析器
*/
@Override
public void invoke(Payment payment, AnalysisContext analysisContext) {
System.out.println(JSON.toJSONString(payment.toString())); //用来输出我们读取到的信息
paymentList.add(payment);//把我们的这个信息添加到我们的这个list集合中
}
/**
* 这个就是使用了我们的这个AOP的思想来实现后置增强
* 就是说我们直接显示我们的解析完成
* @param analysisContext
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("报个数据解析成功");
}
}
然后我们再去编写我们的这个读取Excel文件的方法
/**
* 实现文件路径的读取
*/
@Test
public void read(){
//这个的含义就如下
// 第一个参数老样子得到我们的这个路径,
// 第二个参数就是得到我们的这个实体类的类型,
// 第三个参数就是用来通过我们刚刚自定义的方法来利用我们的这个反射和AOP的思想去读取我的这个excel中的数据
// 最终我们去得到excel中的第几个sheet,最后再去调用我们的这个doRead的这个读取数据的方法
String Path = "D:\\学生学号统计表.xlsx";//用来定义我们的这个excel表格存入的路径
EasyExcel.read(Path,Payment.class,new ExcelRead()).sheet().doRead();
}
最终我们将结果已经成功的打印到我们的这个控制台了文章来源:https://www.toymoban.com/news/detail-449241.html
文章来源地址https://www.toymoban.com/news/detail-449241.html
到了这里,关于使用POI和EasyExcel来实现excel文件的导入导出的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!