Excel文件一键上传并解析导入数据库

文件上传和一键上传原理

文件上传需要具备以下几个条件:
客户端:
- Form表单必须指定Mime协议为:enctype=”multipart/form-data”,即采用多媒体表单数据编码;
- Form表单请求方式必须为post;
- Form表单中必须有<input type=”file” name=”xxx”/>文本框,必须提供name属性。

服务端:
- JavaWeb:Apache commons-fileupload工具包实现上传;
- Struts2:提供了FileUploadInterceptor拦截器,将Apache commons-fileupload进行了封装,使用更简单。
上述客户端在上传的时候,先浏览文件,将文件路径存入表单,然后再通过form表单提交,将其提交到服务端。
为提升用户体验(UE),现在的系统流行一键上传,即用户点击了上传按钮或链接后,直接选择要上传的文件,点击确定就开始上传了,无需额外提交表单。而且页面无刷新。

客户端–使用jQuery ocupload插件实现一键上传

Ocupload即One-click upload,一键上传。
插件下载:http://code.google.com/p/ocupload
插件的使用:

1.项目和页面中引入js

2.插件在页面的编码使用

官方示例:

$(element).upload({
                name: 'file',//上传组件的name属性,即<input type='file' name='file'/>
                action: '',//向服务器请求的路径
                enctype: 'multipart/form-data',//mime类型,默认即可
                params: {},//请求时额外传递的参数,默认为空
                autoSubmit: true,//是否自动提交,即当选择了文件,自动关闭了选择窗口后,是否自动提交请求。
                onSubmit: function() {},//提交表单之前触发事件
                onComplete: function() {},//提交表单完成后触发的事件
                onSelect: function() {}//当用户选择了一个文件后触发事件
        });

开发代码:

//给导入按钮绑定一键上传插件
        $("#button-import").upload({
                name: 'upload',//上传组件的name属性,即<input type='file' name='upload'/>
                action: '${pageContext.request.contextPath}/region_importData.action',//向服务器请求的路径
                onComplete: function(response) {//提交表单完成后触发的事件
                    //response是响应后放到页面的一个json'字符串,不是json对象
                    //转换为json对象
                    var data =eval("("+response+")");
                    if(data.result){
                        $.messager.alert("信息","文件上传成功","info");
                    }else{
                        $.messager.alert("错误","文件上传失败","error");
                    }
                },
                onSelect: function() {//当用户选择了一个文件后触发事件
                    //当选择了文件后,关闭自动提交
                    this.autoSubmit=false;
                    //校验上传的文件名是否满足后缀为.xls或.xlsx
                    //var regex =/^.*\.(?:xls|xlsx)$/;
                    var regex =/^.*\.xlsx?$/i;
                    //this.filename()返回当前选择的文件名称
                    if(regex.test(this.filename())){
                        //通过校验
                        this.submit();
                    }else{
                        //未通过
                        $.messager.alert("警告","文件格式不正确,必须以.xls或xlsx结尾","warning")
                    }
                }
        });

服务端–使用Apache POI解析Excel数据并入库

使用fileUpload拦截器:
[File Name] : File - the actual File
[File Name]ContentType : String - the content type of the file
[File Name]FileName : String - the actual name of the file uploaded (not the HTML name)

Java界常见的解析Excel文档的开源项目有两种:Apache POI和 JXL。

Apache POI

POI的功能可以解析微软的Office组件的文档格式。
企业中通常使用其解析Excel文档或生成Excel文档(SS)。
POI支持HSSF解析(.xls–Excel97-2007之前版本,仅支持65535行记录)和XSSF解析(.xlsx–Excel2007及以后版本)。

一. 使用Maven的坐标引入POI(根据需要可以引入HSSF和XSSF的):

    <poi.version>3.9</poi.version>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${poi.version}</version>
        </dependency>

二. 编写解析Excel的代码。
POI解析的基本过程:打开WorkBook工作簿文件—》找到Sheet工作表—》遍历读取Rows行—》读取行中的cell单元格。

@ParentPackage("basicstruts2")
        @Controller("regionAction")
        @Scope("prototype")
        @Namespace("/")
        public class RegionAction extends BaseAction<Region> {
            //上传文件属性
            private File upload;//上传的文件,名字必须和表单的name属性一致
            private String uploadFileName;//文件名
            private String uploadContextType;//文件类型
            public void setUpload(File upload) {
                this.upload = upload;
            }
            public void setUploadFileName(String uploadFileName) {
                this.uploadFileName = uploadFileName;
            }
            public void setUploadContextType(String uploadContextType) {
                this.uploadContextType = uploadContextType;
            }

            //注入service
            @Autowired
            private RegionService regionService;

            /** * 区域文件上传 * @return * @throws Exception */
            @Action(value="region_upload",,results={@Result(name=JSON,type=JSON)})
            public String upload()throws Exception{
                //获取客户端上传的文件(使用属性驱动+fileUpload拦截器)

                //存放结果集map
                Map<String,Object> resultMap = new HashMap<String,Object>();
                //存放region的list
                List<Region> regionList = new ArrayList<Region>();

                try {
                    //解析excel
                    //1.读取文件输入流
                    InputStream is = new FileInputStream(upload);
                    //2.创建Excel工作簿文件(包含.xsl和.xslx格式)
                    Workbook wb = WorkbookFactory.create(is);
                    //3.打开需要解析的Sheet工作表
                    Sheet sheet = wb.getSheetAt(0);
                    //4.遍历工作表对象(本质是个行的集合),读取每一行
                    for (Row row : sheet) {
                        //跳过第一行
                        if (row.getRowNum() == 0) {
                            continue;
                        }

                        //另外,一般第一列都标识列,如果第一个格没数据,则认为该行数据无效,要跳过
                        //注意:getStringCellValue()读取的格必须是文本,否则抛异常
                        if (StringUtils.isNotBlank(row.getCell(0).getStringCellValue())) {
                            Region region = new Region();
                            region.setId(row.getCell(0).getStringCellValue());
                            region.setProvince(row.getCell(1).getStringCellValue());
                            region.setCity(row.getCell(2).getStringCellValue());
                            region.setDistrict(row.getCell(3).getStringCellValue());
                            region.setPostcode(row.getCell(4).getStringCellValue());    

                            regionList.add(region);
                        }
                    }

                    //调用service保存数据
                    regionService.saveRegionBatch(regionList);

                    //解析成功
                    resultMap.put("result", true);

                    //关流
                    is.close();
                } catch (Exception e) {
                    e.printStackTrace();
                    //解析失败
                    resultMap.put("result", false);
                }
                //将装有结果集的map压入栈顶
                pushToValueStack(resultMap);
                //返回json类型
                return JSON;
            }
        }

你可能感兴趣的:(文件上传,解析excel)