Java POI 批量导入功能升级版

31 篇文章 1 订阅
31 篇文章 0 订阅

之前有做过导入的功能,也写过,之前的导入:http://blog.csdn.net/u014266877/article/details/53691572

先来个效果图镇楼:


这次是升级版,优化过后的导入功能,首先步骤是一样的,不过减少了很多代码,下面开始导入之旅:

1、还是先上传导入的文件到服务器,这里不在介绍上传文件,可以参考博客(后面有时间会写文件上传):

http://www.open-open.com/lib/view/open1342167969281.html

2、控制层:

    /**
     * @Description 导入数据
     * @author        <p style="color:#8e8e8e;font-family:微软雅黑;font-size=16px;font-weight:bold;">Cloud</p>
     * @date        <p style="color:#000;font-family:微软雅黑;font-size=16px;">2017-1-12下午2:31:03</p> 
     * @param request
     * @param path
     * @return
     */
    @RequestMapping(value = "/interfaceLeadingIn")
    @SuppressWarnings("static-access")
    @ResponseBody
    public JSONObject interfaceLeadingIn(HttpServletRequest request, String path){
        JSONObject json = new JSONObject();
        String returnCode = new String();
        try {
            //登陆帐号
            String loginAccount = (String) request.getSession().getAttribute("userName");
            //远程读取服务器文件
            URL url = new URL(path);
            URLConnection conn = url.openConnection();
            //文件输入流信息
            InputStream is = conn.getInputStream();
            /*
             *  Workbook、Sheet、Row、Cell等为接口;
             *    1) HSSFWorkbook、HSSFSheet、HSSFRow、HSSFCell为97-2003版本对应的处理实现类;
             *    2) XSSFWorkbook、XSSFSheet、XSSFRow、XSSFCell为2007+版本对应的处理实现类;
             */
            XSSFWorkbook hssfWorkbook = new XSSFWorkbook(is);
            //用于接收表格数据, 以第几行数据为Key, 数据用 List<String> 接收
            Map<Integer, List<String>> dataMap = new HashMap<Integer, List<String>>();
            //循环excel表格每行数据
            for (int numSheet = 0; numSheet < hssfWorkbook.getNumberOfSheets(); numSheet++) {
                XSSFSheet hssfSheet = hssfWorkbook.getSheetAt(numSheet);
                if (hssfSheet == null) {
                    continue;
                }
                //循环读取每行所有列数据
                for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
                    XSSFRow hssfRow = hssfSheet.getRow(rowNum);
                    if(hssfRow != null){
                        List<String> list = new ArrayList<String>();
                        //将表格自每行数据添加到 list中 (list 集合的数据是有序号的 方便数据对应)
                        for (int i = 0; i < 28; i++) {// 28 代表导入 excel 模板中的列数
                            XSSFCell xssfCell = hssfRow.getCell(i);
                            //初始化列值(不建议导入数据库对应表添加过多非空校验, 导入数据可能为空)
                            String date = null;
                            //预防空指针
                            if(xssfCell != null){
                                //17 列 18 列(下标从0开始 16就是17列)是时间类型, 默认用 String 类型接收
                                if(i == 16 || i == 17){
                                    date = Common.fromDateY(xssfCell.getDateCellValue());
                                }else{
                                    date = String.valueOf(xssfCell);
                                }
                            }
                            list.add(date);
                        }
                        //这些数据不是表格中的 保存 登陆用户, 添加时间, 状态, 显示
                        list.add(1 + "");
                        list.add(loginAccount);
                        list.add(Common.fromDateH());
                        list.add(1 + "");
                        dataMap.put(numSheet, list);
                    }
                }
            }
            //既然是批量操作, 在 MyBatis 中要取值, 所以还要一个 Map 来保存所有数据, 方便取值
            Map<String, Map<Integer, List<String>>> leadingInData = new HashMap<String, Map<Integer, List<String>>>();
            leadingInData.put("leadingInData", dataMap);
            if(!dataMap.isEmpty()){
                int circleInsertInterface = interfaceConcludeSignServiceImpl.circleInsertInterface(leadingInData);
                if(circleInsertInterface > 0){
                    returnCode = new String(ReturnCode.LEADINGIN_SUCCESS.toString());
                }else{
                    returnCode = new String(ReturnCode.LEADINGIN_ERROR.toString());
                }
            }else{
                returnCode = new String(ReturnCode.FILE_NULL.toString());
            }
        } catch (Exception e) {
            //异常信息    org.apache.poi.POIXMLException: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13]
            //目前导入只兼容 excel 2007 以上版本, 不再支持 excel 2003
            returnCode = new String(ReturnCode.OPERATE_ERROR.toString());
            e.printStackTrace();
        }
        return json.fromObject(returnCode);
    }
3、Dao层:

	/**
	 * 循环插入已签接口	导入数据
	 * @param 导入数据
	 * @return	成功/失败
	 */
	public int circleInsertInterface(Map<String, Map<Integer, List<String>>> data);

4、Mybatis mapper insert sql:

	<!-- 批量添加已签接口 -->
	<insert id="circleInsertInterface" parameterType="map">
		INSERT INTO interface_conclude_sign(
			interface_name,
			parent_interface_name,
			son_interface_name,
			interface_remark,
			catalog_name,
			tiny_catalog,
			out_parameter,
			put_parameter,
			buy_price,
			pack_name,
			company_name,
			company_code,
			company_abutment,
			company_tel,
			channel_area,
			channel_user,
			pact_sttime,
			pact_entime,
			product_model,
			type,
			scope,
			test_scope,
			upd_rate,
			remark,
			cell_url,
			test_url,
			upd_info,
			platform_price,
			status,
			add_user,
			add_time,
			is_show
		) VALUES 
		<foreach collection="leadingInData" item="map_item" index="i" separator=",">
			(
				<foreach collection="map_item" item="list_item" index="j" separator=",">
					#{list_item}
				</foreach>
			)
		</foreach>
	</insert>


5、Jsp 代码:

<a href="#" id="input-btn" class="easyui-linkbutton" iconcls="icon-redo">导入</a>


6、Js 程序:

<script type="text/javascript" charset="utf-8" src="<%=path%>/js/ajaxfileupload.js"></script>):

    // 导入按钮
    $("#input-btn").on("click",function(){
        $("#fileBtn1").trigger("click");
    });
    
    // 数据导入
    $(document).on("change","#fileBtn1",function(){
        $.ajaxFileUpload({
            url: "<%=path%>/uploadImage/exportUpload",
            fileElementId :'fileBtn1',
            dataType : 'json',
            success: function(data){
                var result = $.parseJSON(data.returnCode);
                if(result.code != "0030"){
                    $.messager.alert('信息提示',result.message,'info');
                }else{
                    $.ajax({
                        url: '<%=path%>/interfaceSign/interfaceLeadingIn',
                        data: {
                            path:"${image_url}" + data.url
                        },success:function(data){
                            $.messager.alert('信息提示',data.message,'info');
                            $("#viewList").datagrid("unselectAll");
                            $("#viewList").datagrid("reload");
                        }
                    });
                }
            },
            error : function() {  
                $.messager.alert('失败提示','系统异常,操作失败','error');
            }
        });
    });

--------------------------------------------------------  总结  --------------------------------------------------------

写了一天的时间,最终还是有成果的,非常开心,在Mybatis 中双重 for 循环,很少用到吧,我也是第一次,很赞的方法:

下面介绍下核心:

1、首先是一对一(哈哈只不过是表格列对应,insert 中的列啦!),这就是之前用 List 的原因

2、核心是mapper 中的双重 for 循环,首先看下如下代码:

//既然是批量操作, 在 MyBatis 中要取值, 所以还要一个 Map 来保存所有数据, 方便取值
Map<String, Map<Integer, List<String>>> leadingInData = new HashMap<String, Map<Integer, List<String>>>();

<foreach collection="leadingInData" item="map_item" index="i" separator=",">
 (
    <foreach collection="map_item" item="list_item" index="j" separator=",">
        #{list_item}
    </foreach>
 )
</foreach>
2.1、leadingInData 中是表格中所有数据,每行数据都在其中,第一个 for 循环用来循环表格所有行;

2.2、leadingInData 中每行数据中要是一个 List 集合,包含一行所有列数据,所以要第二个 for 循环;

2.3、循环过后的数据格式如下:(表格第一列数据,表格 第二列数据, 表格第三列数据, ....),(表格第一列数据,表格 第二列数据, 表格第三列数据, ....) , ..... ,这样就做到了批量;

因为项目中只有一个导入功能,所有没有写成工具类,感兴趣的同学可以多加优化,欢迎吐槽;

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值