POI-Excel导入导出 详细实现代码

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yuzongtao/article/details/82114183

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了,当然单参数也可

猜你喜欢

转载自blog.csdn.net/yuzongtao/article/details/82114183