POI
其实这只是低配版,过几天等我有空了,再补一个好一点的解决方案。
一、需求背景
POI提供了一些API,可以是java程序对Microsoft Office的读和写
- 小明是一个按摩师,需要把用户信息存到数据库中,可以让客户把自己的信息填写在excel中,再通过POI提供的api,读取文档中的内容到数据库中。
- 小明的老板需要看小明的客户信息情况,小明可以在数据库中的内容写到excel中,再把文件给老板。
二、添加依赖
<dependencies>
<!--xls(03)-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<!--xlsx(07)-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<!--日期格式化工具-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.1</version>
</dependency>
<!--test-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
三、版本区别
- 对于excel,POI提供的03和07版本
因为我们不能控制用户的行为,用户用的是03还是07的excel,所以,提供的两套api
- 两者的区别
- 在使用上,只有两者的对象名不同,所用的api名字,操作流程都是一样的。
- 03
- 优点:把数据写到内存中,最后再一次性写入磁盘,速度快
- 缺点:最多只能处理65536行数据,否则就会抛出异常
- 07
- 优点:可以一次写叫大量的数据,如20W条数据
- 缺点:写数据数据慢,非常耗内存,也可能会发生内存异常,如100W条数据
四、把数据写到excel
效果图
@Test
public void testOne() throws IOException {
//创建workbook对象,相当于工作台
HSSFWorkbook workbook = new HSSFWorkbook();
//创建当前页,相当于excel左下角的sheet
HSSFSheet sheet = workbook.createSheet();
//创建第一行
HSSFRow rowOne = sheet.createRow(0);
//往第一行的0号位置填入数据 one
rowOne.createCell(0).setCellValue("one");
rowOne.createCell(1).setCellValue("two");
HSSFRow rowTwo = sheet.createRow(1);
rowTwo.createCell(0).setCellValue("third");
rowTwo.createCell(1).setCellValue("fourth");
//写到本地磁盘中
workbook.write(new FileOutputStream(new File("E:/sheet.xls")));
workbook.close();
}
五、把读取excel中的数据到程序中
@Test
public void testTwo() throws IOException {
HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream("E:/sheet.xls"));
HSSFSheet sheet = workbook.getSheetAt(0);
int lastRowNum = sheet.getLastRowNum();//查询一共有多少行
for (int i = 0; i <= lastRowNum; i++) {
HSSFRow row = sheet.getRow(i);
for (int j = 0; j < row.getLastCellNum(); j++) {//求列有多少数据是从一开始
System.out.println(row.getCell(j).getStringCellValue());
}
}
}
工具累的抽取
因为cell.getXxxVlaue只能获取相同的类型数据
public abstract class MyUtil {
public static void print(HSSFRow row, int i) {
HSSFCell cell = row.getCell(i);
if (CellType.STRING.equals(cell.getCellType())) {
System.out.println(cell.getStringCellValue());
} else if (CellType.BLANK.equals(cell.getCellType())) {
System.out.println("");
} else if (CellType.BOOLEAN.equals(cell.getCellType())) {
System.out.println(cell.getBooleanCellValue());
} else if (CellType.NUMERIC.equals(cell.getCellType())) {
System.out.println(cell.getNumericCellValue());
}
}
}
六、在Web环境下使用
- 上传
//使用ajax发送请求
function importSave() {
//要把file的文件数据封装到FormData对象中
let formData = new FormData();
formData.append("file", $('#uploadFile')[0].files[0]);
$.ajax({
url: '/permission/importSave',
type: 'post',
processData: false,
contentType: false,
data: formData,
success: function (data) {
if (data.success) {
window.location.reload();
} else {
Swal.fire({
text: "失败!",
icon: 'warning',
})
}
}
})
//控制层
@ResponseBody
@RequestMapping("/importSave")
public JsonResult importSave(MultipartFile file) throws IOException {
permissionService.importSave(file);
return new JsonResult(true,"成功");
}
//业务层
@Override
public void importSave(MultipartFile file) throws IOException {
XSSFWorkbook workbook = new XSSFWorkbook(file.getInputStream());
List<String> expressions = permissionMapper.selectAllExpression();
XSSFSheet sheet = workbook.getSheetAt(0);
int lastRowNum = sheet.getLastRowNum();
for (int i = 0; i < lastRowNum; i++) {
//除去标题,所以从i + 1行开始
XSSFRow row = sheet.getRow(i + 1);
String name = row.getCell(0).getStringCellValue();
String expression = row.getCell(1).getStringCellValue();
if (expressions.contains(expression)) {
//重复就跳过
continue;
}
permissionMapper.insert(new Permission(null, name, expression));
}
}
- 下载
//使用javacript发送请求
function exportOP() {
window.location="/permission/exportOP";
}
//数据请求,把数据响应到浏览器
@RequestMapping("/exportOP")
public String exportOP(HttpServletResponse response) throws IOException {
//设置下载头
response.setHeader("Content-Disposition", "attachment;filename=test.XLSX");
Workbook workbook = permissionService.exportOP();
workbook.write(response.getOutputStream());
return null;
}
//业务层
@Override
public Workbook exportOP() {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("sheet");
Row row = sheet.createRow(0);
row.createCell(0).setCellValue("名字");
row.createCell(1).setCellValue("表达式");
List<Permission> permissionList = permissionMapper.selectAll();
//把集合中的数据封装到workbook对象中
for (int i = 0; i < permissionList.size(); i++) {
Permission permission = permissionList.get(i);
Row r = sheet.createRow(i + 1);
r.createCell(0).setCellValue(permission.getName());
r.createCell(1).setCellValue(permission.getExpression());
}
return workbook;
}
Row r = sheet.createRow(i + 1);
r.createCell(0).setCellValue(permission.getName());
r.createCell(1).setCellValue(permission.getExpression());
}
return workbook;
}