导入所需坐标
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
所需方法
/**
* @author cd
* @param entityClass excel中每一行数据的实体类
* @param in excel文件
* @param fields 字段名字 需要注意的是这个方法中的map中: excel表格中每一列名为键,每一列对应的实体类的英文名为值
* @throws Exception
*/
public static <T> List<T> ExcelToList(InputStream in, Class<T> entityClass, Map<String, String> fields)
工具类代码
package com.imed.mts.order.core.api.util;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.merge.LoopMergeStrategy;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
public class ExcelUtil {
/**
* 用户信息导出类
* @param response 响应
* @param fileName 文件名
* @param columnList 每列的标题名
* @param dataList 导出的数据
*/
public static void exportExcel(HttpServletResponse response, String fileName, List<String> columnList, List<List<String>> dataList){
//声明输出流
OutputStream os = null;
//设置响应头
setResponseHeader(response,fileName);
try {
//获取输出流
os = response.getOutputStream();
//内存中保留1000条数据,以免内存溢出,其余写入硬盘
SXSSFWorkbook wb = new SXSSFWorkbook(1000);
//获取该工作区的第一个sheet
Sheet sheet1 = wb.createSheet("sheet1");
int excelRow = 0;
//创建标题行
Row titleRow = sheet1.createRow(excelRow++);
for(int i = 0;i<columnList.size();i++){
//创建该行下的每一列,并写入标题数据
Cell cell = titleRow.createCell(i);
cell.setCellValue(columnList.get(i));
}
//设置内容行
if(dataList!=null && dataList.size()>0){
//序号是从1开始的
int count = 1;
//外层for循环创建行
for(int i = 0;i<dataList.size();i++){
Row dataRow = sheet1.createRow(excelRow++);
//内层for循环创建每行对应的列,并赋值
for(int j = -1;j<dataList.get(0).size();j++){//由于多了一列序号列所以内层循环从-1开始
Cell cell = dataRow.createCell(j+1);
if(j==-1){//第一列是序号列,不是在数据库中读取的数据,因此手动递增赋值
cell.setCellValue(count++);
}else{//其余列是数据列,将数据库中读取到的数据依次赋值
cell.setCellValue(dataList.get(i).get(j));
}
}
}
}
//将整理好的excel数据写入流中
wb.write(os);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 关闭输出流
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
设置浏览器下载响应头
*/
private static void setResponseHeader(HttpServletResponse response, String fileName) {
try {
try {
fileName = new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
response.setContentType("application/octet-stream;charset=UTF-8");
// response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename="+ fileName);
response.addHeader("Pargam", "no-cache");
response.addHeader("Cache-Control", "no-cache");
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* @author cd
* @param entityClass excel中每一行数据的实体类
* @param in excel文件
* @param fields 字段名字 需要注意的是这个方法中的map中: excel表格中每一列名为键,每一列对应的实体类的英文名为值
* @throws Exception
*/
public static <T> List<T> ExcelToList(InputStream in, Class<T> entityClass, Map<String, String> fields)
throws Exception {
List<T> resultList = new ArrayList<T>();
XSSFWorkbook workbook = new XSSFWorkbook(in);
// excel中字段的中英文名字数组
String[] egtitles = new String[fields.size()];
String[] cntitles = new String[fields.size()];
Iterator<String> it = fields.keySet().iterator();
int count = 0;
while (it.hasNext()) {
String cntitle = (String) it.next();
String egtitle = fields.get(cntitle);
egtitles[count] = egtitle;
cntitles[count] = cntitle;
count++;
}
// 得到excel中sheet总数
int sheetcount = workbook.getNumberOfSheets();
if (sheetcount == 0) {
workbook.close();
throw new Exception("Excel文件中没有任何数据");
}
// 数据的导出
for (int i = 0; i < sheetcount; i++) {
Sheet sheet = workbook.getSheetAt(i);
if (sheet == null) {
continue;
}
// 每页中的第一行为标题行,对标题行的特殊处理
Row firstRow = sheet.getRow(0);
int celllength = firstRow.getLastCellNum();
String[] excelFieldNames = new String[celllength];
LinkedHashMap<String, Integer> colMap = new LinkedHashMap<String, Integer>();
// 获取Excel中的列名
for (int f = 0; f < celllength; f++) {
Cell cell = firstRow.getCell(f);
excelFieldNames[f] = cell.getStringCellValue().trim();
// 将列名和列号放入Map中,这样通过列名就可以拿到列号
for (int g = 0; g < excelFieldNames.length; g++) {
colMap.put(excelFieldNames[g], g);
}
}
// 由于数组是根据长度创建的,所以值是空值,这里对列名map做了去空键的处理
colMap.remove(null);
// 判断需要的字段在Excel中是否都存在
// 需要注意的是这个方法中的map中:中文名为键,英文名为值
boolean isExist = true;
List<String> excelFieldList = Arrays.asList(excelFieldNames);
for (String cnName : fields.keySet()) {
if (!excelFieldList.contains(cnName)) {
isExist = false;
break;
}
}
// 如果有列名不存在,则抛出异常,提示错误
if (!isExist) {
workbook.close();
throw new Exception("Excel中缺少必要的字段,或字段名称有误");
}
String endName = "default";
// 将sheet转换为list
for (int j = 1; j <= sheet.getLastRowNum(); j++) {
boolean flag = false;
String enNormalName = "";
String content = "";
Row row = sheet.getRow(j);
// 根据泛型创建实体类
T entity = entityClass.newInstance();
// 给对象中的字段赋值
for (Map.Entry<String, String> entry : fields.entrySet()) {
// 获取中文字段名
String cnNormalName = entry.getKey();
// 获取英文字段名
enNormalName = entry.getValue();
// 根据中文字段名获取列号
int col = colMap.get(cnNormalName);
// 获取当前单元格中的内容
content = "";
if (row.getCell(col) != null){
if(StringUtils.isNotBlank(row.getCell(col).toString())){
flag = true;
}
content = row.getCell(col).toString().trim();
}
if(enNormalName.equals("name") && content.equals("")){
endName = "";
break;
}
// 给对象赋值
setFieldValueByName(enNormalName, content, entity);
}
if(!endName.equals("") && flag){
resultList.add(entity);
}
}
}
workbook.close();
return resultList;
}
/**
* @MethodName : setFieldValueByName
* @Description : 根据字段名给对象的字段赋值
* @param fieldName
* 字段名
* @param fieldValue
* 字段值
* @param o
* 对象
*/
private static void setFieldValueByName(String fieldName, Object fieldValue, Object o) throws Exception {
Field field = getFieldByName(fieldName, o.getClass());
if (field != null) {
field.setAccessible(true);
// 获取字段类型
Class<?> fieldType = field.getType();
// 根据字段类型给字段赋值
if (String.class == fieldType) {
field.set(o, fieldValue);
} else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) {
if(!fieldValue.equals("")){
field.set(o, Integer.parseInt(fieldValue.toString()));
}
}
// else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) {
// field.set(o, Long.valueOf(fieldValue.toString()));
// }
else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) {
field.set(o, Float.valueOf(fieldValue.toString()));
} else if ((Short.TYPE == fieldType) || (Short.class == fieldType)) {
field.set(o, Short.valueOf(fieldValue.toString()));
} else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) {
field.set(o, Double.valueOf(fieldValue.toString()));
} else if (Character.TYPE == fieldType) {
if ((fieldValue != null) && (fieldValue.toString().length() > 0)) {
field.set(o, Character.valueOf(fieldValue.toString().charAt(0)));
}
} else if (Date.class == fieldType) {
field.set(o, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(fieldValue.toString()));
} else {
field.set(o, fieldValue);
}
} else {
throw new Exception(o.getClass().getSimpleName() + "类不存在字段名 " + fieldName);
}
}
/**
* @MethodName : getFieldByName
* @Description : 根据字段名获取字段
* @param fieldName
* 字段名
* @param clazz
* 包含该字段的类
* @return 字段
*/
private static Field getFieldByName(String fieldName, Class<?> clazz) {
// 拿到本类的所有字段
Field[] selfFields = clazz.getDeclaredFields();
// 如果本类中存在该字段,则返回
for (Field field : selfFields) {
if (field.getName().equals(fieldName)) {
return field;
}
}
// 否则,查看父类中是否存在此字段,如果有则返回
Class<?> superClazz = clazz.getSuperclass();
if (superClazz != null && superClazz != Object.class) {
return getFieldByName(fieldName, superClazz);
}
// 如果本类和父类都没有,则返回空
return null;
}
public static void exportTempleExcel(HttpServletResponse response, String fileName, List<String> columnList, List<List<String>> dataList){
//声明输出流
OutputStream os = null;
//设置响应头
setResponseHeader(response,fileName);
try {
//获取输出流
os = response.getOutputStream();
//内存中保留1000条数据,以免内存溢出,其余写入硬盘
SXSSFWorkbook wb = new SXSSFWorkbook(1000);
//获取该工作区的第一个sheet
SXSSFSheet sheet1 = wb.createSheet("sheet1");
sheet1.trackAllColumnsForAutoSizing();
// sheet1.setDefaultColumnWidth(25);
int excelRow = 0;
//创建标题行
Row titleRow = sheet1.createRow(excelRow++);
for(int i = 0;i<columnList.size();i++){
//创建该行下的每一列,并写入标题数据
Cell cell = titleRow.createCell(i);
cell.setCellValue(columnList.get(i));
sheet1.autoSizeColumn(i);
sheet1.setColumnWidth(i,sheet1.getColumnWidth(i)*17/10);
}
//设置内容行
if(dataList!=null && dataList.size()>0){
//外层for循环创建行
for(int i = 0;i<dataList.size();i++){
Row dataRow = sheet1.createRow(excelRow++);
//内层for循环创建每行对应的列,并赋值
for(int j = 0;j<dataList.get(i).size();j++){
// cell.setCellStyle(getDataFont(wb));
if (dataList.get(i).size()>j) {
Cell cell = dataRow.createCell(j);
cell.setCellValue(dataList.get(i).get(j));
sheet1.autoSizeColumn(j);
sheet1.setColumnWidth(j, sheet1.getColumnWidth(j) * 17 / 10);
}
}
}
}
//将整理好的excel数据写入流中
wb.write(os);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 关闭输出流
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void exportNoNumberExcel(HttpServletResponse response, String fileName, List<String> columnList, List<List<String>> dataList){
//声明输出流
OutputStream os = null;
//设置响应头
setResponseHeader(response,fileName);
try {
//获取输出流
os = response.getOutputStream();
//内存中保留1000条数据,以免内存溢出,其余写入硬盘
SXSSFWorkbook wb = new SXSSFWorkbook(1000);
//获取该工作区的第一个sheet
Sheet sheet1 = wb.createSheet("sheet1");
int excelRow = 0;
//创建标题行
Row titleRow = sheet1.createRow(excelRow++);
for(int i = 0;i<columnList.size();i++){
//创建该行下的每一列,并写入标题数据
Cell cell = titleRow.createCell(i);
cell.setCellValue(columnList.get(i));
}
//设置内容行
if(dataList!=null && dataList.size()>0){
//外层for循环创建行
for(int i = 0;i<dataList.size();i++){
Row dataRow = sheet1.createRow(excelRow++);
//内层for循环创建每行对应的列,并赋值
for(int j = 0;j<dataList.get(0).size();j++){
Cell cell = dataRow.createCell(j);
cell.setCellValue(dataList.get(i).get(j));
}
}
}
//将整理好的excel数据写入流中
wb.write(os);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 关闭输出流
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}