1. 程式人生 > >POI-Excel匯入匯出 詳細實現程式碼

POI-Excel匯入匯出 詳細實現程式碼

1.介面效果:

                  1)點選批量匯入,彈出檔案選擇框,選擇檔案,點選開啟,檔案開始上傳。

                   

                  2)重複匯入人員校驗提示資訊

                   

2.頁面程式碼:

<a class="zdr-dr-btn" onclick="fileClick()">批量匯入</a>
<a class="zdr-down-btn" onclick="viewOnlineEvidence()">模板下載</a>
<input type="file" id="upfile" name="upfile" placeholder="" onchange="importExp(1);" style="display: none;"/>

3.JS程式碼:

//匯入檔案
function importExp(type) {
	var index = layer.load(1, {time: 20*1000});  // 呼叫載入層
	var formData = new FormData();
	var name = $("#upfile").val();
	formData.append("name",name);
	formData.append("file",$("#upfile")[0].files[0]);

	$.ajax({
		url : '/zdry/personInfo/uploadExcelController/uploadExcel?type='+type,
		type : 'POST',
		data : formData,
		//ajax2.0可以不用設定請求頭,但是jq幫我們自動設定了,這樣的話需要我們自己取消掉
		contentType:false,
		//取消幫我們格式化資料,是什麼就是什麼
		processData:false,
		success : function(data) {
			//關閉 載入層
			layer.close(index);
			if(data.state=="00"){
				layer.msg("匯入成功");
				window.location.href="/zdry/personInfo/weiwen";
			}else if(data.state=="01"){
				layer.msg("excel中身份證不能為空");
			}else if(data.state=="02"){
				layer.alert("以下人員已經存在,不可重複上傳!<br/>"+data.exsitCertNums, {icon: 0});
			}else{
				layer.msg("匯入失敗");
			}
		}
	});

	$("#upfile").val("");
}

function viewOnlineEvidence() {
	window.location.href="/zdry/personInfo/uploadExcelController/downloadExcel";
}

function fileClick(){
	$("#upfile").click();
}

4.Controller層程式碼:

    @Autowired
    private ExcelfileService exService; 

    @PostMapping(value = "/uploadExcel")
    @ResponseBody
    public JSONObject uploadExcel(@RequestParam(value = "file", required = false)MultipartFile file,Integer type) {
        JSONObject json = new JSONObject();
        try {
            json.put("state", "00");  // 成功
            List<PersonInfoDO> personInfoLists = new ArrayList<PersonInfoDO>();

            //使用POI解析Excel檔案
            //如果是xls,使用HSSFWorkbook;2003年的excel  如果是xlsx,使用XSSFWorkbook  2007年excel
            HSSFWorkbook workbook = new HSSFWorkbook(file.getInputStream());
            //根據名稱獲得指定Sheet物件
            HSSFSheet hssfSheet = workbook.getSheetAt(0);
            for (Row row : hssfSheet) {
                PersonInfoDO personInfo = new PersonInfoDO();
                personInfo.setType(type);      // 人員型別
                personInfo.setControlType(0);  // 預設為日常管控
                int rowNum = row.getRowNum();
                if(rowNum == 0){//跳出第一行   一般第一行都是表頭沒有資料意義
                    continue;
                }
                if(row.getCell(1)!=null){//第2列資料
                    row.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
                    personInfo.setName(row.getCell(1).getStringCellValue().trim() );
                }
                if(row.getCell(2)!=null){
                    row.getCell(2).setCellType(Cell.CELL_TYPE_STRING);
                    personInfo.setNativePolice(row.getCell(2).getStringCellValue().trim() );
                }
 

//	    		 轉換為Integer型別
//                if(row.getCell(3)!=null){//第4列
//                    row.getCell(3).setCellType(Cell.CELL_TYPE_STRING);
//                    personInfo.setAdduserid(Integer.parseInt(row.getCell(3).getStringCellValue()));
//                }
                //            轉換為日期型別
//                if(row.getCell(4)!=null){//第5列
//                    row.getCell(4).setCellType(Cell.CELL_TYPE_NUMERIC);
//                    personInfo.setAddtime( HSSFDateUtil.getJavaDate(row.getCell(4).getNumericCellValue()));
//                } 
                personInfoLists.add(personInfo); 
            }
            if(null != personInfoLists && personInfoLists.size()>0){
                String[] certNumArray = new String[personInfoLists.size()];
                for(int i=0;i<personInfoLists.size();i++){
                    certNumArray[i] =  personInfoLists.get(i).getCertNum();
                }
                Map<String,Object> map = new HashMap<String,Object>();
                map.put("type",type);
                map.put("certNumArray",certNumArray);

                // 查詢是否有重複
                List<PersonInfoDO>  list = exService.queryExcelList(map); 
                if(null != list && list.size()>0){ 
                    String exsitCertNums = "";
                    for(int i=0;i<list.size();i++){
                        exsitCertNums += "'"+list.get(i).getCertNum()+"',<br/>";
                    }
                    exsitCertNums = exsitCertNums.substring(0,exsitCertNums.length()-1);
                    json.put("state", "02");  // 人員已經存在,不可重複上傳
                    json.put("exsitCertNums", exsitCertNums);  // 重複人員身份證號碼
                    return json;
                } 
                //呼叫service執行儲存personInfoLists的方法
                exService.saveExcelList(personInfoLists); 
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return json;
    }

    @RequestMapping("/downloadExcel")
    public String downloadExcel(HttpServletRequest request, HttpServletResponse response) {
        String fileName = "mh_zdry.xls";// 設定檔名,根據業務需要替換成要下載的檔名
        if (fileName != null) {
            //設定檔案路徑
            String realPath = "E://excelModel";
            File file = new File(realPath , fileName);
            if (file.exists()) {
                response.setContentType("application/force-download");// 設定強制下載不開啟
                response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 設定檔名
                byte[] buffer = new byte[1024];
                FileInputStream fis = null;
                BufferedInputStream bis = null;
                try {
                    fis = new FileInputStream(file);
                    bis = new BufferedInputStream(fis);
                    OutputStream os = response.getOutputStream();
                    int i = bis.read(buffer);
                    while (i != -1) {
                        os.write(buffer, 0, i);
                        i = bis.read(buffer);
                    }
                    System.out.println("success");
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (bis != null) {
                        try {
                            bis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fis != null) {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        return null;
    }

5. service層程式碼:

void saveExcelList(List<PersonInfoDO> personInfoList);
List<PersonInfoDO>  queryExcelList(Map<String,Object> map);

6.service實現層程式碼:

    @Autowired
    private PersonInfoDao personInfoDao;

    public void saveExcelList(List<PersonInfoDO> personInfoList){
        for (PersonInfoDO personInfo : personInfoList) {
            //呼叫mapper的儲存方法
            personInfoDao.save(personInfo);
        }
    }

    public List<PersonInfoDO>  queryExcelList(Map<String,Object> map){
        //呼叫mapper的儲存方法
        return personInfoDao.queryList(map);
    }

7.Dao層程式碼:

List<PersonInfoDO> queryList(Map<String,Object> map);

8. Mbatis mapper.xml檔案:

<select id="queryList" resultType="com.bootdo.zdry.domain.PersonInfoDO">
		select `name`,`cert_num` from control_person_info
		<where>
		<if test="type != null and type != ''"> and type = #{type} </if>
		<if test="certNumArray != null and certNumArray != ''"> and cert_num in
			<foreach item="certNum" collection="certNumArray" open="(" separator="," close=")">
				#{certNum}
			</foreach>
		</if>
		</where>
	</select>

注意事項:

1.前臺頁面匯入只使用一個按鈕,方法 onchange="importExp(1);" 在結束後必須清除input中file的值,不然下次選擇同樣的檔案上傳,onchange方法不生效。

2.上傳檔案的ajax中必須有下面兩行的程式碼:

//ajax2.0可以不用設定請求頭,但是jq幫我們自動設定了,這樣的話需要我們自己取消掉
contentType:false,

//取消幫我們格式化資料,是什麼就是什麼
processData:false,

3.本次批量匯入過程前臺向後臺傳遞了2個引數:@RequestParam(value = "file", required = false)MultipartFile file,Integer type,使用mybatis傳遞多個引數的時候,必須封裝到map物件中:

Map<String,Object> map = new HashMap<String,Object>();
map.put("type",type);   // 匯入人員型別
map.put("certNumArray",certNumArray);   // 人員身份證陣列

// 查詢是否有重複
List<PersonInfoDO>  list = exService.queryExcelList(map);

map中的陣列物件,需要在mybatis中使用foreach元素和collection元素處理,collection的值為map中對應陣列的key值

<if test="certNumArray != null and certNumArray != ''"> and cert_num in
	<foreach item="certNum" collection="certNumArray" open="(" separator="," close=")">
		#{certNum}
	</foreach>
</if>

foreach的主要用在構建in條件中,它可以在SQL語句中進行迭代一個集合。

foreach元素的屬性主要有 item,index,collection,open,separator,close。

    item表示集合中每一個元素進行迭代時的別名,
    index指 定一個名字,用於表示在迭代過程中,每次迭代到的位置,
    open表示該語句以什麼開始,
    separator表示在每次進行迭代之間以什麼符號作為分隔 符,
    close表示以什麼結束。


在使用foreach的時候最關鍵的也是最容易出錯的就是collection屬性,該屬性是必須指定的,但是在不同情況 下,該屬性的值是不一樣的,主要有一下3種情況:

    1. 如果傳入的是單引數且引數型別是一個List的時候,collection屬性值為list
    2. 如果傳入的是單引數且引數型別是一個array陣列的時候,collection的屬性值為array
    3. 如果傳入的引數是多個的時候,我們就需要把它們封裝成一個Map了,當然單引數也可