提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 表格导入导出实现效果展示
    • 根据实体类导出模板
    • 读取表格数据
    • 导出数据为excel
    • 进阶:修改表格导出的列头
  • controller示例
  • 工具类
  • 测试实体
  • 实体注解
  • maven依赖

表格导入导出实现效果展示

根据实体类导出模板

所有对excel都是根据实体类进行操作

根据实体导出的excel模板展示

读取表格数据

读取结果返回,和表格上传数据一致

导出数据为excel

也支持将已有的数据导出为表格

进阶:修改表格导出的列头

部分情况,表头需要为中文,可以使用注解,对表格进行标注,导出的模板和导出的数据列头就是注解的内容了

controller示例

一下示例代码实现了表格模板导出、数据导出、数据读取和百万数据读取

package com.mabo.controller;import com.alibaba.fastjson.JSONArray;
import com.mabo.entity.ChatInfo;
import com.mabo.util.ExcelHSSFUtil;
import com.monitorjbl.xlsx.StreamingReader;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.IOUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.io.File;
/*** TODO your comment** @author Yujiaqi* @date 2020/12/2 19:20*/
@Slf4j
@RestController
@RequestMapping("/excel")
public class ExcelController {/*** 读取excel*/@PostMapping("/upload")public Object upload(MultipartHttpServletRequest file) throws Exception {MultipartFile file1 = file.getFile("file");byte[] bytes = IOUtils.toByteArray(file1.getInputStream());File excelFile = new File("test1.xlsx");FileOutputStream fos = new FileOutputStream(excelFile);fos.write(bytes);fos.close();JSONArray  jsonArray = ExcelHSSFUtil.readXlsxExcel(ChatInfo.class, excelFile);return jsonArray;}/*** 下载excel模板*/@GetMapping("/download")public void download(HttpServletResponse response) throws Exception {String fileName="downloadModel.xlsx";fileName = URLEncoder.encode(fileName,"UTF-8");File file=new File(fileName);file = ExcelHSSFUtil.createXlsxExcel(ChatInfo.class, new ArrayList<>(), file.getAbsolutePath());// 以流的形式下载文件。InputStream fis = null;try {fis = new BufferedInputStream(new FileInputStream(file.getAbsoluteFile()));} catch (FileNotFoundException e) {e.printStackTrace();}byte[] buffer = new byte[fis.available()];fis.read(buffer);fis.close();// 清空responseresponse.reset();// 设置response的Headerresponse.addHeader("Content-Disposition", "attachment;filename=" + new String(file.getName().getBytes()));response.addHeader("Content-Length", "" + file.length());OutputStream toClient = new BufferedOutputStream(response.getOutputStream());response.setContentType("application/octet-stream;charset=utf-8");toClient.write(buffer);toClient.flush();toClient.close();}/*** 超大数据量上传* @param file* @return* @throws Exception*/@PostMapping("/uploadBatch")public Object uploadBatch(MultipartHttpServletRequest file) throws Exception {MultipartFile file1 = file.getFile("file");byte[] bytes = IOUtils.toByteArray(file1.getInputStream());File excelFile = new File("test1.xlsx");FileOutputStream fos = new FileOutputStream(excelFile);fos.write(bytes);fos.close();InputStream inputStream1 = new FileInputStream(excelFile);JSONArray jsonArray = null;Workbook work= StreamingReader.builder().rowCacheSize(100)  //缓存到内存中的行数,默认是10.bufferSize(4096)  //读取资源时,缓存到内存的字节大小,默认是1024.open(inputStream1);Sheet sheet = work.getSheetAt(0);//得到第一个sheetint excelSize = sheet.getLastRowNum();int max =3;if (excelSize < max) {jsonArray = ExcelHSSFUtil.readXlsxExcel(ChatInfo.class, excelFile);System.out.println(jsonArray);}else {//大数据进行多线程处理,并且直接返回数据int size=max;for (int i = 1; i < excelSize; ) {log.info("当前为第" + i);jsonArray = ExcelHSSFUtil.readXlsxExcelCache(ChatInfo.class, excelFile, i, size);System.out.println(jsonArray);i+=max;if (i+max>excelSize){jsonArray = ExcelHSSFUtil.readXlsxExcelCache(ChatInfo.class, excelFile,i,excelSize-i);System.out.println(jsonArray);}}}return jsonArray;}/*** 下载excel批量数据*/@GetMapping("/downloadBatch")public void downloadBatch(HttpServletResponse response) throws Exception {String fileName="downloadBatch.xlsx";fileName = URLEncoder.encode(fileName,"UTF-8");File file=new File(fileName);List list = new ArrayList<>();ChatInfo chatInfo = new ChatInfo();chatInfo.setMsg("1");chatInfo.setId("1");//写入业务数据list.add(chatInfo);list.add(chatInfo);list.add(chatInfo);file = ExcelHSSFUtil.createXlsxExcel(ChatInfo.class, list, file.getAbsolutePath());// 以流的形式下载文件。InputStream fis = null;try {fis = new BufferedInputStream(new FileInputStream(file.getAbsoluteFile()));} catch (FileNotFoundException e) {e.printStackTrace();}byte[] buffer = new byte[fis.available()];fis.read(buffer);fis.close();// 清空responseresponse.reset();// 设置response的Headerresponse.addHeader("Content-Disposition", "attachment;filename=" + new String(file.getName().getBytes()));response.addHeader("Content-Length", "" + file.length());OutputStream toClient = new BufferedOutputStream(response.getOutputStream());response.setContentType("application/octet-stream;charset=utf-8");toClient.write(buffer);toClient.flush();toClient.close();}}

工具类

package com.mabo.util;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mabo.annotation.ExcelField;
import com.monitorjbl.xlsx.StreamingReader;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;@Slf4j
public class ExcelHSSFUtil<T> {//日期支持以下以下格式private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");private static SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");private static SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy.MM.dd");private static SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy年MM月dd日");public static <T> File create(Class<T> aClass, List<T> list, String fileName) throws IOException {// 创建一个webbook,对应一个Excel文件HSSFWorkbook wb = new HSSFWorkbook();HSSFCellStyle textType = wb.createCellStyle();HSSFCellStyle dateType = wb.createCellStyle();HSSFDataFormat format = wb.createDataFormat();textType.setDataFormat(format.getFormat("@"));dateType.setDataFormat(format.getFormat("yyyy年m月d日"));// 在webbook中添加一个sheet,对应Excel文件中的sheetHSSFSheet sheet = wb.createSheet("sheet1");// 在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制shortHSSFRow row = sheet.createRow(0);// 添加标题行HSSFCell cell = null;Field[] fields = aClass.getDeclaredFields();List<Field> excelField = new ArrayList<>();int excelNo = 0;for (int i = 0; i < fields.length; i++) {ExcelField annotation = fields[i].getAnnotation(ExcelField.class);if (annotation != null) {if (annotation.ignore() == true) {continue;} else {excelField.add(fields[i]);// 获取行内对应单元格cell = row.createCell(excelNo++);// 单元格赋值String value = annotation.value();if (value.equals("")) {cell.setCellValue(fields[i].getName());} else {cell.setCellValue(value);}}} else {cell = row.createCell(excelNo++);cell.setCellValue(fields[i].getName());}}// 写入实体数据,实际应用中这些数据从数据库得到,list中字符串的顺序必须和数组strArray中的顺序一致int i = 0;for (int j = 0; j < list.size(); j++) {T t = list.get(i);i++;row = sheet.createRow(i);// 添加数据行//数据转为JsonString json = JSON.toJSONString(t);//关键JSONObject parse = (JSONObject) JSONObject.parse(json);for (int z = 0; z < excelField.size(); z++) {Field field = excelField.get(z);ExcelField annotation = field.getAnnotation(ExcelField.class);boolean ignore = false;if (annotation != null) {ignore = annotation.ignore();}if (!ignore) {cell = row.createCell(z);cell.setCellStyle(textType);// 获取行内对应单元格String name = field.getName();Object o = parse.get(name);// 单元格赋值if (o instanceof Long) {long o1 = (long) o;Date date = null;SimpleDateFormat simpleDateFormat = null;try {date = new Date();date.setTime(o1);simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");cell.setCellValue(simpleDateFormat.format(date));} catch (Exception e) {e.printStackTrace();cell.setCellValue(o1);}} else if (o instanceof String) {cell.setCellValue((String) o);} else if (o instanceof Double) {cell.setCellValue((double) o);} else if (o instanceof Boolean) {cell.setCellValue((boolean) o);}}}}
//            // 第六步,将文件存到指定位置FileOutputStream fout = new FileOutputStream(fileName);try {wb.write(fout);fout.close();} catch (Exception e) {e.printStackTrace();} finally {fout.close();}return new File(fileName);}/*** @Description : 读取excel为实体集合* @Author : mabo*/public static <T> JSONArray readExcel(Class<T> aClass, File file) {JSONArray array = new JSONArray();try {FileInputStream fileInputStream = new FileInputStream(file.getAbsolutePath());HSSFWorkbook work = new HSSFWorkbook(fileInputStream);// 得到这个excel表格对象HSSFSheet sheet = work.getSheetAt(0); //得到第一个sheetint rowNo = sheet.getLastRowNum(); //得到行数//获取首行列头HSSFRow row = sheet.getRow(0);short lastCellNum = row.getLastCellNum();List<String> fieldNames = new ArrayList<>();for (int i = 0; i < lastCellNum; i++) {HSSFCell cell = row.getCell(i);if (cell != null) {String stringCellValue = cell.getStringCellValue();fieldNames.add(stringCellValue);}}JSONObject jsonField = getJsonField(aClass);for (int i = 1; i <= rowNo; i++) {row = sheet.getRow(i);JSONObject jsonObject = new JSONObject();for (int j = 0; j < fieldNames.size(); j++) {HSSFCell cell = row.getCell(j);if (cell != null) {Object value = null;CellType cellTypeEnum = cell.getCellTypeEnum();if (cellTypeEnum.equals(CellType.STRING)) {value = cell.getStringCellValue();
//                            try {//                                value = simpleDateFormat.parse(value.toString());
//                            } catch (ParseException e) {//                                try {//                                    value = sdf1.parse(value.toString());
//                                } catch (ParseException e1) {//                                    try {//                                        value = sdf2.parse(value.toString());
//                                    } catch (ParseException e2) {//                                        try {//                                            value = sdf3.parse(value.toString());
//                                        } catch (ParseException e3) {//                                        }
//                                    }
//                                }
//                            }} else if (cellTypeEnum.equals(CellType.NUMERIC)) {value = cell.getNumericCellValue();} else if (cellTypeEnum.equals(CellType.BOOLEAN)) {value = cell.getBooleanCellValue();}String string = jsonField.getString(fieldNames.get(j));jsonObject.put(string, value);}}array.add(jsonObject);}} catch (Exception e) {e.printStackTrace();}return array;}/*** @Description : 获取表格列头和实体的对应关系* @Author : mabo*/public static <T> JSONObject getJsonField(Class<T> aClass) {Field[] fields = aClass.getDeclaredFields();JSONObject js = new JSONObject();for (int i = 0; i < fields.length; i++) {ExcelField annotation = fields[i].getAnnotation(ExcelField.class);if (annotation != null) {if (annotation.ignore() == true) {continue;} else {if (!annotation.value().equals("")) {String value = annotation.value();js.put(value, fields[i].getName());} else {js.put(fields[i].getName(), fields[i].getName());}}} else {js.put(fields[i].getName(), fields[i].getName());}}return js;}/*** @Description : 生成xlsx格式表格文件,可上传的数据量更大*/public static <T> File createXlsxExcel(Class<T> aClass, List<T> list, String fileName) throws Exception {// 创建一个webbook,对应一个Excel文件
//        Workbook wb =  WorkbookFactory.create(new File(fileName));Workbook wb = new SXSSFWorkbook(3000);CellStyle textType = wb.createCellStyle();CellStyle dateType = wb.createCellStyle();DataFormat dataFormat = wb.createDataFormat();textType.setDataFormat(dataFormat.getFormat("@"));dateType.setDataFormat(dataFormat.getFormat("yyyy年m月d日"));// 在webbook中添加一个sheet,对应Excel文件中的sheetSheet sheet = wb.createSheet("sheet1");// 在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制shortRow row = sheet.createRow(0);// 添加标题行Cell cell = null;Field[] fields = aClass.getDeclaredFields();List<Field> excelField = new ArrayList<>();int excelNo = 0;for (int i = 0; i < fields.length; i++) {ExcelField annotation = fields[i].getAnnotation(ExcelField.class);if (annotation != null) {if (annotation.ignore() == true) {continue;} else {excelField.add(fields[i]);// 获取行内对应单元格cell = row.createCell(excelNo++);// 单元格赋值String value = annotation.value();if (value.equals("")) {cell.setCellValue(fields[i].getName());} else {cell.setCellValue(value);}}} else {excelField.add(fields[i]);cell = row.createCell(excelNo++);cell.setCellValue(fields[i].getName());}}// 写入实体数据,实际应用中这些数据从数据库得到,list中字符串的顺序必须和数组strArray中的顺序一致int i = 0;for (int j = 0; j < list.size(); j++) {T t = list.get(i);i++;row = sheet.createRow(i);// 添加数据行//数据转为JsonString json = JSON.toJSONString(t);//关键JSONObject parse = (JSONObject) JSONObject.parse(json);for (int z = 0; z < excelField.size(); z++) {Field field = excelField.get(z);ExcelField annotation = field.getAnnotation(ExcelField.class);boolean ignore = false;if (annotation != null) {ignore = annotation.ignore();}if (!ignore) {cell = row.createCell(z);cell.setCellStyle(textType);// 获取行内对应单元格String name = field.getName();Object o = parse.get(name);// 单元格赋值if (o instanceof Long) {long o1 = (long) o;Date date = null;SimpleDateFormat simpleDateFormat = null;try {date = new Date();date.setTime(o1);simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");cell.setCellValue(simpleDateFormat.format(date));} catch (Exception e) {e.printStackTrace();cell.setCellValue(o1);}} else if (o instanceof String) {cell.setCellValue((String) o);} else if (o instanceof Double) {cell.setCellValue((double) o);} else if (o instanceof Boolean) {cell.setCellValue((boolean) o);}}}}
//            // 第六步,将文件存到指定位置FileOutputStream fout = new FileOutputStream(fileName);try {wb.write(fout);fout.close();} catch (Exception e) {e.printStackTrace();} finally {fout.close();}return new File(fileName);}public static <T> JSONArray readXlsxExcel(Class<T> aClass, File file) {JSONArray array = new JSONArray();try {Workbook work = new XSSFWorkbook(new FileInputStream(file.getAbsolutePath()));// 得到这个excel表格对象Sheet sheet = work.getSheetAt(0);//得到第一个sheetint rowNo = sheet.getLastRowNum(); //得到行数//获取首行列头Row row = sheet.getRow(0);short lastCellNum = row.getLastCellNum();List<String> fieldNames = new ArrayList<>();for (int i = 0; i < lastCellNum; i++) {Cell cell = row.getCell(i);if (cell != null) {String stringCellValue = cell.getStringCellValue();fieldNames.add(stringCellValue);}}JSONObject jsonField = getJsonField(aClass);for (int i = 1; i <= rowNo; i++) {row = sheet.getRow(i);JSONObject jsonObject = new JSONObject();for (int j = 0; j < fieldNames.size(); j++) {Cell cell = row.getCell(j);if (cell != null) {Object value = null;CellType cellTypeEnum = cell.getCellTypeEnum();if (cellTypeEnum.equals(CellType.STRING)) {value = cell.getStringCellValue();
//                            try {//                                value = simpleDateFormat.parse(value.toString());
//                            } catch (ParseException e) {//                                try {//                                    value = sdf1.parse(value.toString());
//                                } catch (ParseException e1) {//                                    try {//                                        value = sdf2.parse(value.toString());
//                                    } catch (ParseException e2) {//                                        try {//                                            value = sdf3.parse(value.toString());
//                                        } catch (ParseException e3) {//                                        }
//                                    }
//                                }
//                            }} else if (cellTypeEnum.equals(CellType.NUMERIC)) {value = cell.getNumericCellValue();} else if (cellTypeEnum.equals(CellType.BOOLEAN)) {value = cell.getBooleanCellValue();}String string = jsonField.getString(fieldNames.get(j));jsonObject.put(string, value);}}array.add(jsonObject);}} catch (Exception e) {e.printStackTrace();}return array;}public static <T> JSONArray readXlsxExcel(Class<T> aClass, File file, int start, int size) {JSONArray array = new JSONArray();try {Workbook work = new XSSFWorkbook(new FileInputStream(file.getAbsolutePath()));// 得到这个excel表格对象Sheet sheet = work.getSheetAt(0);//得到第一个sheetint rowNo = sheet.getLastRowNum(); //得到行数if (rowNo > start + size) {rowNo = start + size;}//获取首行列头Row row = sheet.getRow(0);short lastCellNum = row.getLastCellNum();List<String> fieldNames = new ArrayList<>();for (int i = 0; i < lastCellNum; i++) {Cell cell = row.getCell(i);if (cell != null) {String stringCellValue = cell.getStringCellValue();fieldNames.add(stringCellValue);}}JSONObject jsonField = getJsonField(aClass);//从数据行开始start++;for (int i = start; i <= rowNo; i++) {row = sheet.getRow(i);JSONObject jsonObject = new JSONObject();for (int j = 0; j < fieldNames.size(); j++) {Cell cell = row.getCell(j);if (cell != null) {Object value = null;CellType cellTypeEnum = cell.getCellTypeEnum();if (cellTypeEnum.equals(CellType.STRING)) {value = cell.getStringCellValue();
//                            try {//                                value = simpleDateFormat.parse(value.toString());
//                            } catch (ParseException e) {//                                try {//                                    value = sdf1.parse(value.toString());
//                                } catch (ParseException e1) {//                                    try {//                                        value = sdf2.parse(value.toString());
//                                    } catch (ParseException e2) {//                                        try {//                                            value = sdf3.parse(value.toString());
//                                        } catch (ParseException e3) {//                                        }
//                                    }
//                                }
//                            }} else if (cellTypeEnum.equals(CellType.NUMERIC)) {value = cell.getNumericCellValue();} else if (cellTypeEnum.equals(CellType.BOOLEAN)) {value = cell.getBooleanCellValue();}String string = jsonField.getString(fieldNames.get(j));jsonObject.put(string, value);}}array.add(jsonObject);}} catch (Exception e) {e.printStackTrace();}return array;}public static <T> JSONArray readXlsxExcelCache(Class<T> aClass, File file, int start, int size) throws FileNotFoundException {InputStream inputStream1 = new FileInputStream(file);Workbook work = StreamingReader.builder().rowCacheSize(100)  //缓存到内存中的行数,默认是10.bufferSize(4096)  //读取资源时,缓存到内存的字节大小,默认是1024.open(inputStream1);Sheet sheet = work.getSheetAt(0);//得到第一个sheetint excelSize = sheet.getLastRowNum();//大数据进行多线程处理,并且直接返回数据log.info("当前数据量大小为" + excelSize);List<String> fieldNames = new ArrayList<>();JSONArray array = new JSONArray();JSONObject jsonField = ExcelHSSFUtil.getJsonField(aClass);for (Row row : sheet) {if (row.getRowNum() == 0) {short lastCellNum = row.getLastCellNum();for (int i = 0; i < lastCellNum; i++) {Cell cell = row.getCell(i);if (cell != null) {String stringCellValue = cell.getStringCellValue();fieldNames.add(stringCellValue);}}}int maxSize = start + size;if (row.getRowNum() >= start && row.getRowNum()<maxSize) { //从设定的行开始取值//对当前行逐列进行循环取值JSONObject jsonObject = new JSONObject();for (int j = 0; j < fieldNames.size(); j++) {Cell cell = row.getCell(j);if (cell != null) {Object value = null;CellType cellTypeEnum = cell.getCellTypeEnum();if (cellTypeEnum.equals(CellType.STRING)) {value = cell.getStringCellValue();
//                            try {//                                value = simpleDateFormat.parse(value.toString());
//                            } catch (ParseException e) {//                                try {//                                    value = sdf1.parse(value.toString());
//                                } catch (ParseException e1) {//                                    try {//                                        value = sdf2.parse(value.toString());
//                                    } catch (ParseException e2) {//                                        try {//                                            value = sdf3.parse(value.toString());
//                                        } catch (ParseException e3) {//                                        }
//                                    }
//                                }
//                            }} else if (cellTypeEnum.equals(CellType.NUMERIC)) {value = cell.getNumericCellValue();} else if (cellTypeEnum.equals(CellType.BOOLEAN)) {value = cell.getBooleanCellValue();}String string = jsonField.getString(fieldNames.get(j));jsonObject.put(string, value);}}array.add(jsonObject);}if (row.getRowNum()>maxSize){break;}}return array;}public static int getExcelSize(File file) throws IOException {//        Workbook work = new XSSFWorkbook(new FileInputStream(file.getAbsolutePath()));// 得到这个excel表格对象
//        Sheet sheet = work.getSheetAt(0);//得到第一个sheet
//        return  sheet.getLastRowNum(); //得到行数InputStream inputStream1 = new FileInputStream(file);Workbook work= StreamingReader.builder().rowCacheSize(100)  //缓存到内存中的行数,默认是10.bufferSize(4096)  //读取资源时,缓存到内存的字节大小,默认是1024.open(inputStream1);Sheet sheet = work.getSheetAt(0);//得到第一个sheetint excelSize = sheet.getLastRowNum();return excelSize;}/*** @Description : 生成xlsx格式表格文件,可上传的数据量更大*/public static <T> File createXlsxExcelCache(Class<T> aClass, List<T> list, String fileName,int startRow) throws Exception {// 创建一个webbook,对应一个Excel文件
//        File file = new File(fileName);
//        XSSFWorkbook tplWorkBook = new XSSFWorkbook(new FileInputStream(file));Workbook wb = new SXSSFWorkbook( 3000);
//
//        InputStream inputStream1 = new FileInputStream(file);
//        Workbook wb =   new XSSFWorkbook(inputStream1);
//        wb = new SXSSFWorkbook(wb,3000);CellStyle textType = wb.createCellStyle();CellStyle dateType = wb.createCellStyle();DataFormat dataFormat = wb.createDataFormat();textType.setDataFormat(dataFormat.getFormat("@"));dateType.setDataFormat(dataFormat.getFormat("yyyy年m月d日"));// 在webbook中添加一个sheet,对应Excel文件中的sheetSheet sheet = wb.createSheet("sheet1");// 在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制shortList<Field> excelField = new ArrayList<>();Row row =null;Cell cell = null;if (startRow==0){row = sheet.createRow(0);// 添加标题行Field[] fields = aClass.getDeclaredFields();int excelNo = 0;for (int i = 0; i < fields.length; i++) {ExcelField annotation = fields[i].getAnnotation(ExcelField.class);if (annotation != null) {if (annotation.ignore() == true) {continue;} else {excelField.add(fields[i]);// 获取行内对应单元格cell = row.createCell(excelNo++);// 单元格赋值String value = annotation.value();if (value.equals("")) {cell.setCellValue(fields[i].getName());} else {cell.setCellValue(value);}}} else {excelField.add(fields[i]);cell = row.createCell(excelNo++);cell.setCellValue(fields[i].getName());}}}else {// 不添加标题行,只获取数Field[] fields = aClass.getDeclaredFields();int excelNo = 0;for (int i = 0; i < fields.length; i++) {ExcelField annotation = fields[i].getAnnotation(ExcelField.class);if (annotation != null) {if (annotation.ignore() == true) {continue;} else {excelField.add(fields[i]);}} else {excelField.add(fields[i]);}}}// 写入实体数据,实际应用中这些数据从数据库得到,list中字符串的顺序必须和数组strArray中的顺序一致int i = startRow;for (int j = 0; j < list.size(); j++) {T t = list.get(j);i++;row = sheet.createRow(i);// 添加数据行//数据转为JsonString json = JSON.toJSONString(t);//关键JSONObject parse = (JSONObject) JSONObject.parse(json);for (int z = 0; z < excelField.size(); z++) {Field field = excelField.get(z);ExcelField annotation = field.getAnnotation(ExcelField.class);boolean ignore = false;if (annotation != null) {ignore = annotation.ignore();}if (!ignore) {cell = row.createCell(z);cell.setCellStyle(textType);// 获取行内对应单元格String name = field.getName();Object o = parse.get(name);// 单元格赋值if (o instanceof Long) {long o1 = (long) o;Date date = null;SimpleDateFormat simpleDateFormat = null;try {date = new Date();date.setTime(o1);simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");cell.setCellValue(simpleDateFormat.format(date));} catch (Exception e) {e.printStackTrace();cell.setCellValue(o1);}} else if (o instanceof String) {cell.setCellValue((String) o);} else if (o instanceof Double) {cell.setCellValue((double) o);} else if (o instanceof Boolean) {cell.setCellValue((boolean) o);}}}}
//            // 第六步,将文件存到指定位置FileOutputStream fout = new FileOutputStream(fileName);try {wb.write(fout);fout.close();} catch (Exception e) {e.printStackTrace();} finally {fout.close();}return new File(fileName);}public static <T> File appendExcelDataWithCache(Class<T> aClass, List<T> list, String fileName,int startRow) throws Exception {FileInputStream input = new FileInputStream(fileName);XSSFWorkbook xssfWorkbook = new XSSFWorkbook(input);//构建SXSSF,设置模板和内存保留行数Workbook   wb = new SXSSFWorkbook(xssfWorkbook,100);// 创建一个webbook,对应一个Excel文件Workbook wb = new SXSSFWorkbook( xssfWorkbook,3000);CellStyle textType = wb.createCellStyle();CellStyle dateType = wb.createCellStyle();DataFormat dataFormat = wb.createDataFormat();textType.setDataFormat(dataFormat.getFormat("@"));dateType.setDataFormat(dataFormat.getFormat("yyyy年m月d日"));// 在webbook中添加一个sheet,对应Excel文件中的sheetSheet sheet = wb.getSheet("sheet1");if (sheet==null){sheet= wb.createSheet("sheet1");}// 在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制shortList<Field> excelField = new ArrayList<>();Row row =null;Cell cell = null;if (startRow==0){row = sheet.createRow(0);// 添加标题行Field[] fields = aClass.getDeclaredFields();int excelNo = 0;for (int i = 0; i < fields.length; i++) {ExcelField annotation = fields[i].getAnnotation(ExcelField.class);if (annotation != null) {if (annotation.ignore() == true) {continue;} else {excelField.add(fields[i]);// 获取行内对应单元格cell = row.createCell(excelNo++);// 单元格赋值String value = annotation.value();if (value.equals("")) {cell.setCellValue(fields[i].getName());} else {cell.setCellValue(value);}}} else {excelField.add(fields[i]);cell = row.createCell(excelNo++);cell.setCellValue(fields[i].getName());}}}else {// 不添加标题行,只获取数Field[] fields = aClass.getDeclaredFields();int excelNo = 0;for (int i = 0; i < fields.length; i++) {ExcelField annotation = fields[i].getAnnotation(ExcelField.class);if (annotation != null) {if (annotation.ignore() == true) {continue;} else {excelField.add(fields[i]);}} else {excelField.add(fields[i]);}}}// 写入实体数据,实际应用中这些数据从数据库得到,list中字符串的顺序必须和数组strArray中的顺序一致int i = startRow;for (int j = 0; j < list.size(); j++) {T t = list.get(j);i++;row = sheet.createRow(i);// 添加数据行//数据转为JsonString json = JSON.toJSONString(t);//关键JSONObject parse = (JSONObject) JSONObject.parse(json);for (int z = 0; z < excelField.size(); z++) {Field field = excelField.get(z);ExcelField annotation = field.getAnnotation(ExcelField.class);boolean ignore = false;if (annotation != null) {ignore = annotation.ignore();}if (!ignore) {cell = row.createCell(z);cell.setCellStyle(textType);// 获取行内对应单元格String name = field.getName();Object o = parse.get(name);// 单元格赋值if (o instanceof Long) {long o1 = (long) o;Date date = null;SimpleDateFormat simpleDateFormat = null;try {date = new Date();date.setTime(o1);simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");cell.setCellValue(simpleDateFormat.format(date));} catch (Exception e) {e.printStackTrace();cell.setCellValue(o1);}} else if (o instanceof String) {cell.setCellValue((String) o);} else if (o instanceof Double) {cell.setCellValue((double) o);} else if (o instanceof Boolean) {cell.setCellValue((boolean) o);}}}}
//            // 第六步,将文件存到指定位置FileOutputStream fout = new FileOutputStream(fileName);try {wb.write(fout);fout.close();} catch (Exception e) {e.printStackTrace();} finally {fout.close();}return new File(fileName);}/*** @Description : 向excel中追加数据,不影响原来数据* @Author : mabo*/public static <T> Workbook appendExcelDataWithCache( Workbook wb,Class<T> aClass, List<T> list,int startRow) throws Exception {CellStyle textType = wb.createCellStyle();CellStyle dateType = wb.createCellStyle();DataFormat dataFormat = wb.createDataFormat();textType.setDataFormat(dataFormat.getFormat("@"));dateType.setDataFormat(dataFormat.getFormat("yyyy年m月d日"));// 在webbook中添加一个sheet,对应Excel文件中的sheetSheet sheet = wb.getSheet("sheet1");if (sheet==null){sheet= wb.createSheet("sheet1");}// 在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制shortList<Field> excelField = new ArrayList<>();Row row =null;Cell cell = null;if (startRow==0){row = sheet.createRow(0);// 添加标题行Field[] fields = aClass.getDeclaredFields();int excelNo = 0;for (int i = 0; i < fields.length; i++) {ExcelField annotation = fields[i].getAnnotation(ExcelField.class);if (annotation != null) {if (annotation.ignore() == true) {continue;} else {excelField.add(fields[i]);// 获取行内对应单元格cell = row.createCell(excelNo++);// 单元格赋值String value = annotation.value();if (value.equals("")) {cell.setCellValue(fields[i].getName());} else {cell.setCellValue(value);}}} else {excelField.add(fields[i]);cell = row.createCell(excelNo++);cell.setCellValue(fields[i].getName());}}}else {// 不添加标题行,只获取数Field[] fields = aClass.getDeclaredFields();int excelNo = 0;for (int i = 0; i < fields.length; i++) {ExcelField annotation = fields[i].getAnnotation(ExcelField.class);if (annotation != null) {if (annotation.ignore() == true) {continue;} else {excelField.add(fields[i]);}} else {excelField.add(fields[i]);}}}// 写入实体数据,实际应用中这些数据从数据库得到,list中字符串的顺序必须和数组strArray中的顺序一致int i = startRow;for (int j = 0; j < list.size(); j++) {T t = list.get(j);i++;row = sheet.createRow(i);// 添加数据行//数据转为JsonString json = JSON.toJSONString(t);//关键JSONObject parse = (JSONObject) JSONObject.parse(json);for (int z = 0; z < excelField.size(); z++) {Field field = excelField.get(z);ExcelField annotation = field.getAnnotation(ExcelField.class);boolean ignore = false;if (annotation != null) {ignore = annotation.ignore();}if (!ignore) {cell = row.createCell(z);cell.setCellStyle(textType);// 获取行内对应单元格String name = field.getName();Object o = parse.get(name);// 单元格赋值if (o instanceof Long) {long o1 = (long) o;Date date = null;SimpleDateFormat simpleDateFormat = null;try {date = new Date();date.setTime(o1);simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");cell.setCellValue(simpleDateFormat.format(date));} catch (Exception e) {e.printStackTrace();cell.setCellValue(o1);}} else if (o instanceof String) {cell.setCellValue((String) o);} else if (o instanceof Double) {cell.setCellValue((double) o);} else if (o instanceof Boolean) {cell.setCellValue((boolean) o);}}}}return wb;}
}

测试实体

package com.mabo.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.mabo.annotation.ExcelField;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.Serializable;
import java.util.Date;/*** (ChatInfo)实体类** @author makejava* @since 2022-08-01 16:18:08*/
@Data
public class ChatInfo implements Serializable {/*** 主键*/@ExcelField("主键id")private String id;/*** 消息*/@ExcelField("消息")private String msg;}

实体注解

package com.mabo.annotation;import java.lang.annotation.*;@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelField {String value() default "";boolean ignore() default false;
}

maven依赖

<dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.3.22</version></dependency><!-- 07版本以后的格式 .xlsx --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.17</version></dependency><!-- 读取大量excel数据时使用 --><dependency><groupId>com.monitorjbl</groupId><artifactId>xlsx-streamer</artifactId><version>2.1.0</version></dependency>

根据实体excel导入导出百万数据,可修改表头名称相关推荐

  1. Excel导入导出百万级数据

    Excel百万级数据导入导出方案 本文使用EasyExcel工作,导出格式XLSX 1.生成测试数据 这里用到的是MYSQL 5.7.31 创建表语句 CREATE TABLE `ACT_RESULT ...

  2. PHP 导入导出excel、csv百万数据到数据库

    PHP 导入导出excel.csv百万数据到数据库 待解决: wamp下导入导出百万数据没有问题 lnmp下导入10W条数据没问题,导入50W及以上会出现nginx504报错 代码包地址 测试数据表地 ...

  3. Java操作百万数据量Excel导入导出工具类(程序代码教程)

    Java操作百万数据量Excel导入导出工具类(程序代码教程): # 功能实现1.自定义导入数据格式,支持配置时间.小数点类型(支持单/多sheet)(2种方式:本地文件路径导入(只支持xls.xls ...

  4. Excel怎么导出百万级数据

    以前很久没碰到导出上10万数据到Excel.最近两年的业务有导出几十万数据的场景.Excel导出之前一直用NPOI导出的,NPOI的优势是不依赖Office环境.但是早期的NPOI导出操作Excel全 ...

  5. Java操作大数据量Excel导入导出万能工具类(完整版)

    Java操作大数据量Excel导入导出万能工具类(完整版) 转载自:https://blog.csdn.net/JavaWebRookie/article/details/80843653 更新日志: ...

  6. 一个基于POI的通用excel导入导出工具类的简单实现及使用方法

    前言: 最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据.网上关于excel导入导出的例子很多,但大多相互借鉴. ...

  7. easyexcel 设置标题_EasyExcel,让 excel 导入导出更加简单

    做积极的人,而不是积极废人! 来源:jianshu.com/p/8f3defdc76d4EasyExcelGitHub上的官方说明快速开始maven仓库地址导入导出总结 EasyExcel 在做exc ...

  8. 一款Excel导入导出解决方案组成的轻量级开源组件

    Excel-Boot GitHub地址:gitee.com/nw1992/easy- 码云地址:github.com/programmere- Excel-Boot是一款Excel导入导出解决方案组成 ...

  9. easypoi导入校验跳过空行_Easy-POI是一款Excel导入导出解决方案组成的轻量级开源组件...

    Excel-Boot是一款Excel导入导出解决方案组成的轻量级开源组件. 如果喜欢或愿意使用, 请star本项目或者点击donate图标捐赠我们 如果是企业使用, 为了产品推广, 请通过评论.Iss ...

最新文章

  1. JAVA中常用的异常处理情况
  2. python中数字应该用什么表示_Python
  3. 指针数组,数组指针,函数指针,main函数实质,二重指针,函数指针作为參数,泛型函数...
  4. 平滑数据迁移,不影响服务
  5. shell 中的export作用(转载)
  6. java集合输入存储_Java练习IO流使用Properties集合存储数据并...
  7. [SAP ABAP开发技术总结]选择屏幕——各种屏幕元素演示
  8. iOS AnchorPoint 引起的坐标问题
  9. 上海浦东软件园入园企业
  10. IPv6 的速度比 IPv4 更快?
  11. ❤️工作半年前端的一些思考 | 共勉
  12. 学习spf记录引发的问题(一)
  13. 【教程】如何查看自己的外网ip是不是公网ip
  14. plc是微型计算机,plc控制系统与微型计算机系统有什么区别
  15. CSS3 制作 3D 水晶糖果按钮
  16. 简单好用的js 压缩工具
  17. 压缩软件Bandizip
  18. 基于java的俄罗斯方块小游戏设计(含源文件)
  19. 校园网、CMCC自动登录
  20. brew install gpg

热门文章

  1. 大数据分析技术之JAVA基础(一):数据类型
  2. 全球与中国高档装饰灯具市场深度研究分析报告(2021)
  3. MAX3485芯片软件使用总结
  4. LibRTMP源代码分析2:解释RTMP地址
  5. Kitty猫 vs. 百度狗,区块链动物大战,谁将下一个入局?
  6. 幼儿园开学教学课件PPT模板
  7. 【android免root脚本制作】总览Auto.js开发小结——基础篇
  8. ubunto命令大全
  9. 盐酸雷宁替丁(胃泛酸)
  10. 【oracle存储过程】实现生成等额本息的还款计划