日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringBoot中使用POI实现Excel导入到数据库(图文教程已实践)

發(fā)布時(shí)間:2025/3/19 javascript 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringBoot中使用POI实现Excel导入到数据库(图文教程已实践) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

場景

IDEA中開發(fā)SpringBoot項(xiàng)目時(shí)需要將Excel模板中數(shù)據(jù)導(dǎo)入的到數(shù)據(jù)庫。

Excel模板如下

實(shí)現(xiàn)思想

首先將模板上傳到服務(wù)器中某路徑,并將當(dāng)前路徑存儲,然后使用POI自帶的

工具類獲取到sheet以及行數(shù)以及每個(gè)cell,然后分別給數(shù)據(jù)庫中對應(yīng)的對象的屬性賦值,然后插入到數(shù)據(jù)庫中并返回執(zhí)行結(jié)果。

實(shí)現(xiàn)

實(shí)現(xiàn)文件上傳

頁面代碼

實(shí)現(xiàn)點(diǎn)擊導(dǎo)入按鈕彈窗

<div class="modal inmodal" id="apImportModel" tabindex="-1" role="dialog" aria-hidden="true"><div class="modal-dialog" id="apImportDiv" th:fragment="apImportDiv"><div class="modal-content animated fadeIn"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button><form class="dropzone" id="dropzoneForm" enctype="multipart/form-data"><div class="fallback"><input name="file" type="file" id="file_id" /></div></form><button id="uploladBtn" class="btn btn-info mt-2" type="button" onclick="return uploadExcel()"><i class="fa fa-reply"></i>上傳</button><button id="parseBtn" class="btn btn-info mt-2" type="button" onclick="return parseExcel()"><i class="fa fa-reply"></i>導(dǎo)入</button></div></div></div>

因?yàn)檫@里使用的是thymeleaf模板

thymeleaf中文參考手冊下載:

https://download.csdn.net/download/badao_liumang_qizhi/11021427 ?

在當(dāng)前頁面需要引入js文件

<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"th:replace="layout/layout(title='測試數(shù)據(jù)',cssPaths='/public/css/plugins/datapicker/datepicker3.css',jsPaths='/public/js/plugins/dataTables/datatables.min.js,/modular/receiveOrder/wmsReceiveOrder.js')"><!-- layout文件路徑-->

?

來到/modular/receiveOrder/wmsReceiveOrder.js此目錄下的js文件

在js中實(shí)現(xiàn)點(diǎn)擊導(dǎo)入按鈕彈窗功能

//導(dǎo)入按鈕點(diǎn)擊事件$("#importBtn").click(function () {importExcel();});

點(diǎn)擊事件調(diào)用下面的方法

?? function importExcel(){var url = "/wmsReceiveOrder/doExcelImport.html";$('#apImportDiv').load(url, function (response,status,xhr) {$("#apImportModel").modal('show');});}

該方法按照url請求后臺,其中l(wèi)oad方法是讓隱藏的彈窗部分顯示 。

來到后臺url對應(yīng)的方法中

@Description("獲取收獲單信息列表頁面")@RequestMapping("/wmsReceiveOrder.html")public String page(Model model) {return "receiveOrder/wmsReceiveOrder.html";}

返回當(dāng)前頁面并將彈窗顯示

開始設(shè)置文件上傳的點(diǎn)擊事件

在彈窗部分的代碼中

<div class="modal inmodal" id="apImportModel" tabindex="-1" role="dialog"? aria-hidden="true"><div class="modal-dialog" id="apImportDiv" th:fragment="apImportDiv"><div class="modal-content animated fadeIn"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button><form? class="dropzone"? id="dropzoneForm" enctype="multipart/form-data"><div class="fallback"><input name="file" type="file" id="file_id" /></div></form><button id="uploladBtn" class="btn btn-info mt-2" type="button" onclick="return uploadExcel()"><i class="fa fa-reply"></i>上傳</button><button id="parseBtn" class="btn btn-info mt-2" type="button" onclick="return parseExcel()"><i class="fa fa-reply"></i>導(dǎo)入</button></div></div></div>

其中

<button id="uploladBtn" class="btn btn-info mt-2" type="button" onclick="return uploadExcel()"><i class="fa fa-reply"></i>上傳</button>


是調(diào)用js中對應(yīng)的方法uploadExcel()

//上傳Excel操作 function uploadExcel(){debuggervar formData = new FormData();var file=$("#file_id");formData.append('file', file[0].files[0]);$.ajax({type: 'POST',url: "/wmsReceiveOrder/doImportExcel",cache: false,? //禁用緩存data:formData,contentType: false,dataType: "json",processData:false,success: function (result) {debuggeralert(result.message)}})return false; }

?

選擇文件后,會上傳到url中對應(yīng)的位置

要實(shí)現(xiàn)文件上傳,需要引入commons-fileupload包

找到項(xiàng)目下的pom.xml

添加如下依賴

?<!--文件上傳--><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3</version></dependency>

來到url對應(yīng)的后臺方法

?@Description("獲取前端導(dǎo)入excel")@ResponseBody@RequestMapping(value = "/doImportExcel")public Map<String, Object> doUpload(HttpServletRequest request, @RequestParam("file") MultipartFile file) {Map<String, Object> result = new HashMap<String, Object>();String fileName = "";try {//將當(dāng)前上下文初始化給? CommonsMutipartResolver (多部分解析器)CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());//檢查form中是否有enctype="multipart/form-data"if (multipartResolver.isMultipart(request)) {//將request變成多部分requestMultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;//獲取multiRequest 中所有的文件名Iterator iter = multiRequest.getFileNames();while (iter.hasNext()) {//一次遍歷所有文件MultipartFile file1 = multiRequest.getFile(iter.next().toString());if (file != null) {//獲取上傳文件名fileName = file1.getOriginalFilename();//獲取后綴名String sname = fileName.substring(fileName.lastIndexOf("."));//時(shí)間格式化格式SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyyMMddHHmmssSSS");//獲取當(dāng)前時(shí)間并作為時(shí)間戳String timeStamp=simpleDateFormat.format(new Date());//拼接新的文件名String newName ="收貨單"+timeStamp+sname;//指定上傳文件的路徑String path = "F:\\" + newName;//上傳保存file.transferTo(new File(path));//保存當(dāng)前文件路徑request.getSession().setAttribute("currFilePath", path);}}}result.put("statusCode", "200");result.put("message", "上傳成功!");result.put("filename", fileName);} catch (Exception ex) {result.put("statusCode", "300");result.put("message", "上傳失敗:" + ex.getMessage());}return result;}

實(shí)現(xiàn)效果

點(diǎn)擊選擇文件

選擇文件后

然后點(diǎn)擊上傳

這時(shí)在后臺controller打斷點(diǎn)查看,可以看到后臺已經(jīng)獲取到上傳的文件,并以當(dāng)前時(shí)間戳重名名存放在F盤下,將存放路徑存在當(dāng)前

session中。

可以看到F盤 下已經(jīng)有了剛才上傳的文件

?

解析并導(dǎo)入Excel實(shí)現(xiàn)

彈窗頁面的解析Excel按鈕代碼

<div class="modal inmodal" id="apImportModel" tabindex="-1" role="dialog"? aria-hidden="true"><div class="modal-dialog" id="apImportDiv" th:fragment="apImportDiv"><div class="modal-content animated fadeIn"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button><form? class="dropzone"? id="dropzoneForm" enctype="multipart/form-data"><div class="fallback"><input name="file" type="file" id="file_id" /></div></form><button id="uploladBtn" class="btn btn-info mt-2" type="button" onclick="return uploadExcel()"><i class="fa fa-reply"></i>上傳</button><button id="parseBtn" class="btn btn-info mt-2" type="button" onclick="return parseExcel()"><i class="fa fa-reply"></i>導(dǎo)入</button></div></div></div>

點(diǎn)擊導(dǎo)入按鈕后調(diào)用js中的parseExcel()方法

//解析Excel操作 function parseExcel(){var url = "/wmsReceiveOrder/parseExcel";$.ajax({type: 'POST',url: url,cache: false,? //禁用緩存contentType: false,dataType: "json",processData:false,success: function (result) {debuggeralert(result.message)}})return false; }

ajax請求后臺的url對應(yīng)的方法

前提要實(shí)現(xiàn)Excel的導(dǎo)入和導(dǎo)出需要引入POI的包

打開項(xiàng)目的pom.xml

<!--excel導(dǎo)入導(dǎo)出--><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.9</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.9</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>3.9</version></dependency>

剛才請求到后臺url對應(yīng)的方法

@ResponseBody@RequestMapping("/parseExcel")public Map<String, Object> parseExcel(HttpServletRequest request) {Map<String, Object> result = new HashMap<String, Object>();Workbook workbook = null;//獲取文件路徑String path = (String)request.getSession().getAttribute("currFilePath");//獲取文件格式String fileType = path.substring(path.lastIndexOf(".") + 1, path.length());try {InputStream stream = new FileInputStream(path);//如果后綴名為xls,使用HSSFif (fileType.equals("xls")) {workbook = new HSSFWorkbook(stream);//如果后綴名是xlsx,使用XSSF}else if (fileType.equals("xlsx")){workbook = new XSSFWorkbook(stream);}Sheet sheet= workbook.getSheet("sheet1");//獲取行數(shù)int rows=sheet.getPhysicalNumberOfRows();//List<WmsReceiveOrder> receiveOrderList =new ArrayList<WmsReceiveOrder>();WmsReceiveOrder receiveOrder =new WmsReceiveOrder();//獲取第一行數(shù)據(jù)Row row1 =sheet.getRow(0);if(row1!=null){//獲取采購訂單號row1.getCell(1).setCellType(Cell.CELL_TYPE_STRING);String purchaseCode =row1.getCell(1).getStringCellValue();receiveOrder.setPurchaseCode(purchaseCode);}//獲取第二行數(shù)據(jù)Row row2 =sheet.getRow(1);if(row2!=null){//獲取供應(yīng)商送貨單號row2.getCell(1).setCellType(Cell.CELL_TYPE_STRING);String deliveryCode =row2.getCell(1).getStringCellValue();receiveOrder.setDeliveryCode(deliveryCode);//獲取送貨日期Date deliveryTime =row2.getCell(3).getDateCellValue();receiveOrder.setDeliveryTime(deliveryTime);//獲取供應(yīng)商名稱row2.getCell(5).setCellType(Cell.CELL_TYPE_STRING);String supplierName =row2.getCell(5).getStringCellValue();receiveOrder.setSupplierName(supplierName);}//獲取第三行數(shù)據(jù)Row row3 =sheet.getRow(2);if(row3!=null){//獲取ERP入貨單號row3.getCell(1).setCellType(Cell.CELL_TYPE_STRING);String erpInCode =row3.getCell(1).getStringCellValue();receiveOrder.setErpInCod(erpInCode);//獲取入庫日期Date inTime =row3.getCell(3).getDateCellValue();receiveOrder.setInTime(inTime);}receiveOrder.setRemark("測試備注");receiveOrder.setType(1);receiveOrder.setStatus("1");//插入receiveOrder表數(shù)據(jù)boolean isSaveReceiveOrder =receiveOrderService.save(receiveOrder);List<WmsReceiveOrderDetails> receiveOrderDetailsList = new ArrayList<WmsReceiveOrderDetails>();if(isSaveReceiveOrder){//如果插入表頭成功,獲取插入數(shù)據(jù)的ID并插入詳情表Long receiveId=receiveOrder.getId();for (int currentRow=4;currentRow<rows;currentRow++) {WmsReceiveOrderDetails wmsReceiveOrderDetails =new WmsReceiveOrderDetails();wmsReceiveOrderDetails.setReceiveId(receiveId);//獲取物料編號sheet.getRow(currentRow).getCell(1).setCellType(Cell.CELL_TYPE_STRING);String materielId = sheet.getRow(currentRow).getCell(1).getStringCellValue();wmsReceiveOrderDetails.setMaterielId(materielId);//獲取物料名稱sheet.getRow(currentRow).getCell(2).setCellType(Cell.CELL_TYPE_STRING);String materielName = sheet.getRow(currentRow).getCell(2).getStringCellValue();wmsReceiveOrderDetails.setMaterielName(materielName);//獲取供應(yīng)商批次sheet.getRow(currentRow).getCell(3).setCellType(Cell.CELL_TYPE_STRING);String supplierBatch = sheet.getRow(currentRow).getCell(3).getStringCellValue();wmsReceiveOrderDetails.setSupplierBatch(supplierBatch);//獲取生產(chǎn)日期Date productDate = sheet.getRow(currentRow).getCell(4).getDateCellValue();wmsReceiveOrderDetails.setProductDate(productDate);//獲取數(shù)量sheet.getRow(currentRow).getCell(5).setCellType(Cell.CELL_TYPE_STRING);Long num =Long.parseLong(sheet.getRow(currentRow).getCell(5).getStringCellValue());wmsReceiveOrderDetails.setNum(num);//獲取托盤編號String salverCode = sheet.getRow(currentRow).getCell(6).getStringCellValue();wmsReceiveOrderDetails.setSalverCode(salverCode);wmsReceiveOrderDetails.setStatus("1");wmsReceiveOrderDetails.setRemark("測試備注");wmsReceiveOrderDetails.setDeletedFlag(false);receiveOrderDetailsList.add(wmsReceiveOrderDetails);}if(receiveOrderDetailsList!=null){for (WmsReceiveOrderDetails wmsReceiveOrderDetails:receiveOrderDetailsList) {boolean isSaveReceiveOrderDetails =receiveOrderDetailsService.save(wmsReceiveOrderDetails);if(!isSaveReceiveOrderDetails){result.put("statusCode", "300");result.put("message", "導(dǎo)入物料編號為:"+wmsReceiveOrderDetails.getMaterielId()+"出錯(cuò)了!");}else{result.put("statusCode", "200");result.put("message", "導(dǎo)入收貨單成功!");}}}}else{result.put("statusCode", "300");result.put("message", "導(dǎo)入收貨單失敗!");}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return result;}

這里是結(jié)合具體的業(yè)務(wù)實(shí)現(xiàn)的Excel的導(dǎo)入,這里要導(dǎo)入的表是兩個(gè)關(guān)聯(lián)表。

基本思想就是通過行與列的坐標(biāo)定位獲取到cell中的值。

比如:

1.獲取sheet頁

Workbook workbook= null;

?中間需要根據(jù)獲取的后綴名進(jìn)行初始化

?workbook = new HSSFWorkbook(stream);

?或者

workbook = new XSSFWorkbook(stream);

然后
?

Sheet sheet= workbook.getSheet("sheet1");

這里的sheet1是sheet頁的名字

2.獲取行數(shù)

int rows=sheet.getPhysicalNumberOfRows();

3.獲取第一行數(shù)據(jù)

Row row1 =sheet.getRow(0);

4.獲取第一行的第2個(gè)Cell對象

row1.getCell(1)

注意行與Cell都是從0開始的。

5.給第一行的第二個(gè)Cell設(shè)置值的類型

?row1.getCell(1).setCellType(Cell.CELL_TYPE_STRING);

具體類型在IDEA代碼提示中會有。

6.獲取第一行第二個(gè)Cell的String類型的值。

String purchaseCode =row1.getCell(1).getStringCellValue();

7.獲取日期格式的Cell的值

Date inTime =row3.getCell(3).getDateCellValue();

?

實(shí)現(xiàn)效果

?

總結(jié)

以上是生活随笔為你收集整理的SpringBoot中使用POI实现Excel导入到数据库(图文教程已实践)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。