SpringBoot怎么实现导入导出Excel文档
发表于:2025-11-13 作者:千家信息网编辑
千家信息网最后更新 2025年11月13日,这篇文章主要介绍了SpringBoot怎么实现导入导出Excel文档的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇SpringBoot怎么实现导入导出Excel文档文章都
千家信息网最后更新 2025年11月13日SpringBoot怎么实现导入导出Excel文档
这篇文章主要介绍了SpringBoot怎么实现导入导出Excel文档的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇SpringBoot怎么实现导入导出Excel文档文章都会有所收获,下面我们一起来看看吧。
一、添加poi的maven依赖
org.apache.poi poi 3.13 org.apache.poi poi-ooxml 3.13 二、自定义注解(Excel属性标题、位置等)
package com.cloud.core.annotation;import java.lang.annotation.*;/** * 自定义实体类所需要的bean(Excel属性标题、位置等) * Copyright: Copyright (C) 2021 DLANGEL, Inc. All rights reserved. * Company: 大连安琪科技有限公司 * * @author Rex * @since 2021/5/19 9:30 */@Target({ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface ExcelColumn { /** * Excel标题 * * @return * @author Rex */ String value() default ""; /** * Excel从左往右排列位置,第一个是0 * * @return * @author Rex */ int col() default 0;}三、CustomExcelUtils编写
package com.cloud.core.utils;import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;import com.cloud.core.annotation.ExcelColumn;import com.cloud.core.common.CommonConst;import org.apache.commons.lang.BooleanUtils;import org.apache.commons.lang.CharUtils;import org.apache.commons.lang.StringUtils;import org.apache.commons.lang.math.NumberUtils;import org.apache.poi.hssf.usermodel.HSSFDateUtil;import org.apache.poi.hssf.usermodel.HSSFWorkbook;import org.apache.poi.ss.usermodel.*;import org.apache.poi.xssf.usermodel.XSSFWorkbook;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.http.MediaType;import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletResponse;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.math.BigDecimal;import java.net.URLEncoder;import java.util.*;import java.util.concurrent.atomic.AtomicInteger;import java.util.stream.Collectors;import java.util.stream.Stream;/** * 自定义导入导出Excel文件类 * Copyright: Copyright (C) 2021 DLANGEL, Inc. All rights reserved. * Company: 大连安琪科技有限公司 * * @author Rex * @since 2021/5/19 9:31 */public class CustomExcelUtils { private final static Logger log = LoggerFactory.getLogger(CustomExcelUtils.class); private final static String EXCEL2003 = "xls"; private final static String EXCEL2007 = "xlsx"; /** * 读取Excel * * @param path 为了测试文件用,实际为空 * @param cls 类 * @param startRow 起始行 * @param file 文件 * @return * @author Rex */ public static List readExcel(String path, Class cls, int startRow, MultipartFile file) { String fileName = file.getOriginalFilename(); if (!fileName.matches(CommonConst.Regex.FILE_EXT_XLS) && !fileName.matches(CommonConst.Regex.FILE_EXT_XLSX)) { log.error("上传文件格式不正确"); } List dataList = new ArrayList<>(); Workbook workbook = null; try { InputStream is = file.getInputStream(); if (fileName.endsWith(EXCEL2007)) {// FileInputStream is = new FileInputStream(new File(path)); workbook = new XSSFWorkbook(is); } if (fileName.endsWith(EXCEL2003)) {// FileInputStream is = new FileInputStream(new File(path)); workbook = new HSSFWorkbook(is); } if (workbook != null) { //类映射 注解 value-->bean columns Map> classMap = new HashMap<>(); List fields = Stream.of(cls.getDeclaredFields()).collect(Collectors.toList()); fields.forEach( field -> { ExcelColumn annotation = field.getAnnotation(ExcelColumn.class); if (annotation != null) { String value = annotation.value(); if (StringUtils.isBlank(value)) { // return起到的作用和continue是相同的 语法 return; } if (!classMap.containsKey(value)) { classMap.put(value, new ArrayList<>()); } field.setAccessible(true); classMap.get(value).add(field); } } ); //索引-->columns Map> reflectionMap = new HashMap<>(16); //默认读取第一个sheet Sheet sheet = workbook.getSheetAt(0); boolean firstRow = true; for (int i = startRow; i <= sheet.getLastRowNum(); i++) { Row row = sheet.getRow(i); // 提取注解 if (firstRow) { for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) { Cell cell = row.getCell(j); String cellValue = getCellValue(cell); if (classMap.containsKey(cellValue)) { reflectionMap.put(j, classMap.get(cellValue)); } } if (reflectionMap.size() > 0) { firstRow = false; } } else { //忽略空白行 if (row == null) { continue; } try { T t = cls.newInstance(); //判断是否为空白行 boolean allBlank = true; for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) { if (reflectionMap.containsKey(j)) { Cell cell = row.getCell(j); String cellValue = getCellValue(cell); if (StringUtils.isNotBlank(cellValue)) { allBlank = false; } List fieldList = reflectionMap.get(j); fieldList.forEach( x -> { try { handleField(t, cellValue, x); } catch (Exception e) { log.error(String.format("reflect field:%s value:%s exception!", x.getName(), cellValue), e); } } ); } } if (!allBlank) { dataList.add(t); } else { log.warn(String.format("row:%s is blank ignore!", i)); } } catch (Exception e) { log.error(String.format("parse row:%s exception!", i), e); } } } } } catch (Exception e) { log.error(String.format("parse excel exception!"), e); } finally { if (workbook != null) { try { workbook.close(); } catch (Exception e) { log.error(String.format("parse excel exception!"), e); } } } return dataList; } private static void handleField(T t, String value, Field field) throws Exception { Class> type = field.getType(); if (type == null || type == void.class || StringUtils.isBlank(value)) { return; } if (type == Object.class) { field.set(t, value); //数字类型 } else if (type.getSuperclass() == null || type.getSuperclass() == Number.class) { if (type == int.class || type == Integer.class) { field.set(t, NumberUtils.toInt(value)); } else if (type == long.class || type == Long.class) { field.set(t, NumberUtils.toLong(value)); } else if (type == byte.class || type == Byte.class) { field.set(t, NumberUtils.toByte(value)); } else if (type == short.class || type == Short.class) { field.set(t, NumberUtils.toShort(value)); } else if (type == double.class || type == Double.class) { field.set(t, NumberUtils.toDouble(value)); } else if (type == float.class || type == Float.class) { field.set(t, NumberUtils.toFloat(value)); } else if (type == char.class || type == Character.class) { field.set(t, CharUtils.toChar(value)); } else if (type == boolean.class) { field.set(t, BooleanUtils.toBoolean(value)); } else if (type == BigDecimal.class) { field.set(t, new BigDecimal(value)); } } else if (type == Boolean.class) { field.set(t, BooleanUtils.toBoolean(value)); } else if (type == Date.class) { // field.set(t, value); } else if (type == String.class) { field.set(t, value); } else { Constructor> constructor = type.getConstructor(String.class); field.set(t, constructor.newInstance(value)); } } private static String getCellValue(Cell cell) { if (cell == null) { return ""; } if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) { if (HSSFDateUtil.isCellDateFormatted(cell)) { return HSSFDateUtil.getJavaDate(cell.getNumericCellValue()).toString(); } else { return new BigDecimal(cell.getNumericCellValue()).toString(); } } else if (cell.getCellType() == Cell.CELL_TYPE_STRING) { return StringUtils.trimToEmpty(cell.getStringCellValue()); } else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) { return StringUtils.trimToEmpty(cell.getCellFormula()); } else if (cell.getCellType() == Cell.CELL_TYPE_BLANK) { return ""; } else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) { return String.valueOf(cell.getBooleanCellValue()); } else if (cell.getCellType() == Cell.CELL_TYPE_ERROR) { return "ERROR"; } else { return cell.toString().trim(); } } public static void writeExcel(HttpServletResponse response, List dataList, Class cls) { Field[] fields = cls.getDeclaredFields(); List fieldList = Arrays.stream(fields) .filter(field -> { ExcelColumn annotation = field.getAnnotation(ExcelColumn.class); if (annotation != null && annotation.col() > 0) { field.setAccessible(true); return true; } return false; }).sorted(Comparator.comparing(field -> { int col = 0; ExcelColumn annotation = field.getAnnotation(ExcelColumn.class); if (annotation != null) { col = annotation.col(); } return col; })).collect(Collectors.toList()); Workbook wb = new XSSFWorkbook(); Sheet sheet = wb.createSheet("Sheet1"); AtomicInteger ai = new AtomicInteger(); { Row row = sheet.createRow(ai.getAndIncrement()); AtomicInteger aj = new AtomicInteger(); //写入头部 fieldList.forEach(field -> { ExcelColumn annotation = field.getAnnotation(ExcelColumn.class); String columnName = ""; if (annotation != null) { columnName = annotation.value(); } Cell cell = row.createCell(aj.getAndIncrement()); CellStyle cellStyle = wb.createCellStyle(); cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex()); cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND); cellStyle.setAlignment(CellStyle.ALIGN_CENTER); Font font = wb.createFont(); font.setBoldweight(Font.BOLDWEIGHT_NORMAL); cellStyle.setFont(font); cell.setCellStyle(cellStyle); cell.setCellValue(columnName); }); } if (CollectionUtils.isNotEmpty(dataList)) { dataList.forEach(t -> { Row row1 = sheet.createRow(ai.getAndIncrement()); AtomicInteger aj = new AtomicInteger(); fieldList.forEach(field -> { Class> type = field.getType(); Object value = ""; try { value = field.get(t); } catch (Exception e) { e.printStackTrace(); } Cell cell = row1.createCell(aj.getAndIncrement()); if (value != null) { if (type == Date.class) { cell.setCellValue(value.toString()); } else { cell.setCellValue(value.toString()); } cell.setCellValue(value.toString()); } }); }); } //冻结窗格 wb.getSheet("Sheet1").createFreezePane(0, 1, 0, 1); //浏览器下载excel buildExcelDocument("导出数据.xlsx", wb, response); //生成excel文件// buildExcelFile(".\default.xlsx", wb); } /** * 浏览器下载excel * * @param fileName * @param wb * @param response */ private static void buildExcelDocument(String fileName, Workbook wb, HttpServletResponse response) { try { response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8")); response.flushBuffer(); wb.write(response.getOutputStream()); } catch (IOException e) { e.printStackTrace(); } } /** * 生成excel文件 * * @param path 生成excel路径 * @param wb */ private static void buildExcelFile(String path, Workbook wb) { File file = new File(path); if (file.exists()) { file.delete(); } try { wb.write(new FileOutputStream(file)); } catch (Exception e) { e.printStackTrace(); } }} 四、定义导出实体类
主要是使用这里的@ExcelColumn注解,其中的col从0开始的。
package com.cloud.library.model.role;import com.cloud.core.annotation.ExcelColumn;import lombok.Data;/** * 导入角色用 * Copyright: Copyright (C) 2021 DLANGEL, Inc. All rights reserved. * Company: 大连安琪科技有限公司 * * @author Rex * @since 2021/5/19 16:13 */@Datapublic class SysRoleExcel { @ExcelColumn(value = "姓名", col = 1) private String name; @ExcelColumn(value = "描述", col = 2) private String description;}五、Controller层代码编写
//region 导入数据 /** * 导入数据 * * @param file * @return * @author Rex */ @RequestMapping(value = "/readExcel", method = RequestMethod.POST) public void readExcel(@RequestParam(value = "uploadFile", required = false) MultipartFile file) { List list = CustomExcelUtils.readExcel("", SysRoleExcel.class, 0, file); List sysRoleList = new ArrayList<>(); list.forEach(e -> { SysRole sysRole = new SysRole(); BeanUtils.copyProperties(e, sysRole); sysRoleList.add(sysRole); }); sysRoleService.saveBatch(sysRoleList); } // endregion 这里发现了,这个saveBatch可以直接使用雪花的id来保存数据,因为这里用的是mybatis-plus,单条数据保存使用的是它的配置。然后试了下,批量导入也是可以的,另外,这个批量保存,理论上没有条数限制,这个还等待后续测试。
关于"SpringBoot怎么实现导入导出Excel文档"这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对"SpringBoot怎么实现导入导出Excel文档"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。
文件
数据
文档
注解
位置
公司
有限
有限公司
标题
知识
科技
大连
安琪
生成
内容
实体
属性
浏览器
空白
空白行
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
网络安全幼儿园大班教案ppt
天津 网络技术服务有限公司
mysql数据库主主热备
郑州大学软件开发是几本
云端大数据协调处理软件开发
牧原股份网络安全
战术目标指向网络技术
网络安全助理工程师的等级
网络安全第五章节
一个端口只能映射一个服务器
软件开发合作框架协议模板
枣庄戴尔服务器零售
软件开发费交增值税税率
机械设计数据库
小区网络安全员是干嘛的
农安智能化网络技术服务诚信合作
)数据库理论与技术
php数据库新建表
网络安全宣传周前期工作
数据库语句获取今天时间
广东省三顺互联网科技有限公司
黟县淮猫网络技术有限公司
网络技术中 最高数据率
实际生活中数据库技术应用的例子
如何管理软件开发绩效
服务器电源线粗细要求
网络技术小白
山东省网络安全协会
网络安全法 用户信息 制度
移动网络安全性是什么