最近開發項目,使用到了Excel導入導出功能,以防忘記,還是做下筆記——好記性不如爛筆頭!
首先在html頁面上,設置一個文件上傳的按鈕
<div> <button type="button" class="btn-btn" @click="uploadFile" style="margin-top: 5px;float: left">導入 </button> </div>
觸發點擊事件,這里使用layer mobile移動版插件,用來提示和顯示加載層,大數據傳輸,使用formData封裝,
var formData = new FormData();
formData.append("file", document.getElementById("upload").files[0]);
下面是js方法
//上傳Excel文件 //判斷文件是否存在,以及文件后綴名 uploadFile() { var file = $("#upload").val(); file = file.substring(file.lastIndexOf('.'), file.length); if (file == '') { layer.open({ content: '上傳文件不能為空!' , skin: 'msg' , time: 2 //2秒后自動關閉 }); } else if (file != '.xlsx' && file != '.xls') { layer.open({ content: '請選擇正確的excel類型文件!' , skin: 'msg' , time: 2 //2秒后自動關閉 }); } else { this.ajaxFileUpload(); } }, //上傳文件請求 ajaxFileUpload() { var formData = new FormData(); formData.append("file", document.getElementById("upload").files[0]); $.ajax({ url: uploadExcelFielUrl, type: "POST", async: true, data: formData, processData: false, //需要這兩個設置 contentType: false, beforeSend: function () { layer.open({ type: 2 , content: '文件上傳中,請稍候' }); }, success: function (data) { layer.closeAll(); data = JSON.parse(data); if (data.state == 200) { layer.open({ content: data.message , skin: 'msg' , time: 1 //2秒后自動關閉 }); window.location.reload(); } else { layer.open({ content: data.message , skin: 'msg' , time: 2 //2秒后自動關閉 }); } } }); }
java中Controller層接收文件,這里偷懶,在控制層操作數據,應該在服務層,畢竟服務層加了AOP事務,有兩條sql或以上都需要加事務.
@RequestMapping("InputExcel")
@ResponseBody
public ResultEntity InputExcel(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
ResultEntity result = new ResultEntity();
if (!file.isEmpty()) {
try {
//獲取原始的文件名
String originalFilename = file.getOriginalFilename();
//獲取文件類型
String fileType = originalFilename.substring(originalFilename.lastIndexOf(".") + 1, originalFilename.length());
//默認從第一行開始讀取
Integer startRows = 1;
//獲取輸入流
InputStream is = file.getInputStream();
List<DoorAntRel> bindingList = new ArrayList<>();
List<Bookcase> bookcaseList = new ArrayList<>();
//Excel導入導出的單元類
List<String[]> strings = ExcelUtil.readData(fileType, startRows, true, is);
//遍歷Excel表每一行的數據
for (String[] str : strings) {
Bookcase bookcase = new Bookcase();
DoorAntRel doorAntRel = new DoorAntRel();
bookcase.setName(str[1]);
bookcase.setType(str[2]);
bookcase.setCom(Integer.parseInt(str[3]));
doorAntRel.setDoorName(str[4]);
doorAntRel.setDoorNo(Integer.parseInt(str[5]));
doorAntRel.setAntennaNo(Integer.parseInt(str[6]));
doorAntRel.setReadWriterId(Integer.parseInt(str[7]));
doorAntRel.setBookcaseId(Integer.parseInt(str[8]));
doorAntRel.setBadFlag(Integer.parseInt(str[9]));
doorAntRel.setDoorSlot(Integer.parseInt(str[10]));
bindingList.add(doorAntRel);
bookcaseList.add(bookcase);
}
//將數據批量保存到數據庫,底層原理其實也是遍歷操作,可以自己寫循環插入或修改,我這里使用了Mybatis plus插件,所以有方法批量操作,自己寫也可以
boolean bookState = bookcaseService.insertOrUpdateBatch(bookcaseList);
boolean doorState = doorAntRelService.insertOrUpdateBatch(bindingList);
if(bookState){
if(doorState){
result.setState(HttpCode.SUCCESS);
result.setMessage("上傳文件成功!");
return result;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
result.setState(HttpCode.FAILED);
result.setMessage("上傳文件失敗!");
return result;
}
ExcelUtils類,這個網上有很多版本,下載一個,導入到自己的項目,根據ExcelUtils需要的參數,而做不同的操作,上面貼的代碼則是根據我這個ExcelUtils寫的,我個人覺得我這個ExcelUtils不太安全,但是簡單
package com.ilas.bookcase.common.utils; import org.apache.poi.hssf.usermodel.*; 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.ss.util.CellRangeAddress; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; public class ExcelUtil { public static void createExcel(List<String> header, List<String[]> data, OutputStream out) throws IOException { // 創建一個Excel文件 HSSFWorkbook workbook = new HSSFWorkbook(); // 創建一個工作表 HSSFSheet sheet = workbook.createSheet("sheet1"); // 添加表頭行 HSSFRow hssfRow = sheet.createRow(0); // 設置單元格格式居中 HSSFCellStyle cellStyle = workbook.createCellStyle(); cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 添加表頭內容 for (int i = 0; i < header.size(); i++) { HSSFCell headCell = hssfRow.createCell(i); headCell.setCellValue(header.get(i)); headCell.setCellStyle(cellStyle); } // 添加數據內容 for (int i = 0; i < data.size(); i++) { String[] strings = data.get(i); hssfRow = sheet.createRow(i + 1); for (int j = 0; j < strings.length; j++) { HSSFCell cell = hssfRow.createCell(j); cell.setCellValue(strings[j]); cell.setCellStyle(cellStyle); } } //單元格自適應 sheet.autoSizeColumn(2,true); // 保存Excel文件 workbook.write(out); } public static void createExcel(String title,List<String> header, List<String[]> data, OutputStream out) throws IOException { // 創建一個Excel文件 HSSFWorkbook workbook = new HSSFWorkbook(); // 創建一個工作表 HSSFSheet sheet = workbook.createSheet("sheet1"); // 添加表頭行 HSSFRow hssfRow = sheet.createRow(0); HSSFCell cellTitle = hssfRow.createCell(0); // 設置標題外的單元格格式居中 HSSFCellStyle cellStyle = workbook.createCellStyle(); cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); //設置標題的樣式 HSSFCellStyle titleCellStyle = workbook.createCellStyle(); titleCellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); titleCellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); //設置標題字體的樣式 HSSFFont font = workbook.createFont(); font.setFontHeightInPoints((short) 12);//設置字體大小 titleCellStyle.setFont(font); //標題設置(四個參數分別表示起始行,終止行,起始列,終止列) cellTitle.setCellValue(title); int lastCol = header.size() > 1 ? header.size() : 2; CellRangeAddress region1 = new CellRangeAddress(0, 1, (short) 0, (short) lastCol - 1); sheet.addMergedRegion(region1); hssfRow = sheet.createRow(1); hssfRow = sheet.createRow(2); cellTitle.setCellStyle(titleCellStyle); // 添加表頭內容 for (int i = 0; i < header.size(); i++) { HSSFCell headCell = hssfRow.createCell(i); headCell.setCellValue(header.get(i)); headCell.setCellStyle(cellStyle); } // 添加數據內容 for (int i = 0; i < data.size(); i++) { String[] strings = data.get(i); hssfRow = sheet.createRow(i + 3); for (int j = 0; j < strings.length; j++) { HSSFCell cell = hssfRow.createCell(j); cell.setCellValue(strings[j]); cell.setCellStyle(cellStyle); } } // 保存Excel文件 workbook.write(out); } /** * 讀取Excel的內容 * * @param fileType 文件類型,xls或xlsx * @param startRows 開始讀取行數,比喻行頭不需要讀入 忽略的行數為1 * @param ignoreRowBlank 是否忽略空行 * @param is 文件輸入流 * @return 讀出的Excel中數據的內容 * @throws IOException duxxxxx */ public static List<String[]> readData(String fileType, int startRows, boolean ignoreRowBlank, InputStream is) throws IOException { List<String[]> result = new ArrayList<>(); Workbook wb = readExcel(fileType, is); for (int sheetIndex = 0; sheetIndex < wb.getNumberOfSheets(); sheetIndex++) { Sheet sheet = wb.getSheetAt(sheetIndex); for (int rowIndex = startRows, z = sheet.getLastRowNum(); rowIndex <= z; rowIndex++) { Row row = sheet.getRow(rowIndex); if (row == null) { continue; } int rowSize = row.getLastCellNum(); String[] values = new String[rowSize]; boolean hasValue = false; for (int columnIndex = 0; columnIndex < rowSize; columnIndex++) { String value = ""; Cell cell = row.getCell(columnIndex); if (cell != null) { // 注意:一定要設成這個,否則可能會出現亂碼,后面版本默認設置 switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_STRING: value = cell.getStringCellValue(); break; case HSSFCell.CELL_TYPE_NUMERIC: if (HSSFDateUtil.isCellDateFormatted(cell)) { Date date = cell.getDateCellValue(); if (date != null) { value = new SimpleDateFormat("yyyy-MM-dd") .format(date); } else { value = ""; } } else { //value = new DecimalFormat("0").format(cell.getNumericCellValue()); if (HSSFDateUtil.isCellDateFormatted(cell)) { value = String.valueOf(cell.getDateCellValue()); } else { cell.setCellType(Cell.CELL_TYPE_STRING); String temp = cell.getStringCellValue(); // 判斷是否包含小數點,如果不含小數點,則以字符串讀取,如果含小數點,則轉換為Double類型的字符串 if (temp.indexOf(".") > -1) { value = String.valueOf(new Double(temp)).trim(); } else { value = temp.trim(); } } } break; case HSSFCell.CELL_TYPE_FORMULA: // 導入時如果為公式生成的數據則無值 if (!cell.getStringCellValue().equals("")) { value = cell.getStringCellValue(); } else { value = cell.getNumericCellValue() + ""; } break; case HSSFCell.CELL_TYPE_BLANK: break; case HSSFCell.CELL_TYPE_ERROR: value = ""; break; case HSSFCell.CELL_TYPE_BOOLEAN: value = (cell.getBooleanCellValue() == true ? "Y" : "N"); break; default: value = ""; } } values[columnIndex] = value; if (!value.isEmpty()) { hasValue = true; } } if (!ignoreRowBlank || hasValue) {//不為忽略空行模式或不為空行 result.add(values); } } } return result; } //讀取excel private static Workbook readExcel(String fileType, InputStream is) throws IOException { if ("xls".equals(fileType)) { return new HSSFWorkbook(is); } else if ("xlsx".equals(fileType)) { return new XSSFWorkbook(is); } else { throw new IllegalArgumentException("不支持的文件類型,僅支持xls和xlsx"); } } /** * 去掉字符串右邊的空格 * * @param str 要處理的字符串 * @return 處理后的字符串 */ private static String rightTrim(String str) { if (str == null) { return ""; } int length = str.length(); for (int i = length - 1; i >= 0; i--) { if (str.charAt(i) != 0x20) { break; } length--; } return str.substring(0, length); } }
