Java Controller下兼容xls和xlsx且可識別合並單元格的excel導入功能


1.工具類,讀取單元格數據的時候,如果當前單元格是合並單元格,會自動讀取合並單元格的值

  1 package com.shjh.core.util;
  2 import java.io.IOException;
  3 import java.io.InputStream;
  4 
  5 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  6 import org.apache.poi.ss.usermodel.Cell;
  7 import org.apache.poi.ss.usermodel.Row;
  8 import org.apache.poi.ss.usermodel.Sheet;
  9 import org.apache.poi.ss.usermodel.Workbook;
 10 import org.apache.poi.ss.util.CellRangeAddress;
 11 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 12 
 13 public class ExcelReaderUtil {
 14         private static final String EXTENSION_XLS = "xls";
 15         private static final String EXTENSION_XLSX = "xlsx";
 16         private Workbook workbook = null;
 17         private Sheet sheet = null;//
 18         private int sheetNum = 0; // 第sheetnum個工作表
 19         
 20         public void setWorkbook(Workbook workbook) {
 21             this.workbook = workbook;
 22         }
 23 
 24         public void setSheet(Sheet sheet) {
 25             this.sheet = sheet;
 26         }
 27 
 28         public void setSheetNum(int sheetNum) {
 29             this.sheetNum = sheetNum;
 30         }
 31 
 32         public ExcelReaderUtil() {
 33         }
 34 
 35         public ExcelReaderUtil(InputStream inputStream,String fileName) throws IOException {
 36             if (fileName.endsWith(EXTENSION_XLS)) {
 37                 workbook = new HSSFWorkbook(inputStream);
 38             } else if (fileName.endsWith(EXTENSION_XLSX)) {
 39                 workbook = new XSSFWorkbook(inputStream);
 40             }
 41         }
 42 
 43         /**
 44          * 指定工作表、行、列下的內容
 45          * 
 46          * @param sheetNum
 47          * @param rowNum
 48          * @param cellNum
 49          * @return String
 50          */
 51         public String getCellValue(int rowNum, int colNum) {
 52             if (sheetNum < 0 || rowNum < 0){
 53                 return "";
 54             }
 55             String strExcelCell = "";
 56             try {
 57                 sheet = this.workbook.getSheetAt(sheetNum);
 58                 //判斷是否是合並單元格,如果是,就將行、列索引改為合並單元格的索引
 59                 for(int numMR = 0; numMR < this.sheet.getNumMergedRegions(); numMR++){
 60                       //獲取合並單元格
 61                       CellRangeAddress cellRangeAddress = this.sheet.getMergedRegion(numMR);
 62                       int firstColumnInd = cellRangeAddress.getFirstColumn();    
 63                       int lastColumnInd = cellRangeAddress.getLastColumn();    
 64                       int firstRowInd = cellRangeAddress.getFirstRow();    
 65                       int lastRowInd = cellRangeAddress.getLastRow();    
 66                       //如果當前單元格在這個合並單元格里
 67                       if(rowNum >= firstRowInd && rowNum <= lastRowInd && colNum >= firstColumnInd && colNum <= lastColumnInd){    
 68                           rowNum = firstRowInd;
 69                           colNum = firstColumnInd;
 70                           break;
 71                       }  
 72                 }
 73                 Row row = sheet.getRow(rowNum);
 74                 if (row.getCell((short) colNum) != null) { 
 75                     switch (row.getCell((short) colNum).getCellType()) {
 76                     case Cell.CELL_TYPE_FORMULA:
 77                         strExcelCell = "FORMULA ";
 78                         break;
 79                     case Cell.CELL_TYPE_NUMERIC: {
 80                         strExcelCell = String.valueOf(row.getCell((short) colNum).getNumericCellValue());
 81                     }
 82                         break;
 83                     case Cell.CELL_TYPE_STRING:
 84                         strExcelCell = row.getCell((short) colNum).getStringCellValue();
 85                         break;
 86                     case Cell.CELL_TYPE_BLANK:
 87                         strExcelCell = "";
 88                         break;
 89                     default:
 90                         strExcelCell = "";
 91                         break;
 92                     }
 93                 }
 94             } catch (Exception e) {
 95                 e.printStackTrace();
 96             }
 97             return strExcelCell;
 98         }
 99         
100         /**
101          * sheetNum下的記錄行數
102          * 
103          * @return int
104          */
105         public int getRowCount() {
106             Sheet sheet = workbook.getSheetAt(this.sheetNum);
107             int rowCount = -1;
108             rowCount = sheet.getLastRowNum();
109             return rowCount;
110         }
111 }

2.Controller內調用,尤其要注意傳參部分的寫法,需要加上注解,且變量名必須和jsp頁面里對應的參數名要完全一致。

 1     @RequestMapping(value="/excelUpload")
 2     public void excelUpload(@RequestParam MultipartFile fileToUpload,@RequestParam String tableGroupId, HttpServletRequest request, HttpServletResponse response){
 3         int nullLine=0;
 4         String errorStr = "";
 5         try {
 6             ExcelReaderUtil readExcel = new ExcelReaderUtil(fileToUpload.getInputStream(),fileToUpload.getOriginalFilename());
 7             readExcel.setSheetNum(0); // 設置讀取索引為0的工作表
 8             Map<String,String> checkRepeatMap=new HashMap<String,String>();//檢驗數據是否正常的集合
 9             List<String> tabIdList=new ArrayList<String>();//最終得到的tableid集合
10             /*這里為循環校驗數據*/
11             for (int i = 2; i < readExcel.getRowCount()+1; i++) {
12                 String error="";
13                 //庫名,先判斷是否在合並單元格內,若有則取合並單元格的值
14                 String dataName=readExcel.getCellValue(i, 0).trim();//
15                 String moduleName1=readExcel.getCellValue(i, 1).trim();//一級模塊
16                 String moduleName2=readExcel.getCellValue(i, 2).trim();//二級模塊
17                 String moduleName3=readExcel.getCellValue(i, 3).trim();//三級模塊
18                 //String tableChiName=rows[4]==null ? "" :rows[4].trim();//表中文名  *暫時用不上
19                 String tableEnName=readExcel.getCellValue(i, 5).trim().toUpperCase();//表物理名
20                 //空行校驗
21                 if(StringUtils.isBlank(dataName) && StringUtils.isBlank(moduleName1) && StringUtils.isBlank(moduleName2) && StringUtils.isBlank(moduleName3) && StringUtils.isBlank(tableEnName))
22                 {
23                     nullLine++;
24                     continue;
25                 }
26                 
27                 //空校驗
28                 if(StringUtils.isBlank(tableEnName) )
29                 {
30                     error ="\n第"+(i+1)+"行:表物理名不能為空。\n";
31                     errorStr+=error;
32                     continue;
33                 }
34                 String mapValue=dataName+moduleName1+moduleName2+moduleName3+tableEnName;
35                 if(checkRepeatMap.containsValue(mapValue)){
36                     error ="\n第"+(i+1)+"行:該行數據為重復數據,請刪除該行后重新提交。\n";
37                     errorStr+=error;
38                     continue;
39                 }else{
40                     checkRepeatMap.put((i+1)+"",mapValue);
41                 }
42                 /*各種校驗*/
43             }
44             
45             if (StringUtils.isNotBlank(errorStr)) {
46                 int errorCount=readExcel.getRowCount()-1-tabIdList.size()-nullLine;
47                 OutPutUtil.ajaxOut(response, "導入失敗!有"+errorCount+"條數據存在問題,請修正后再次導入:\n"+errorStr);
48             } else {
49                 /*保存操作*/
50             }
51         } catch (Exception e) {
52             //logger.error("批量導入出錯:"+e.getMessage().toString());
53             OutPutUtil.ajaxOut(response, "批量導入出錯:"+e.getMessage().toString());
54             e.printStackTrace();
55         }
56     }

 

3.js代碼,這里需要引用  ajaxfileupload.js 插件。參數名與controller里傳入的參數名要一致。

 1         function ajaxFileUpload(){
 2                      if (checkFile()) { //此函數就不貼了,就是判斷一下文件后綴名是否正確
 3                         //彈出遮蓋層
 4                         $("#loadingDiv").show();
 5                         var tableGroupId = $("#tableGroupParam").val();
 6                         $.ajaxFileUpload({
 7                              url:'<%=basePath %>userController/excelUpload.do?tableGroupId='+tableGroupId,
 8                              secureuri:false,
 9                              fileElementId:'fileToUpload', //文件選擇框的id屬性
10                              dataType: 'text',//服務器返回的格式,可以是json
11                              //相當於java中try語句塊的用法
12                              success:function (data, status) {
13                                  //關閉遮蓋層
14                                  $("#loadingDiv").hide();
15                                   alert(data);
16                              },
17                              error:function (data, status, e) {
18                                  alert("導入出錯:"+data);
19                                 }
20                             
21                             });
22                         
23                      } 
24          }

 

4.html代碼,就是用到了file控件,沒什么特別的

1         <div class="easyui-dialog" id="role-jurisdiction-dlg2" data-options="title:'批量導入',closed:true" style="width:400px;height:100px;">
2             <input type="hidden" id="tableGroupParam" value="0" class="input-xs" disabled="disabled">
3             <div id="loadingDiv">
4                 <img src="<%=basePath %>/img/loading.gif" style="margin-top:5px;margin-left:120px;" /> 
5             </div>
6             <input type="file" name="fileToUpload" id="fileToUpload" size="300" style="width:300px" onchange="checkFile();">
7             <input type="button" name="btnUpload" value="上 傳" id="btnUpload" style="width:60px" onclick="ajaxFileUpload();" />
8         </div>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM