有些项目中要导入和导出 excel 文件。现在使用的工具有两个好用的其中有:
apache 下的 poi; 阿里的 EasyExcel。今天我们来简单的学习一下如何使用 poi 进行导入与导出。
首先说明一下:poi 不只能实现 excel 的导入导出。
其中 excel 的版本有两种,分别是以. xls 为结尾的老版本和. xlsx 为结尾的,在导出的时候我没有用到版本的限制只有在导入的时候我用到了版本。
在开始之前声明一下:这是本人在开发小项目的时候在短时间使用的,如有不对的和可以优化的地方希望大佬可以指出。谢谢!
说一下我的导出思路:
首先将 excel 看成一个 “数据库” 这样更好的理解,这里的 “数据库” 就是 HSSFWorkbook。
其次将 excel 中的每一页可以看成是一个数据库中的 “表”, 这里的 “表” 就是 sheet 。
其次 “表” 中的每行为 “字段”:row。
其次 每一行的一个单元格可以看成一个 “属性”:cell 。
那这样的话我们的导出的理解就更加方便了。
new 一个数据库:HSSFWorkbook。
通过 new 的对象进行创建表单 createSheet(“表名称”)。
在创建属性的时候,我们想的是在第一行中添加属性,这样我们要创建 sheet.createRow(0), 这样显示的是第一行。
创建单元格中的属性: row.createCell(0).setCellValue(“属性名称”)。
填写其他行的属性 ---⇒ 可以使用 for 循环进行添加。
最后使用输出流导出 excel。
导出:
步骤一:导入 jar:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.6</version>
</dependency>
步骤二:开始编写:
//创建xls文件
HSSFWorkbook hssfWorkbook = new HSSFWorkbook ();
//通过hss创建sheet
HSSFSheet sheet = hssfWorkbook. createSheet ( "学生信息表" );
//创建第一行的内容
HSSFRow row = sheet. createRow ( 0 );
//创建第一个单元格
HSSFCell cell = row. createCell ( 0 );
//给单元个赋值
cell. setCellValue ( "学生信息表" );
//合并单元格
sheet. addMergedRegion ( new CellRangeAddress ( 0 , 0 , 0 , 3 ));
//第二行的内容
String [] str = { "序号" , "姓名" , "性别" , "年龄" , "地址" , "电话" , "班级" };
//创建第二行的表单内容
HSSFRow row1 = sheet. createRow ( 1 );
//创建第二行单元格内容
for ( int i = 0 ; i < str.length; i ++ ) {
//第二行的内容
row1. createCell (i). setCellValue (str[i]);
}
//遍历循环数据进行添加
for ( int i = 0 ; i < one. size (); i ++ ) {
StudentsAndClasses students = headStudentService. queryStudentByStuId (one. get (i));
//创建第几行
HSSFRow row2 = sheet. createRow (i + 2 );
row2. createCell ( 0 ). setCellValue (i + 1 );
row2. createCell ( 1 ). setCellValue (students. getStuName ());
row2. createCell ( 2 ). setCellValue (students. getStuSex ());
row2. createCell ( 3 ). setCellValue (students. getStuBirthday ());
row2. createCell ( 4 ). setCellValue (students. getStuAddress ());
row2. createCell ( 5 ). setCellValue (students. getStuPhone ());
row2. createCell ( 6 ). setCellValue (students. getClassName ());
}
//输出
try {
//获取桌面
FileSystemView fsv = FileSystemView. getFileSystemView ();
File file1 = fsv. getHomeDirectory ();
String string = UUID. randomUUID (). toString ();
String str1 = string. substring ( 0 , 7 );
//生成文件
File file2 = new File (file1. getPath () + File.separator + "学生信息表" + str1 + ".xls" );
FileOutputStream file = new FileOutputStream (file2);
hssfWorkbook. write (file);
file. close ();
} catch (FileNotFoundException e ) {
e. printStackTrace ();
} catch (IOException e ) {
e. printStackTrace ();
}
说一下我的导入思路:
导入和导出一样,但是要导入到数据库中,所以我们可以反向操作(笑哭)。导出怎么使用我们就反向写入。但是我们在导入的时候要判断版本。
写个判断版本的类,同时要使用流进行操作
public Workbook getworkBook (String fileName, InputStream inputStream) throws IOException {
Workbook workbook = null ;
if (fileName. endsWith ( ".xls" )) {
workbook = new HSSFWorkbook (inputStream);
} else if (fileName. endsWith ( ".xlsx" )) {
workbook = new XSSFWorkbook (inputStream);
}
return workbook;
}
编写:
//创建输入流
InputStream inputStream = file. getInputStream ();
//获取名称
String fileName = file. getOriginalFilename ();
//判断什么版本
Workbook workbook = this . getworkBook (fileName, inputStream);
//获取文件中的表格
Sheet sheetAt = workbook. getSheetAt ( 0 );
//获取文件中的长度从0开始
int lastRowNum = sheetAt. getLastRowNum ();
List< StudentsAndClasses > list = new ArrayList<>();
StudentsAndClasses student = null ;
for ( int i = 0 ; i <= sheetAt. getLastRowNum (); i ++ ) {
Row row = sheetAt. getRow (i + 2 );
student = new StudentsAndClasses ();
//当超出sheet的长度后,跳出循环
if (i + 2 > lastRowNum) {
break ;
}
//输出循环
System.out. println (sheetAt. getLastRowNum ());
// System.out.println(student.setStuId((int) row.getCell(0).getNumericCellValue()););
student. setStuName (row. getCell ( 1 ). getStringCellValue ());
student. setStuSex (row. getCell ( 2 ). getStringCellValue ());
student. setStuBirthday (row. getCell ( 3 ). getStringCellValue ());
student. setStuAddress (row. getCell ( 4 ). getStringCellValue ());
student. setStuPhone (row. getCell ( 5 ). getStringCellValue ());
student. setClassName (row. getCell ( 6 ). getStringCellValue ());
// System.out.println("最后一个数" + row.getLastCellNum());
list. add (student);
}
//写入数据库
for (StudentsAndClasses studentsAndClasses : list) {
//数据库代码(略)
}
} catch (IOException e ) {
e. printStackTrace ();
}
这只是我短时间内查看后的编写的。这里面的代码太粗糙了简单的了,等有时间沉下心来仔细翻看 api 后会进行跟新。其实导入的时有很多要注意的,只是这里项目时间短,没有仔细想一下。比如在上传的时候可以判断这一行是否有数据等。等有时间再看 api 吧,这里希望大家也可以看一下 api。相比与这个,api 才是真的正解。
代码粗糙,基本都写的有点死,还希望大佬能够指点。