POI提供API给Java程序对Microsoft Office格式档案读和写的功能。比较常见的是对excel的操作。
Springboot+用poi实现Excel的导入导出
1、Excel导入,即读取Excel内容存入数据库或其他地方。此处我仅仅将其Excel内容读取后,打印到控制台。
2、Excel导出,即通过将对象生成Excel表返回给用户。
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poiartifactId>
<version>3.17version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>3.17version>
dependency>
package com.haibo.base.service;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
public interface PoiService {
/**
* 上传/导入
* @param file
* @return
*/
ResponseEntity fileUpload(MultipartFile file);
/**
* 下载/导出
* @param response
*/
void downLoadExcel(HttpServletResponse response);
}
提供一个假数据源:
package com.haibo.base.dao;
import com.haibo.base.entity.Teacher;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* @author:haibo.xiong
* @date:2019/5/7
* @description:
*/
@Component
public class PoiDaoImpl implements PoiDao{
@Override
public List<Teacher> getTeachers() {
List<Teacher> classmateList= new ArrayList<>();
classmateList.add(new Teacher("1","张三","1","123456"));
classmateList.add(new Teacher("2","李四","1","123456"));
classmateList.add(new Teacher("3","王五","2","123456"));
classmateList.add(new Teacher("4","赵六","2","123456"));
classmateList.add(new Teacher("5","周八","3","123456"));
return classmateList;
}
}
提供service功能:
package com.haibo.base.service.impl;
import com.haibo.base.dao.PoiDao;
import com.haibo.base.entity.Teacher;
import com.haibo.base.utils.Utils;
import com.haibo.base.service.PoiService;
import org.apache.poi.hssf.usermodel.*;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
* @author:haibo.xiong
* @date:2019/5/5
* @description:
*/
@Service
public class PoiServiceImpl implements PoiService{
@Override
public ResponseEntity fileUpload(MultipartFile file) {
if (!Utils.checkExtension(file)){
return new ResponseEntity("请求文件类型错误:后缀名错误",HttpStatus.BAD_REQUEST);
}
try {
if (Utils.isOfficeFile(file)){
//正确的文件类型 自动判断2003或者2007
Workbook workbook = Utils.getWorkbookAuto(file);
Sheet sheet = workbook.getSheetAt(0);//默认只有一个sheet
int rows = sheet.getPhysicalNumberOfRows();//获得sheet有多少行
//读第一个sheet
for (int i = 0;i<rows;i++){
Row row = sheet.getRow(i);
for (int j=0;j<row.getLastCellNum();j++){
Cell cell = row.getCell(j);
if (cell!=null)
System.out.println(cell.toString());
}
}
}else {
return new ResponseEntity("请求文件类型错误:文件类型错误",HttpStatus.BAD_REQUEST);
}
} catch (IOException e) {
e.printStackTrace();
}
return new ResponseEntity(HttpStatus.OK);
}
@Autowired
private PoiDao poiDao;
@Override
public void downLoadExcel(HttpServletResponse response) {
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("信息表");
List<Teacher> classmateList = poiDao.getTeachers();
String fileName = "userinf" + ".xls";//设置要导出的文件的名字
//新增数据行,并且设置单元格数据
int rowNum = 1;
String[] headers = { "学号", "姓名", "身份类型", "登录密码"};
//headers表示excel表中第一行的表头
HSSFRow row = sheet.createRow(0);
//在excel表中添加表头
for(int i=0;i<headers.length;i++){
HSSFCell cell = row.createCell(i);
HSSFRichTextString text = new HSSFRichTextString(headers[i]);
cell.setCellValue(text);
}
//在表中存放查询到的数据放入对应的列
for (Teacher teacher : classmateList) {
HSSFRow row1 = sheet.createRow(rowNum);
row1.createCell(0).setCellValue(teacher.getTno());
row1.createCell(1).setCellValue(teacher.getTname());
row1.createCell(2).setCellValue(teacher.getType());
row1.createCell(3).setCellValue(teacher.getTpassword());
rowNum++;
}
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition", "attachment;filename=" + fileName);
try {
response.flushBuffer();
workbook.write(response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
}
工具类通过魔数判断是否上传文件为Office文件。
package com.haibo.base.utils;
import com.google.common.collect.Lists;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.FileMagic;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.Objects;
/**
* @author:haibo.xiong
* @date:2019/5/5
* @description:
*/
public class Utils {
/**
* 判断是否office文件
* @param inputStream
* @return
*/
public static Boolean isOfficeFile(InputStream inputStream){
boolean result = false;
try {
FileMagic fileMagic = FileMagic.valueOf(inputStream);
if (Objects.equals(fileMagic,FileMagic.OLE2)||Objects.equals(fileMagic,fileMagic.OOXML)){
result = true;
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 判断是否office文件
* @param file
* @return
* @throws IOException
*/
public static Boolean isOfficeFile(MultipartFile file) throws IOException {
BufferedInputStream bufferedInputStream = new BufferedInputStream(file.getInputStream());
boolean result = false;
result = isOfficeFile(bufferedInputStream);
return result;
}
/**
* 判断扩展名是否是excel扩展名
* @param extension
* @return
*/
public static Boolean checkExtension(String extension){
return Lists.newArrayList("xls","xlsx","XLS","XLSX").contains(extension);
}
/**
* 判断扩展名是否是excel扩展名
* @param file
* @return
*/
public static Boolean checkExtension(MultipartFile file){
String fileName = file.getOriginalFilename();
String extension = fileName.substring(fileName.lastIndexOf(".")+1);
return checkExtension(extension);
}
/**
* 自动判断文件类型
* @param file
* @return
* @throws IOException
*/
public static Workbook getWorkbookAuto(MultipartFile file) throws IOException {
/** 判断文件的类型,是2003还是2007 */
boolean isExcel2003 = true;
if (isExcel2007(file.getOriginalFilename())) {
isExcel2003 = false;
}
BufferedInputStream is = new BufferedInputStream(
file.getInputStream());
Workbook wb;
if (isExcel2003) {
wb = new HSSFWorkbook(is);
} else {
wb = new XSSFWorkbook(is);
}
return wb;
}
public static boolean isExcel2003(String filePath) {
return filePath.matches("^.+\\.(?i)(xls)$");
}
public static boolean isExcel2007(String filePath) {
return filePath.matches("^.+\\.(?i)(xlsx)$");
}
}
@Autowired
private PoiService poiService;
@RequestMapping(value = "/fileUpload",method = RequestMethod.POST,
consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<Object> fileUpload(@RequestParam("file")MultipartFile file, HttpServletRequest request){
System.out.println(LoginController.class.getResource("").getPath());
return poiService.fileUpload(file);
}
@RequestMapping(value = "downLoadExcel", method = RequestMethod.GET)
public void downLoadExcel(HttpServletResponse response){
poiService.downLoadExcel(response);
}