Springboot如何上传excel存入数据
发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,这篇文章主要介绍Springboot如何上传excel存入数据,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、导入依赖这里还是用了Apache的POI插件,现在一般的spri
千家信息网最后更新 2025年02月01日Springboot如何上传excel存入数据三、页面效果
四、可能会遇到的问题
这篇文章主要介绍Springboot如何上传excel存入数据,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
一、导入依赖
这里还是用了Apache的POI插件,现在一般的springboot解析excel基本都用它 。
org.apache.poi poi-ooxml 5.0.0 org.apache.poi poi 5.0.0
二、前端实现
/** * 文件上传--批量导入 */ layui.use('upload', function () { var upload = layui.upload; var layer = layui.layer; // layer.msg('上传中', {icon: 16, time: 0,shade: 0.3}); //执行实例 var uploadInst = upload.render({ elem: '#bookFileUpload', //绑定元素 url: '/library/book/batchAddBooks/', //上传接口 exts: 'xlsx|xls', //限制文件类型 done: function (res) { //上传完毕回调 if (res.code == '1') { successMsg("导入成功"); } else { errorMsg("导入失败" + res); } }, error: function (res) { //请求异常回调 errorMsg("系统异常" + res); } }); });
说明一下,这里还是用了layui的框架去实现的,layui是我用过的前端框架里边坑相对较少的一个不错的简单并且很容易入门的框架。
三、后台逻辑
1.首先写一个用于导入数据的model实体类,对应数据库的一张表。
/** * 书籍实体 */@Datapublic class Book { //主键id private int bid; //书名 private String bookname; //作者 private String author; //书的类型 武侠、言情等 private String booktype; //出版社 private String publisher; //出版时间 private String publicationdate; //发行价格 private int price; //发行状态 private String bookstate; //备注 private String comment;}
这里使用了lombok的插件工具,所以可以省去写setget方法,只需要@Data即可。
lombok的依赖,可用可不用,看你自己:
org.projectlombok lombok true
2.接着写一下前端上传过来excel,后台的解析处理逻辑。
下面是重点:
package com.example.library.utils.fileUtiles;import com.example.library.model.Book;import org.apache.poi.hssf.usermodel.HSSFWorkbook;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.apache.poi.xssf.streaming.SXSSFWorkbook;import org.apache.poi.xssf.usermodel.XSSFWorkbook;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.multipart.MultipartFile;import java.io.*;import java.text.DecimalFormat;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.List;/** * @Author Summer_DM * @Summary TODO 操作Excel的工具类 * @Version 1.0 * @Date 2021/9/16 下午 03:44 **/public class ExcelUtils { private static final Logger logger = LoggerFactory.getLogger(ExcelUtils.class); //Mapmap = new HashMap (); private static final String XLS = "xls"; private static final String XLSX = "xlsx"; private final static String DATE_FORMAT = "yyyy-MM-dd"; /** * 根据文件后缀名类型获取对应的工作簿对象 * @param inputStream 读取文件的输入流 * @param fileType 文件后缀名类型(xls或xlsx) * @return 包含文件数据的工作簿对象 * @throws IOException */ public static Workbook getWorkbook(InputStream inputStream, String fileType) throws Exception { Workbook workbook = null; //根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象 if (fileType.equalsIgnoreCase(XLS)) { //2003 workbook = new HSSFWorkbook(inputStream); } else if (fileType.equalsIgnoreCase(XLSX)) { //2007及以上 workbook = new XSSFWorkbook(inputStream); }else { throw new Exception("请上传excel文件!"); } return workbook; } /** * 读取Excel文件内容 * @param fileName 要读取的Excel文件所在路径 * @return 读取结果列表,读取失败时返回null */ public static List readExcel(String fileName) { Workbook workbook = null; FileInputStream inputStream = null; try { // 获取Excel后缀名 String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()); // 获取Excel文件 File excelFile = new File(fileName); if (!excelFile.exists()) { logger.warn("指定的Excel文件不存在!"); } // 获取Excel工作簿 inputStream = new FileInputStream(excelFile); workbook = getWorkbook(inputStream, fileType); // 读取excel中的数据 List resultDataList = parseExcel(workbook); return resultDataList; } catch (Exception e) { logger.warn("解析Excel失败,文件名:" + fileName + " 错误信息:" + e.getMessage()); return null; } finally { try { if (null != workbook) { workbook.close(); } if (null != inputStream) { inputStream.close(); } } catch (Exception e) { logger.warn("关闭数据流出错!错误信息:" + e.getMessage()); return null; } } } /** * 读取Excel文件内容 * @param file 上传的Excel文件 * @return 读取结果列表,读取失败时返回null */ public static List readExcel(MultipartFile file) { Workbook workbook = null; try { //判断文件是否存在 if(null == file){ logger.warn("解析Excel失败,文件不存在!"); return null; } // 获取Excel后缀名 String fileName = file.getOriginalFilename(); if (fileName == null || fileName.isEmpty() || fileName.lastIndexOf(".") < 0) { logger.warn("解析Excel失败,因为获取到的Excel文件名非法!"); return null; } String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()); // 获取Excel工作簿 workbook = getWorkbook(file.getInputStream(), fileType); // 读取excel中的数据 List resultDataList = parseExcel(workbook); return resultDataList; } catch (Exception e) { logger.warn("解析Excel失败,文件名:" + file.getOriginalFilename() + " 错误信息:" + e.getMessage()); return null; } finally { try { if (null != workbook) { workbook.close(); } } catch (Exception e) { logger.warn("关闭数据流出错!错误信息:" + e.getMessage()); return null; } } } /** * 解析Excel数据 * @param workbook Excel工作簿对象 * @return 解析结果 */ private static List parseExcel(Workbook workbook) { List resultDataList = new ArrayList<>(); //获取所有的工作表的的数量 int numOfSheet = workbook.getNumberOfSheets(); System.out.println(numOfSheet+"--->numOfSheet"); // 解析sheet,此处会读取所有脚页的行数据,若只想读取指定页,不要for循环,直接给sheetNum赋值, // 脚页从0开始(通常情况Excel都只有一页,所以此处未进行进一步处理) for (int sheetNum = 0; sheetNum < numOfSheet; sheetNum++) { //获取一个sheet也就是一个工作本。 Sheet sheet = workbook.getSheetAt(sheetNum); // 校验sheet是否合法 if (sheet == null) { continue; } //获取一个sheet有多少Row //int lastRowNum = sheet.getLastRowNum(); //if(lastRowNum == 0) { // continue; //} // 获取第一行数据 int firstRowNum = sheet.getFirstRowNum(); Row firstRow = sheet.getRow(firstRowNum); if (null == firstRow) { logger.warn("解析Excel失败,在第一行没有读取到任何数据!"); } // 解析每一行的数据,构造数据对象 int rowStart = firstRowNum + 1; //获取第几行 //获得当前行的列数 int rowEnd = sheet.getPhysicalNumberOfRows(); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { Row row = sheet.getRow(rowNum); if (null == row) { continue; } Book resultData = convertRowToData(row); if (null == resultData) { logger.warn("第 " + row.getRowNum() + "行数据不合法,已忽略!"); continue; } resultDataList.add(resultData); } } return resultDataList; } /** * 将单元格内容转换为字符串 * @param cell * @return */ private static String convertCellValueToString(Cell cell) { String returnValue = null; if(cell==null){ return returnValue; } //如果当前单元格内容为日期类型,需要特殊处理 String dataFormatString = cell.getCellStyle().getDataFormatString(); if(dataFormatString.equals("m/d/yy")){ returnValue = new SimpleDateFormat(DATE_FORMAT).format(cell.getDateCellValue()); return returnValue; } switch (cell.getCellType()) { case NUMERIC: //数字 Double doubleValue = cell.getNumericCellValue(); // 格式化科学计数法,取一位整数 DecimalFormat df = new DecimalFormat("0"); returnValue = df.format(doubleValue); break; case STRING: //字符串 returnValue = cell.getStringCellValue(); break; case BOOLEAN: //布尔 Boolean booleanValue = cell.getBooleanCellValue(); returnValue = booleanValue.toString(); break; case BLANK: // 空值 break; case FORMULA: // 公式 returnValue = cell.getCellFormula(); break; case ERROR: // 故障 break; default: break; } return returnValue; } /** * 提取每一行中需要的数据,构造成为一个结果数据对象 *将excel的内容赋给实体类model * 当该行中有单元格的数据为空或不合法时,忽略该行的数据 * * @param row 行数据 * @return 解析后的行数据对象,行数据错误时返回null */ private static Book convertRowToData(Row row) { Book resultData = new Book(); Cell cell; int cellNum = 0; //获取书籍名称 cell = row.getCell(cellNum++); String bookName = convertCellValueToString(cell); if (null == bookName || "".equals(bookName)) { // 书籍名称为空 resultData.setBookname(bookName); } else { resultData.setBookname(bookName); } // 获取书籍作者 cell = row.getCell(cellNum++); String author = convertCellValueToString(cell); if (null == author || "".equals(author)) { // 书籍作者为空 resultData.setAuthor(author); } else { resultData.setAuthor(author); } // 获取书籍类型 cell = row.getCell(cellNum++); String type = convertCellValueToString(cell); if (null == type || "".equals(type)) { // 书籍类型为空 resultData.setBooktype(type); } else { resultData.setBooktype(type); } //获取出版单位 cell = row.getCell(cellNum++); String publisher = convertCellValueToString(cell); if (null == publisher || "".equals(publisher)) { // 出版单位为空 resultData.setPublisher(publisher); } else { resultData.setPublisher(publisher); } //获取出版时间 cell = row.getCell(cellNum++); String publicationdate = convertCellValueToString(cell); if (null == publicationdate || "".equals(publicationdate)) { // 出版时间为空 resultData.setPublicationdate(publicationdate); } else { resultData.setPublicationdate(publicationdate); } //获取价格 cell = row.getCell(cellNum++); String price = convertCellValueToString(cell); if (null == price || "".equals(price)) { // 价格为空 resultData.setPrice(Integer.parseInt(price)); } else { resultData.setPrice(Integer.parseInt(price)); } //获取借阅状态 cell = row.getCell(cellNum++); String bookstate = convertCellValueToString(cell); if (null == bookstate || "".equals(bookstate)) { // 借阅状态为空 resultData.setBookstate(bookstate); } else { resultData.setBookstate(bookstate); } //获取备注 cell = row.getCell(cellNum++); String comment = convertCellValueToString(cell); if (null == comment || "".equals(comment)) { // 备注为空 resultData.setComment(comment); } else { resultData.setComment(comment); } return resultData; } /** * 生成Excel文件 * @param outputStream */ public void writeExcel(OutputStream outputStream){ /** * 这个outputstream可以来自与文件的输出流, * 也可以直接输出到response的getOutputStream()里面 * 然后用户就可以直接解析到你生产的excel文件了 */ Workbook wb = new SXSSFWorkbook(100); //创建一个工作本 Sheet sheet = wb.createSheet("sheet"); //通过一个sheet创建一个Row Row row = sheet.createRow(0); for(int i =0;i<10;i++){ //通过row创建一个cell Cell cell = row.createCell(i); cell.setCellValue("这是第"+i+"个cell"); } try { wb.write(outputStream); wb.close(); }catch (IOException e){ e.printStackTrace(); } }}
3.最后写一下解析完成,存入数据库。
insert into user(username,sex,tel,institute,profession,classname,stuid,password,type) values ( #{item.username,jdbcType=VARCHAR}, #{item.sex,jdbcType=VARCHAR}, #{item.tel,jdbcType=VARCHAR}, #{item.institute,jdbcType=VARCHAR}, #{item.profession,jdbcType=VARCHAR}, #{item.classname,jdbcType=VARCHAR}, #{item.stuid,jdbcType=VARCHAR}, #{item.password,jdbcType=VARCHAR}, #{item.type,jdbcType=VARCHAR} )
三、页面效果
点击导入用户,选择excel文件即可。
四、可能会遇到的问题
因为springboot现在使用的poi的支持已经达到5.0以上版本了,但是他整合起来可能会出现一些小异常,虽然不影响我们正常使用,但是控制台会一直出现,也很烦,所以这里 给一个解决办法。
/** * @Author Summer_DM * @Summary TODO 专门用来处理SpringBoot应用集成poi 5.0.0启动报错java.io.FileNotFoundException, * TODO 因为使用poi 5.0.0解析excel,会有一些找不到jar包的问题,但是去maven仓库查看发现jar包都在,所以可以不必理会 * TODO java.io.FileNotFoundException: E:\software\apache\maven\maven-repository\library_repo\org\apache\xmlgraphics\batik-ttf2svg\1.13\lib\batik-i18n-1.13.jar (系统找不到指定的路径。) * @Version 1.0 * @Date 2021/9/18 下午 09:29 **/@Configurationpublic class MyStandardJarScanner { @Bean public TomcatServletWebServerFactory tomcatFactory() { return new TomcatServletWebServerFactory() { @Override protected void postProcessContext(Context context) { ((StandardJarScanner) context.getJarScanner()).setScanManifest(false); } }; }}
以上是"Springboot如何上传excel存入数据"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!
数据
文件
工作
书籍
对象
类型
出版
内容
后缀
错误
一行
信息
结果
处理
价格
作者
前端
单元
备注
实体
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
江苏大型软件开发销售厂家
同一数据库字段映射
谷村新司视频软件开发
杭州佳飞网络技术有限公司电话
耐药card数据库
3000g流量的服务器好不好
浪潮软件开发有限公司
合发上海网络技术有限公司
港口行业价格数据库
新乡市尚嘉网络技术有限公司
软件开发公司建筑结构
苹果软件开发商电话
软件开发需求分析流程
南京银行软件开发待遇 贴吧
服务器crts什么意思
石台新能源软件开发服务参考价格
群星启动器无法连接服务器
博兴机械软件开发服务
手机+应用开发+数据库
pi 数据库 odbc
软件开发后收益
打印机服务器不亮
医院his管理服务器
我的世界手机外部服务器是什么
mysql数据库入门实操教程
软件开发企业 增值税
曲靖昧谏网络技术有限公司
无锡java软件开发培训
长安路网络安全
软件开发也属于实体