利用Apache的相应jar包,写一个解压zip的程序,涉及到解压zip,读取excel文件

本文介绍了一种通过Excel批量导入数据到系统的方法,包括前端页面设计、后台处理逻辑及文件解压、数据解析等关键步骤。

项目背景:从一个系统中导出数据,导入的另一个系统中,导出的数据以.zip形式,里面的内容包括,一个文件夹:文件夹中是要上传文档信息对应的附件文件;两个.xls:一个是上传的文档信息,对应文档表,另一个是每个文档信息对应的附件信息,对应的是附件表。两个excel存在一个Map<String,List<?>>中,文档信息map的key为wdxx,对应的value为List<Wdgl>;附件信息的key为wdfjxx,对应的value值为List<Fjxx>。

前台:

<form id="importForm" method="post" enctype="multipart/form-data">   上传文件时的设置值                              
    <table class="table-form">                                                                       
    <tr>                                                                                             
        <td class="td-title col4" ><label>导入文件<span class="fred">*</span></label></td>               
        <td  colspan="3"  id="fjxxfile" >                                                            
            <span  id="fjxxsjfjcon">                                                                 
                <input type="file" class="myfile easyui-validatebox" id="wdxx" name="uploadFile"/>  
            </span>                                                                                  
        </td>                                                                                        
    </tr>                                                                                            
</table>                                                                                             
</form> 

后台:    在文件的action中定义

单文件
    private File uploadFile;                                        // 实际上传的单个文件
    private String uploadFileContentType;             // 上传单个文件的类型
    private String uploadFileFileName;                  // 上传单个文件的名称

多文件
    private File[] uploadFiles;                                   // 上传的多个文件
    private String[] uploadFilesContentType;        // 上传多个文件的类型
    private String[] uploadFilesFileName;             // 上传多个文件的名称

给出相应的get、set方法

导入的方法

public void importW(){
        String fileName = this.getUploadFileFileName();
        UUID uuid = UUID.randomUUID();
        if(StringUtils.isNotBlank(fileName)){
            //上传文件到服务器端,创建文件夹并加密文件名
            this.uploadFile("test/"+uuid);
            //获得上传的到服务器的文件(已经加密)
            String prefix = fileName.substring(0,fileName.lastIndexOf("."));
            String suffix = fileName.substring(fileName.lastIndexOf("."));
            String newFileName = MD5Util.md5(prefix);
            File newFile = new File(newFileName+suffix);
            
            //获取当前计算机的根目录,同时创建test_fileUpload文件夹
            String absolute = getRootPath();
            String path = "test/"+uuid;
            File f = new File(absolute+path+"/"+newFileName+suffix);
            //解压zip
            try {
                //读取zip包
                Map<String,List<?>> resultMap = readFromZip(f,new ImportFormatter("yyyy-MM-dd HH:mm:ss"));
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
    }


//上传文件到服务器端,创建文件夹并加密文件名
    public void uploadFile(String dir){
        String absolutePath = getRootPath();
        //自定义一个目录
        String path = absolutePath + dir;
        File file = new File(path);
        if(!file.exists()){
            file.mkdir();
        }
        try {
            if(this.getTest().length()>0){
                String fileName =  getTestFileName();
                String prefix = fileName.substring(0,fileName.lastIndexOf("."));
                String suffix = fileName.substring(fileName.lastIndexOf("."));
                /*对文件名进行md5加密,md5(Messager-Digest Algorithm 信息-摘要 算法
                    1.运用一种安全的散列算法;
                    2.其过程是不可逆的,即根据输出值不能得到原始的明文,除非用穷举法进行一一对比
                ),直接调用的公司封装的方法*/
                String newFileName = MD5Util.md5(prefix);
                File newFile = new File(path,newFileName+suffix);
                FileUtils.copyFile(getTest(), newFile);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
    }

    }

  

//获取当前计算机的根目录,同时创建test_fileUpload文件夹
    public String  getRootPath(){
        //获取用户目录   java获得系统的参数用System.getProperties()方法
        String userPath = System.getProperties().getProperty("user.home");
        String dirPath = "/test_fileUpload";
        String rootPath = userPath + dirPath;
        File file = new File(rootPath);
        //test_fileUpload文件夹不存在则创建test_fileUpload文件夹
        if(!file.exists()){
            file.mkdirs();
        }
        return rootPath + "/";
    }

//md5加密,不过不明白
  public static String md5(String str) {      
    return bytes2Hex(md5(str.getBytes()));  
}  


//读取zip包
    public Map<String,List<?>> readFromZip(File file,ImportFormatter formatter) throws Exception{
        Map<String,List<?>> resultMap = new HashMap<String,List<?>>();
        //解压文件到临时路径 test_fileUpload/unZipTemp/xxxxx/
        String tempPath = getRootPath()+"/unZipTemp/"+new Date().getTime();
        //上传文件的路径
        File upLoadPath = new File(getRootPath());
        
        if(file != null && file.exists()){
            //解压文件到临时路径test_fileUpload/unZipTemp/xxx/
            unZip(file.getAbsolutePath(),tempPath);
            //获取解压的文件夹test_fileUpload/unZipTemp/xxxxx
            File unzip = new File(tempPath);
            //获取解压的文件夹里的上传文件test_fileUpload/unZipTemp/xxx/xxx
            String basePath = unzip.listFiles()[0].getAbsolutePath();
            //处理Excel信息
            File unZipFile = new File(basePath);
            File[] fileList = unZipFile.listFiles();
            for(File tempFile : fileList){
                if(tempFile.exists()){
                    //处理附件信息
                    if(tempFile.isDirectory()){
                        FileUtils.copyDirectory(tempFile, upLoadPath);
                    }else{
                        //处理Excel
                        String fileName = tempFile.getName();
                        String prefix = fileName.substring(0,fileName.lastIndexOf("."));
                        //获得excel中的数据
                        List<?> list = readValue(tempFile,prefix,formatter);
                        resultMap.put(prefix, list);
                    }
                }
            }
            //删除临时文件夹的内容
            FileUtils.deleteDirectory(unzip);
        }
        return resultMap;
    }                                       
                                                                                                                                                  
    

//解压压缩包
    public void unZip(String sourcePath,String targetPath) throws IOException{
        //创建一个ZipFile实体类,第一个参数为压缩文件的绝对路径,第二个参数为编码方式,设置为GBK目的是使其支持中文
        ZipFile zf = new ZipFile(sourcePath,"GBK");
        //利用了Enumeration类,获得的zipEntry是无序的
        @SuppressWarnings("rawtypes")
        Enumeration e = zf.getEntries();
        //判断枚举类是否还有更多的元素
        while(e.hasMoreElements()){
            //如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素
            ZipEntry ze = (ZipEntry)e.nextElement();
            String zipName = ze.getName();
            String path = targetPath +"/"+ zipName;
            //判断该元素是否为文件夹
            if(ze.isDirectory()){
                File dirFile = new File(path);
                if(!dirFile.exists()){
                    //dirFile.mkdir();只能在已经存在的目录中创建文件夹
                    dirFile.mkdirs();   //可以在不存的目录中创建文件夹
                }
            }else{
                File fileDirFile = new File(path.substring(0,path.lastIndexOf("/")));
                if(!fileDirFile.exists()){
                    fileDirFile.mkdirs();
                }
                //BufferedOutputStream是一个带有缓冲区域的OutputStream
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path));
                /*BufferedInputStream是一个带有缓冲区域的InputStream,
                当read时会先把缓冲区填满,然后下次读取是直接从缓冲区读取。
                当读取的位置大于缓冲区时会再一次加载缓冲区。*/
                BufferedInputStream bis = new BufferedInputStream(zf.getInputStream(ze));
                //设置缓冲区的大小
                byte[] readContent = new byte[1024];
                //这个缓冲区数组的作用在于对源进行数据块访问,而不是一字节一字节的访问,也就是进行一次I/O将一块数据存到缓冲区中,
                //再从缓冲区中read,当缓冲区为空时再重新读新的数据块
                //read方法返回当前位置的后一位置byte值(int表示)
                int readCount = bis.read(readContent);
                while(readCount != -1){
                    //使用write方法写入时,实际上先将数据写入到缓冲区
                    bos.write(readContent,0,readCount);
                    readCount = bis.read(readContent);
                }
                bos.close();
            }
        }
        zf.close();
    }

   

    //读取Excel获得实体列表
    public List<?> readValue(File file,String prefix,ImportFormatter formatter) throws Exception{
        List<Object> list = new ArrayList<Object>();
        String classUrl = PropertyGetter.getString(prefix + ".classURL");
        String fieldStr = PropertyGetter.getString(prefix + ".fields");
        String xy = PropertyGetter.getString(prefix + ".xy");
        String typeStr = PropertyGetter.getString(prefix + ".types");
        String[] fields = fieldStr.split(",");
        String[] types = typeStr.split(",");
        int startRow = Integer.parseInt(xy.substring(0,xy.lastIndexOf(",")));
        int startClumn = Integer.parseInt(xy.substring(xy.lastIndexOf(",")+1));
        
        InputStream is = new FileInputStream(file);
        //org.apache.poi.hssf.usermodel.HSSFWorkbook 声明一个工作薄
        HSSFWorkbook hssfWorkBook = new HSSFWorkbook(is);
        
        //循环工作表
        for(int numSheet=0;numSheet<hssfWorkBook.getNumberOfSheets();numSheet++){
            HSSFSheet hssfSheet = hssfWorkBook.getSheetAt(numSheet);
            if(hssfSheet == null){
                continue;
            }
            //循环Row
            for(int rowNum=startRow;rowNum<=hssfSheet.getLastRowNum();rowNum++){
                HSSFRow hssfRow = hssfSheet.getRow(rowNum);
                if(hssfRow == null){
                    continue;
                }
                //一下两句代码相当于Object object = new Object();
                /*用到了反射机制*/
                Class classLoader = Class.forName(classUrl);
                Object object = classLoader.newInstance();
                //循环Cell
                for(int i=0;i<fields.length;i++){
                    //将属性的首字母变为大写
                    String firstUpper = fields[i].substring(0,1).toUpperCase()+fields[i].substring(1);
                    Method method = classLoader.getMethod("set"+firstUpper, Class.forName(types[i]));
                    
                    HSSFCell column = hssfRow.getCell(i+startClumn);
                    if(column == null){
                        continue;
                    }
                    
                    //判断值的类型后,进行强制类型转换
                    if(types[i].equals("java.lang.String")){
                        method.invoke(object, getValue(column));
                    }else if(types[i].equals("java.lang.Integer")){
                        method.invoke(object, getValue(column));
                    }else if(types[i].equals("java.util.Date")){
                        if(formatter == null){
                            formatter = new ImportFormatter("yyyy-MM-dd");
                        }
                        method.invoke(object, DateUtils.getDate(getValue(column, formatter),formatter.getDateFormat()));
                    }else if(types[i].equals("java.math.BigDecimal")){
                        method.invoke(object, new BigDecimal(getValue(column)));
                    }else if(types[i].equals("java.lang.Double")){
                        method.invoke(object, Double.parseDouble(getValue(column)));
                    }else if(types[i].equals("java.lang.Float")){
                        method.invoke(object, Float.parseFloat(getValue(column)));
                    }else if(types[i].equals("java.lang.Short")){
                        String value = getValue(column);
                        if(StringUtils.isNotBlank(value)){
                            value = value.contains(".")?value.substring(0,value.lastIndexOf(".")):value;
                            method.invoke(object, value);
                        }
                    }else{
                        method.invoke(object, new Object[]{});
                    }
                }
                list.add(object);
            }
        }
        
        return list;s
    }     


/*
     * 方法描述 : 得到Excel表中的值
     * 参数: excel中的每一个格子
     * 返回值:excel中每一个格子中的值
     */

    @SuppressWarnings("static-access")
    public String getValue(HSSFCell hssfCell){
        int num = hssfCell.getCellType();
        if(num == hssfCell.CELL_TYPE_BOOLEAN){
            //返回布尔类型的值
            return String.valueOf(hssfCell.getBooleanCellValue());
        }else if(num == hssfCell.CELL_TYPE_NUMERIC){
            if(HSSFDateUtil.isCellDateFormatted(hssfCell)){
                Date date = HSSFDateUtil.getJavaDate(hssfCell.getNumericCellValue());
                //调用公司的方法,就是将日期格式化
                return DateUtils.dateToDateString(date, "yyyy-MM-dd HH:mm:ss");
            }
            //返回数值类型的值
            return String.valueOf(hssfCell.getNumericCellValue());
        }else{
            //返回字符串类型的值
            return String.valueOf(hssfCell.getStringCellValue());
        }
    }
    
    /**
     * 实体类中字段为Date时格式化得到Excel表中的值
     * @param hssfCell  Excel中的每一个格子
     * @param formatter 格式化参数
     * @return Excel中每一个格子中的值
     */

    @SuppressWarnings("static-access")
    private static String getValue(HSSFCell hssfCell, ImportFormatter formatter) {
        if (hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN) {
            // 返回布尔类型的值
            return String.valueOf(hssfCell.getBooleanCellValue());
        } else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC) {
            if(HSSFDateUtil.isCellDateFormatted(hssfCell)) {
                Date dt = HSSFDateUtil.getJavaDate(hssfCell.getNumericCellValue());  
                return DateUtils.dateToDateString(dt,"yyyy-MM-dd HH:mm:ss");
            }
            return String.valueOf(hssfCell.getNumericCellValue());
        } else {
            // 返回字符串类型的值
            String format = formatter.getDateFormat(); //自己传入的日期格式
            String cellValue = hssfCell.getStringCellValue();  //excel中的值
            String replaceChar = "";  //需要替换的字符;
            if (!StringUtils.isBlank(format)) {
                if (format.contains("/")) {
                    replaceChar = "/";
                } else if (format.contains("-")){
                    replaceChar = "-";
                }
            }
            if (!StringUtils.isBlank(cellValue)) {
                if (cellValue.contains("-")) {
                    cellValue = cellValue.replace("-", replaceChar);
                } else if (cellValue.contains("/")) {
                    cellValue = cellValue.replace("/", replaceChar);
                } else {
                    if (cellValue.length() < 8) {
                        throw new RuntimeException("格式错误");
                    } else {
                       cellValue = cellValue.substring(0, 4) + replaceChar + cellValue.substring(4, 6) + replaceChar + cellValue.substring(6);
                    }
                }
            }
            return String.valueOf(cellValue);
        }
    }                                                                                                                                         
                                                                        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值