從零開始實現放置遊戲(六):Excel批量匯入
涉及的功能點主要有對office文件的程式設計、檔案上傳功能。流程圖大致如下:
一、新增依賴項
解析office文件推薦使用免費的開源元件POI,已經可以滿足80%的功能需求。上傳檔案需要依賴commons-fileupload包。我們在pom中新增下列程式碼:
- <!-- office元件 -->
- <dependency>
- <groupId>org.apache.poi</groupId>
- <artifactId>poi</artifactId>
- <version>4.1.0</version>
- </dependency>
- <dependency>
- <groupId>org.apache.poi</groupId>
- <artifactId>poi-ooxml</artifactId>
- <version>4.1.0</version>
- </dependency>
- <!-- 檔案上傳 -->
- <dependency>
- <groupId>commons-fileupload</groupId>
- <artifactId>commons-fileupload</artifactId>
- <version>1.4</version>
- </dependency>
另外,之前我們配置的mvc檢視解析器只能解析簡單的檢視,上傳檔案需要支援multipart。在spring-mvc.xml中新增如下配置:
- <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
- <property name="defaultEncoding" value="UTF-8"></property>
- <property name="maxUploadSize" value="10485770"></property>
- <property name="maxInMemorySize" value="10485760"></property>
- </bean>
這裡配置了上傳最大限制10MB,對於excel上傳來說足矣。
二、檔案上傳、解析、落庫
在MapController中,我們新增3個方法
MapController.java
- @ResponseBody
- @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
- public Object importExcel(HttpServletRequest request) {
- try {
- ServletContext servletContext = request.getServletContext();
- String uploadPath = servletContext.getRealPath("/upload");
- File dir = new File(uploadPath);
- if (!dir.exists()) {
- dir.mkdir();
- }
- CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(servletContext);
- if (multipartResolver.isMultipart(request)) {
- MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
- Iterator<String> iter = multiRequest.getFileNames();
- while (iter.hasNext()) {
- MultipartFile file = multiRequest.getFile(iter.next());
- if (file.getSize() > 0) {
- String fileName = file.getOriginalFilename();
- String extension = fileName.substring(fileName.lastIndexOf("."));
- if (!extension.toLowerCase().equals(".xls") && !extension.toLowerCase().equals(".xlsx")) {
- throw new Exception("不支援的文件格式!請上傳.xls或.xlsx格式的文件!");
- }
- String destFileName = fileName + "_" + System.currentTimeMillis() + extension;
- File destFile = new File(uploadPath, destFileName);
- file.transferTo(destFile);
- List<WowMap> dataList = this.loadExcelData(destFile.getPath());
- this.saveExcelData(dataList);
- if (!destFile.delete()) {
- logger.warn("臨時檔案刪除失敗:" + destFile.getAbsolutePath());
- }
- }
- }
- }
- return CommonResult.success();
- } catch (Exception ex) {
- logger.error(ex.getMessage(), ex);
- return CommonResult.fail();
- }
- }
- protected List<WowMap> loadExcelData(String excelPath) throws Exception {
- FileInputStream fileInputStream = new FileInputStream(excelPath);
- XSSFWorkbook workbook = new XSSFWorkbook(fileInputStream);
- Sheet sheet = workbook.getSheet("地圖");
- List<WowMap> wowMapList = new ArrayList<>();
- // 處理當前頁,迴圈讀取每一行
- String createUser = this.currentUserName();
- for (int rowNum = 2; rowNum <= sheet.getLastRowNum(); rowNum++) {
- XSSFRow row = (XSSFRow) sheet.getRow(rowNum);
- String name = PoiUtil.getCellValue(row.getCell(2));
- DataDict.Occupy occupy = DataDict.Occupy.getByDesc(PoiUtil.getCellValue(row.getCell(4)));
- WowMap wowMap = new WowMap();
- wowMap.setName(name);
- wowMap.setOccupy(occupy.getCode());
- wowMap.setDescription("");
- wowMap.setCreateUser(createUser);
- wowMapList.add(wowMap);
- }
- fileInputStream.close();
- return wowMapList;
- }
- protected void saveExcelData(List<WowMap> dataList) {
- wowMapManager.batchInsert(dataList);
- }
其中,importExcel方法,時候對應前端點選匯入按鈕時的後端入口,在這個方法中,我們定義了臨時檔案上傳路徑,校驗了檔名字尾,儲存上傳的檔案到伺服器,並在操作結束後將臨時檔案刪除; loadExcelData方法,利用POI元件讀取解析Excel資料,Excel資料怎麼配我們可以自由定義,這裡讀取時自由調整對應的行列即可,本例使用的Excel在文末給出的原始碼中可以找到; saveExcelData方法,將解析到的資料列表存入資料庫,這裡呼叫的batchInsert批量新增方法,在前面講增刪查改的時候已經提前實現了。
另外,在使用POI元件讀取Excel資料時,需要先判斷單元格格式,我們建立一個工具類PoiUtil來實現此功能,這種在以後的其他專案中也可以使用的工具類,我們把它提取出來,放到util模組中,作為我們的通用工具包,以便日後使用。在util模組新建包com.idlewow.util.poi,並新增PoiUtil類:
PoiUtil.java
- package com.idlewow.util.poi;
- import org.apache.commons.lang3.StringUtils;
- import org.apache.poi.ss.usermodel.Cell;
- import org.apache.poi.ss.usermodel.CellType;
- import org.apache.poi.ss.usermodel.DateUtil;
- import java.text.DecimalFormat;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- public class PoiUtil {
- public static String getCellValue(Cell cell) {
- CellType cellType = cell.getCellType();
- if (cellType.equals(CellType.STRING)) {
- return cell.getStringCellValue();
- } else if (cellType.equals(CellType.NUMERIC)) {
- if (DateUtil.isCellDateFormatted(cell)) {
- Date date = cell.getDateCellValue();
- return date == null ? "" : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
- } else {
- return new DecimalFormat("0.##").format(cell.getNumericCellValue());
- }
- } else if (cellType.equals(CellType.FORMULA)) {
- if (StringUtils.isNotBlank(cell.getStringCellValue())) {
- return cell.getStringCellValue();
- } else {
- return cell.getNumericCellValue() + "";
- }
- } else if (cellType.equals(CellType.BOOLEAN)) {
- return cell.getBooleanCellValue() ? "TRUE" : "FALSE";
- } else {
- return "";
- }
- }
- }
工具類提取到util模組後,需要在util模組也新增對Poi的依賴,並在rms模組新增對util的依賴。這裡util模組中,依賴項的scope為provided即可,僅在編譯階段使用,因為在引用此工具包的模組中肯定已經引入了POI依賴,無需重複打包:
- <dependencies>
- <dependency>
- <groupId>org.apache.poi</groupId>
- <artifactId>poi</artifactId>
- <version>4.1.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.poi</groupId>
- <artifactId>poi-ooxml</artifactId>
- <version>4.1.0</version>
- <scope>provided</scope>
- </dependency>
- </dependencies>
三、修改前端頁面
在地圖列表頁面list.jsp中,新增匯入excel的按鈕。
- <form>
- …………
- …………
- <div class="layui-inline layui-show-xs-block">
- <button type="button" class="layui-btn" onclick="xadmin.open('新增地圖','add',500,500)">
- <i class="layui-icon"></i>新增地圖
- </button>
- </div>
- <div class="layui-upload layui-inline layui-show-xs-block">
- <button type="button" class="layui-btn layui-btn-normal" id="btnSelectFile">選擇Excel</button>
- <button type="button" class="layui-btn" id="btnImport">開始匯入</button>
- </div>
- </form>
在列表頁面的list.js中,繫結相應的按鈕事件。
- layui.use(['upload', 'table', 'form'], function () {
- …………
- …………
- layui.upload.render({
- elem: '#btnSelectFile',
- url: '/manage/map/importExcel',
- accept: 'file',
- exts: 'xls|xlsx',
- auto: false,
- bindAction: '#btnImport',
- done: function (result) {
- if (result.code === 1) {
- layer.alert(result.message, {icon: 6},
- function () {
- layui.layer.closeAll();
- layui.table.reload('datatable');
- });
- } else {
- layer.alert(result.message, {icon: 5});
- }
- }
- });
- });
四、執行效果
以上,excel匯入的功能就全部完成了,我們執行下看下效果:
小結
本章通過匯入Excel檔案,實現了批量錄入的功能。
原始碼下載地址:https://idlestudio.ctfile.com/fs/14960372-383760599
本文原文地址:https://www.cnblogs.com/lyosaki88/p/idlewow_6.html
相關閱讀:
從零開始實現放置遊戲(一):準備工作
從零開始實現放置遊戲(二):整體框架搭建
從零開始實現放置遊戲(三):後臺管理系統搭建
從零開始實現放置遊戲(四)後臺數值配置的增刪查改
從零開始實現放置遊戲(五):管理系統搭建之實現切面日誌
作者:丶謙信
部落格地址:https://www.cnblogs.com/lyosaki88/p/idlewow_6.html
相關文章
- 從零開始實現放置遊戲(六)——實現掛機戰鬥(4)匯入Excel數值配置遊戲Excel
- 從零開始實現放置遊戲(一)遊戲
- 從零開始實現放置遊戲(一):整體框架搭建遊戲框架
- 從零開始實現放置遊戲(三):後臺管理系統搭建遊戲
- 從零開始實現放置遊戲(五):管理系統搭建之實現切面日誌遊戲
- 從零開始實現放置遊戲(八)——實現掛機戰鬥(6)程式碼重構遊戲
- 從零開始實現放置遊戲(四)——實現掛機戰鬥(2)實現後臺數值配置遊戲
- 從零開始實現放置遊戲(四)後臺數值配置的增刪查改遊戲
- 從零開始實現放置遊戲(五)——實現掛機戰鬥(3)引入日誌功能並實現切面日誌遊戲
- 從零開始實現線上直播
- 從零開始用 proxy 實現 Mobx
- 從零開始學Electron筆記(六)筆記
- 從零開始實現一個RPC框架(零)RPC框架
- 從零開始的Java RASP實現(一)Java
- 從零開始的Java RASP實現(二)Java
- 從零開始實現簡單 RPC 框架 3:配置匯流排 URLRPC框架
- Vue + Element 實現匯入匯出ExcelVueExcel
- Laravel- 後臺批量匯入 ExcelLaravelExcel
- 從零開始React專案架構(六)React架構
- 從零開始做一個SLG遊戲(一):六邊形網格遊戲
- 從零開始寫 Docker(六)---實現 mydocker run -v 支援資料卷掛載Docker
- 前端實現Excel匯入和匯出功能前端Excel
- 從零開始寫 Docker(十一)---實現 mydocker exec 進入容器內部Docker
- 從零開始做一個SLG遊戲(六):UI系統擴充套件遊戲UI套件
- 從零開始學五筆(六):捺區字根
- Python批量匯入Excel資料到MySQLPythonExcelMySql
- EasyPoi框架實現Excel表格匯入框架Excel
- 從零開始實現一個簡易的Java MVC框架(六)--加強AOP功能JavaMVC框架
- 從Excel匯入sql serverExcelSQLServer
- Laravel6 配合 Maatwebsite\Excel 實現 Excel 匯入LaravelWebExcel
- 從零開始學機器學習——入門NLP機器學習
- 從零開始實現一個RPC框架(五)RPC框架
- 從零開始實現一個RPC框架(四)RPC框架
- 從零開始實現一個RPC框架(三)RPC框架
- 從零開始實現一個RPC框架(二)RPC框架
- 從零開始實現一個RPC框架(一)RPC框架
- 從零開始最小實現 react 伺服器渲染React伺服器
- Laravel Maatwebsite-Excel 3.1 實現匯出匯入LaravelWebExcel