SpringBoot自定義工具類實(shí)現(xiàn)Excel數(shù)據(jù)存入MySQL數(shù)據(jù)庫(kù)
前言
本文主要介紹使用EasyExcel讀取Excel內(nèi)數(shù)據(jù)并轉(zhuǎn)換為csv格式數(shù)據(jù)(String字符串),然后實(shí)現(xiàn)字符串分割,分割出屬性名和屬性值建表插入MySQL數(shù)據(jù)庫(kù)中。
一、EasyExcel轉(zhuǎn)CSV
使用EasyExcel讀取Excel文件,轉(zhuǎn)換為csv數(shù)據(jù),也就是轉(zhuǎn)化為一個(gè)字符串。
工具類:
/** * @Version: 1.0.0 * @Author: Dragon_王 * @ClassName: ExcelUtils * @Description: Excel相關(guān)工具類 * @Date: 2024/3/9 11:24 */ import cn.hutool.core.collection.CollUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.support.ExcelTypeEnum; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * Excel 相關(guān)工具類 */ @Slf4j public class ExcelUtils { /** * excel 轉(zhuǎn) csv * * @param multipartFile * @return */ public static String excelToCsv(MultipartFile multipartFile) { // 讀取數(shù)據(jù) List<Map<Integer, String>> list = null; try { list = EasyExcel.read(multipartFile.getInputStream()).excelType(ExcelTypeEnum.XLSX).sheet().headRowNumber(0).doReadSync(); } catch (IOException e) { log.error("表格處理錯(cuò)誤", e); } if (CollUtil.isEmpty(list)) { return ""; } // 轉(zhuǎn)換為 csv StringBuilder stringBuilder = new StringBuilder(); // 讀取表頭 LinkedHashMap<Integer, String> headerMap = (LinkedHashMap) list.get(0); List<String> headerList = headerMap.values().stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList()); stringBuilder.append(StringUtils.join(headerList, ",")).append("\n"); // 讀取數(shù)據(jù) for (int i = 1; i < list.size(); i++) { LinkedHashMap<Integer, String> dataMap = (LinkedHashMap) list.get(i); List<String> dataList = dataMap.values().stream().filter(ObjectUtils::isNotEmpty).collect(Collectors.toList()); stringBuilder.append(StringUtils.join(dataList, ",")).append("\n"); } return stringBuilder.toString(); } }
實(shí)際運(yùn)用中,只需要如下調(diào)用:
//傳入的是Excel文件,不是路徑哦 ExcelUtils.excelToCsv(Excel文件);
Excel文件格式如下:
讀取的數(shù)據(jù)如下格式(這里我用加號(hào)拼接更清晰,實(shí)際上就是一個(gè)包含換行符的字符串,并不包含+號(hào)):
"日期,閱讀量\n" +
"3,253\n" +
"4,408\n" +
"5,363\n" +
"6,955\n" +
"7,496\n" +
"8,1310\n" +
"9,748";
二、分割建表入庫(kù)
將獲取的csv數(shù)據(jù),其實(shí)這里就是一個(gè)String字符串,記住現(xiàn)在是字符串不是數(shù)組。
首先我們分析一下,如何從字符串從分割出屬性名(日期、閱讀量)以及插入表中的每行屬性值(3 253;4 408…):
- 找出第一個(gè)換行符(\n)的位置index,然后從第一位切割到index,這時(shí)候就得到屬性名的字符串。再以英文逗號(hào)為分割符進(jìn)行分割,得到屬性名數(shù)組。
- 從index切割到字符串最后的位置就是全部屬性值,那么如何分割得到每行的屬性值呢?同樣以換行符為分割符進(jìn)行分割得到每行屬性值的數(shù)組。(這里注意一下,數(shù)組中的每個(gè)元素是一個(gè)包含一行值的字符串,如:“3,253”)
- 分割得到的屬性值數(shù)組內(nèi)的每個(gè)元素再以英文逗號(hào)為分割符進(jìn)行分割得到每行屬性值,如"3"和"253"
- 最后根據(jù)屬性名和屬性值動(dòng)態(tài)構(gòu)建sql語(yǔ)句進(jìn)行創(chuàng)建表,插入值的操作。
分割csv數(shù)據(jù)并調(diào)用自定義建表和插入函數(shù):
//定義表名 String tableName = "test"; //獲取第一個(gè)換行符的索引 int index = csvData.indexOf("\n"); //分割出屬性名字符串,如"日期,閱讀量" String colum = csvData.substring(0,index); //得到屬性名數(shù)組,如{"日期","閱讀量"} String[] colums = colum.split(","); //得到全部屬性值字符串,如"3,253\n4,408\n5,363\n6,955\n7,496\n8,1310\n9,748" String data = csvData.substring(index).trim(); //得到全部屬性值數(shù)組,如:{"3,253","4,408","5,363""6,955".......} String[] split_data = data.split("\n"); //調(diào)用建表 tableCreationUtils.createTable(tableName,colums); //調(diào)用插入 tableCreationUtils.Dynamicinsert(tableName,colums,split_data);
動(dòng)態(tài)構(gòu)造建表sql和插入sql工具類:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; import javax.sql.DataSource; import java.sql.SQLException; /** * 構(gòu)建生成表sql * * @version 1.0.0 * @Author: dragon_王 * @Date: 2024/3/11 20:45:16 */ @Component public class TableCreationUtils { private final JdbcTemplate jdbcTemplate; @Autowired public TableCreationUtils(DataSource dataSource){ this.jdbcTemplate = new JdbcTemplate(dataSource); } /** * 動(dòng)態(tài)構(gòu)建創(chuàng)建表的sql語(yǔ)句并執(zhí)行 * * @param tableName 表名字符串 * @param columnNames 屬性名數(shù)組 * @return: void * @Date: 2024-03-13 23:23:36 */ public void createTable(String tableName, String[] columnNames) { String sql = "CREATE TABLE " + tableName + " ("; for (int i = 0; i < columnNames.length; i++) { sql += columnNames[i] + " VARCHAR(255)"; if (i < columnNames.length - 1) { sql += ", "; } } sql += ");"; jdbcTemplate.execute(sql); } /** * 動(dòng)態(tài)構(gòu)建插入sql語(yǔ)句并執(zhí)行 * * @param tableName 表名字符串 * @param columnName 屬性名數(shù)組,如{"日期","閱讀"} * @param rowData 屬性值數(shù)組,如{"3,253","4,408","5,363""6,955".......} * @return: void * @Date: 2024-03-13 23:24:09 */ public void Dynamicinsert(String tableName, String[] columnName,String[] rowData) throws SQLException { //屬性值為空就拋出異常 if (rowData == null || rowData.length == 0) { throw new IllegalArgumentException("Row data must not be null or empty"); } for (int i = 0;i < rowData.length;i++){ //傳進(jìn)來(lái)的是所有屬性值數(shù)組,如:{"3,253","4,408","5,363""6,955".......} //所以以將每個(gè)元素取出以英文逗號(hào)分割,得到插入的每行元素如["3","253"] String[] row = rowData[i].split(","); // 構(gòu)建占位符 StringBuilder columnNames = new StringBuilder(); StringBuilder placeholders = new StringBuilder(); for (int j = 0; j < row.length; j++) { if (j > 0) { columnNames.append(", "); placeholders.append(", "); } columnNames.append(columnName[j]); placeholders.append("?"); // 使用?作為PreparedStatement的占位符 } // 構(gòu)建完整的SQL語(yǔ)句 String sql = "INSERT INTO " + tableName + " (" + columnNames + ") VALUES (" + placeholders + ")"; // 使用JdbcTemplate執(zhí)行插入操作,如第一次循環(huán):insert into tablename (日期,閱讀) values (?,?) //row:["3","253"] jdbcTemplate.update(sql,row); } } }
上面代碼有以上面EXcel數(shù)據(jù)為例子的詳細(xì)講解,我就不再贅訴,很簡(jiǎn)單的思路。
以上就是SpringBoot自定義工具類實(shí)現(xiàn)Excel數(shù)據(jù)存入MySQL數(shù)據(jù)庫(kù)的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot Excel數(shù)據(jù)存入數(shù)據(jù)庫(kù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解Springboot如何優(yōu)雅的進(jìn)行數(shù)據(jù)校驗(yàn)
基于?Spring?Boot?,如何“優(yōu)雅”的進(jìn)行數(shù)據(jù)校驗(yàn)?zāi)兀疚膶⒋蠹以敿?xì)介紹Springboot如何優(yōu)雅的進(jìn)行數(shù)據(jù)校驗(yàn),文中有詳細(xì)的代碼示例和流程步驟,需要的朋友可以參考下2023-06-06springmvc接收json串,轉(zhuǎn)換為實(shí)體類List方法
今天小編就為大家分享一篇springmvc接收json串,轉(zhuǎn)換為實(shí)體類List方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2018-08-08IDEA中實(shí)體類(POJO)與JSON快速互轉(zhuǎn)問題
這篇文章主要介紹了IDEA中實(shí)體類(POJO)與JSON快速互轉(zhuǎn),本文通過圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08Java基于遞歸和循環(huán)兩種方式實(shí)現(xiàn)未知維度集合的笛卡爾積算法示例
這篇文章主要介紹了Java基于遞歸和循環(huán)兩種方式實(shí)現(xiàn)未知維度集合的笛卡爾積算法,結(jié)合實(shí)例形式分析了Java使用遞歸與循環(huán)兩種方式實(shí)現(xiàn)未知維度集合的笛卡爾積相關(guān)概念、原理與操作技巧,需要的朋友可以參考下2017-12-12Spring boot actuator端點(diǎn)啟用和暴露操作
這篇文章主要介紹了Spring boot actuator端點(diǎn)啟用和暴露操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07Spring Cloud Gateway + Nacos 實(shí)現(xiàn)動(dòng)態(tài)路由
這篇文章主要介紹了Spring Cloud Gateway + Nacos 實(shí)現(xiàn)動(dòng)態(tài)路由的方法,幫助大家實(shí)現(xiàn)路由信息的自動(dòng)更新,感興趣的朋友可以了解下2020-10-10關(guān)于HashSet與HashMap的區(qū)別及說明
這篇文章主要介紹了關(guān)于HashSet與HashMap的區(qū)別及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07