Java POI 批量导入功能升级版

来源:互联网 发布:好用的飞机杯 知乎 编辑:程序博客网 时间:2024/04/29 19:58

之前有做过导入的功能,也写过,之前的导入: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、循环过后的数据格式如下:(表格第一列数据,表格 第二列数据, 表格第三列数据, ....),(表格第一列数据,表格 第二列数据, 表格第三列数据, ....) , ..... ,这样就做到了批量;

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

1 0
原创粉丝点击