1. 程式人生 > >JAVA POI批量匯入EXCEL資料到資料庫

JAVA POI批量匯入EXCEL資料到資料庫

首先先記錄下碰到的問題: 

原先想直接傳要上傳的檔案路徑到後端,然後後端絕對定位到相應檔案進行資料的解析,後面發現瀏覽器這邊為了安全問題,是不能獲得檔案的真實路徑的,只能獲得一個虛假的路徑,然後這種做法就行不通了,我的解決方法是先把檔案上傳的到後端相關目錄,解析完資料後在將對應的檔案刪除

下面貼程式碼:

	        		<form id="monitordocform" enctype="multipart/form-data" style="padding-top: 10px;" action="monitor/excelData">
	                        <div class="file-input file-input-new">
	                        <div class="file-preview ">
	    						<div class="close fileinput-remove">×</div>
	    							<div class="file-drop-disabled">
						    <div class="file-preview-thumbnails">
						    </div>
						    <div class="clearfix"></div>    
						    <div class="file-preview-status text-center text-success"></div>
						    <div class="kv-fileinput-error file-error-message" style="display: none;"></div>
						    </div>
						</div>
						<div class="kv-upload-progress hide"><div class="progress">
						    <div class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%;">
						        0%
						     </div>
						</div></div>
						
						<div class="input-group file-caption-main">
						   <div tabindex="500" class="form-control file-caption  kv-fileinput-caption">
						   <div class="file-caption-name" id="monitordocpath"></div>
						</div>
						
						   <div class="input-group-btn" >
						       <button type="button" tabindex="500" title="Clear selected files" class="btn btn-default fileinput-remove fileinput-remove-button"><i class="glyphicon glyphicon-trash"></i>  <span class="hidden-xs">移除</span></button>
						       <button type="button" tabindex="500" title="Abort ongoing upload" class="btn btn-default hide fileinput-cancel fileinput-cancel-button"><i class="glyphicon glyphicon-ban-circle"></i>  <span class="hidden-xs">取消</span></button>
						       <button type="submit" tabindex="500" title="Upload selected files" class="btn btn-default fileinput-upload fileinput-upload-button">
						       <i class="glyphicon glyphicon-upload"></i>  <span class="hidden-xs">上傳</span></button>
						       <div tabindex="500" class="btn btn-primary btn-file" style="background-color: #0093DF;">
							       <i class="glyphicon glyphicon-folder-open"></i>   
							       <span class="hidden-xs">選擇檔案</span>
							       <input  type="file" id="monitordoc" name="monitordoc" onchange="showPath(this)">
						       </div>
						   </div>
						</div>
						</div>
						
	                    <br>
		        		<div class="uploadtips">提示:請上傳您要分發的圖斑資料,格式.xls/.xlsx </div>  
                    </form>
傳輸檔案 form表單要加上 
enctype="multipart/form-data" 

這個屬性,

JS中AJAX上傳檔案的格式:

function excelData(){
	var monitordocpath=$("#monitordocpath").text();
	if(monitordocpath!=null && monitordocpath!=""){
		var form = new FormData(document.getElementById("monitordocform"));
		$.ajax({
		    url:  "monitor/excelData",
		    type: 'POST',
		    data: form,
		    processData: false,
		    contentType : false,
		    success:function(data){
		    	alert(data);
		    	if(data=="true" || data==true){
		    		$("#monitorspotgrid").mtable("reload");
		    		closeMonitorUploadWin();
		    		$.mal({
						text : '匯入成功',
						type : 'success' 
					});
		    	}else{
		    		$.mal({
						text : '匯入失敗',
						type : 'error'
					});
		    	}
            },
            error:function(e){
             
            }
		})
		
	
	}else{
		$.mal({
			text : '請先選擇檔案',
			type : 'warning'
		});
	}
}

JAVA後臺程式碼的處理方法:

@ResponseBody
	@RequestMapping(value="excelData",method = RequestMethod.POST)
	public String excelData(HttpServletRequest request,HttpServletResponse response,@RequestParam("monitordoc")MultipartFile monitordoc){
    	// 上傳檔案路徑
		String path = request.getSession().getServletContext().getRealPath("/upload/");
		System.out.println(path);
		// 上傳檔名
		String fileName = monitordoc.getOriginalFilename();
		if(fileName.endsWith("xls") || fileName.endsWith("xlsx")){
		File file=new File(path+File.separator+fileName);
		ShardedJedisProvider jedis=JedisManager.getShardedJedis("redis"); //根據需要獲取相關資料
		String sessionId = GetSessionID(request, response);
		String tenantId = jedis.hget("userkey:"+sessionId, "tenantId");
		try {
			monitordoc.transferTo(file);//先將上傳的檔案儲存
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		List<PdaOneMapMonitorSpotModel>list=paseExcel(file,tenantId,fileName);//解析上傳的Excel資料
		Integer result=pdaOneMapMonitorSpotService.batchInsert(list);
		if (result>0) {
			 return "true";
		}else {
			return  "false";
		}
		}else {
			return "false";
		}
      }
	

解析Excel資料的方法

	public List<PdaOneMapMonitorSpotModel> paseExcel(File f,String tenantId,String fileName){
			String path=f.getPath();
			List<PdaOneMapMonitorSpotModel>list=new ArrayList<PdaOneMapMonitorSpotModel>();
			FileInputStream fis =null;
			Map<String, Object>map=new HashMap<String, Object>();
	        Workbook wookbook = null;
	        //XSSFWorkbook ss=null;
	        int flag = 0;
	        
	        try{
	            //獲取一個絕對地址的流
	              fis = new FileInputStream(f);
	        }
	        catch(Exception e){
	        	deleteExcel(path);
	            e.printStackTrace();
	        }
	       
	        try {
				if(fileName.endsWith("xls")){
					 //2003版本的excel,用.xls結尾
					  wookbook = new HSSFWorkbook(fis);//得到工作簿
				}else {
					 //2007版本的excel,用.xlsx結尾                 
	                   wookbook = new XSSFWorkbook(fis);//得到工作簿
				}
	          
	        }  catch (Exception ex) {        	 
	        	ex.printStackTrace();
	        	 deleteExcel(path);
	        }
	        
	        //得到一個工作表
	        Sheet sheet = wookbook.getSheetAt(0);
	        
	        //獲得表頭
	        Row rowHead = sheet.getRow(0);
	        
	      //根據不同的data放置不同的表頭
	        Map<Object,Integer> headMap = new HashMap<Object, Integer>(); 
	        
	        try{
	            //----------------這裡根據你的表格有多少列
	            while (flag < rowHead.getPhysicalNumberOfCells())
	            {
	                Cell cell = rowHead.getCell(flag);
	                if (getRightTypeCell(cell).toString().equals("標識碼"))
	                {
	                    headMap.put("bsm", flag);
	                }
	                if (getRightTypeCell(cell).toString().equals("監測編號"))
	                {
	                    headMap.put("jcbh", flag);
	                }
	                if (getRightTypeCell(cell).toString().equals("圖斑型別"))
	                {
	                    headMap.put("tblx", flag);
	                }
	                if (getRightTypeCell(cell).toString().equals("監測面積(畝)"))
	                {
	                    headMap.put("jcmj", flag);
	                }
	                if (getRightTypeCell(cell).toString().equals("變更後地類"))
	                {
	                    headMap.put("bghdl", flag);
	                }
	                if (getRightTypeCell(cell).toString().equals("變更範圍情況"))
	                {
	                    headMap.put("bgfwqk", flag);
	                }
	                
	                if (getRightTypeCell(cell).toString().equals("未變更原因"))
	                {
	                    headMap.put("wbgyy", flag);
	                }
	                if (getRightTypeCell(cell).toString().equals("備註"))
	                {
	                    headMap.put("bz", flag);
	                }
	                if (getRightTypeCell(cell).toString().equals("接收人員"))
	                {
	                    headMap.put("jsry", flag);
	                }
	                if (getRightTypeCell(cell).toString().equals("分發狀態"))
	                {
	                    headMap.put("ffzt", flag);
	                }
	                
	                flag++;
	            }
	        } catch (Exception e){
	        	deleteExcel(path);
	            e.printStackTrace();
	            System.out.println("表頭不合規範,請修改後重新匯入");
	        }
	        
	        
	        //獲得資料的總行數
	        int totalRowNum = sheet.getLastRowNum();
	        
	        if(0 == totalRowNum){
	            System.out.println("Excel內沒有資料!");
	        }
	        
	        Cell cell_1 = null,cell_2 = null; Cell cell_3 = null,cell_4 = null; Cell cell_5 = null,cell_6 = null; 
	        Cell cell_7 = null,cell_8 = null;Cell cell_9 = null,cell_10 = null;
	       //獲得所有資料
	        for(int i = 1 ; i <= totalRowNum ; i++){
	            //獲得第i行物件
	            Row row = sheet.getRow(i);
		        PdaOneMapMonitorSpotModel pdaOneMapMonitorSpotModel=new PdaOneMapMonitorSpotModel();
	            try{
	                cell_1 = row.getCell(headMap.get("bsm"));
	                cell_2 = row.getCell(headMap.get("jcbh"));
	                cell_3 = row.getCell(headMap.get("tblx"));
	                cell_4 = row.getCell(headMap.get("jcmj"));
	                cell_5 = row.getCell(headMap.get("bghdl"));
	                cell_6 = row.getCell(headMap.get("bgfwqk"));
	                cell_7 = row.getCell(headMap.get("wbgyy"));
	                cell_8 = row.getCell(headMap.get("bz"));
	                cell_9 = row.getCell(headMap.get("jsry"));
	                cell_10 = row.getCell(headMap.get("ffzt"));
	            } catch (Exception e){
	                e.printStackTrace();
	                System.out.println("獲取單元格錯誤");
	            	deleteExcel(path);
	            }
	            
	            try{
	                pdaOneMapMonitorSpotModel.setMonitorNum((String)getRightTypeCell(cell_2));
	                pdaOneMapMonitorSpotModel.setMapType((String)getRightTypeCell(cell_3));
	                pdaOneMapMonitorSpotModel.setMonitorArea((String)getRightTypeCell(cell_4));
	                pdaOneMapMonitorSpotModel.setChangeClass((String)getRightTypeCell(cell_5));
	                pdaOneMapMonitorSpotModel.setChangeRange((String)getRightTypeCell(cell_6));
	                pdaOneMapMonitorSpotModel.setCause((String)getRightTypeCell(cell_7));
	                pdaOneMapMonitorSpotModel.setRemark((String)getRightTypeCell(cell_8));
	                if (cell_10.equals("已分發")) {
		                pdaOneMapMonitorSpotModel.setDistributeStatus("1");
					}else{
						 pdaOneMapMonitorSpotModel.setDistributeStatus("0");
					}
	                pdaOneMapMonitorSpotModel.setTenantId(tenantId);
	                list.add(pdaOneMapMonitorSpotModel);
	                
	            } catch (ClassCastException e){	
	            	deleteExcel(path);
	                e.printStackTrace();
	            }
	        }
	    	deleteExcel(path);
	        return list;
	        
	}

解析成功或者出現異常的情況下都將上傳的檔案刪除,呼叫deleteExcel方法

/**
	 * 刪除指定路徑下的Excel
	 * @param path
	 * @return
	 */
	public String deleteExcel(String path){

		 try {
			 //目錄路徑
		   	 File target=new File(path);
			 //刪檔案
			 target.delete();
		} catch (Exception e) {
			return "false";
		}
		return "true";
	}

返回單元格資料型別的函式:

 /**
     *     
     * @param cell 一個單元格的物件
     * @return 返回該單元格相應的型別的值
     */
    public static Object getRightTypeCell(Cell cell){
    
        Object object = null;
        switch(cell.getCellType())
        {
            case Cell.CELL_TYPE_STRING :
            {
                object=cell.getStringCellValue();
                break;
            }
            case Cell.CELL_TYPE_NUMERIC :
            {
                cell.setCellType(Cell.CELL_TYPE_NUMERIC);
                object=cell.getNumericCellValue();
                break;
            }
                
            case Cell.CELL_TYPE_FORMULA :
            {
                cell.setCellType(Cell.CELL_TYPE_NUMERIC);
                object=cell.getNumericCellValue();
                break;
            }
            
            case Cell.CELL_TYPE_BLANK :
            {
                cell.setCellType(Cell.CELL_TYPE_BLANK);
                object=cell.getStringCellValue();
                break;
            }
        }
        return object;
    }    

暫時就這樣解決,如果有能夠不用儲存先儲存檔案到伺服器就能夠解析要上傳檔案的資料的方法的話,歡迎大神指教!