java解析 VCF文件导入导出数据库

java解析 VCF文件导入导出数据库
   前几天,客户要求开发个小功能,就是把手机的VCF电话薄文件导出来后,可以导入数据库,然后从数据库出来的记录,同样可以生成vcf文件,并且地手机导入后可以成为有用电话薄.(vcf文件内容格式另外有介绍)
   大家可以看看http://sourceforge.net/projects/mime-dir-j/这个开源的,前几天还上不了个网站(我是用代理上的),这几天好像是可以了,我是自己看了下源码.然后写了下,
  在java中生成vcf文件,我是在Servlet中用文件流做的部份代码如下 :
 response.setHeader("Content-Disposition","attachment; filename="+ new String(bean.getTrueName().getBytes("GBK"), "ISO8859-1" )+".vcf");
            try{
                java.io.PrintWriter  bufout=response.getWriter();
                          bufout.write("BEGIN:VCARD");
                          bufout.write("\r\n");
                          bufout.write("VERSION:2.1");
                          bufout.write("\r\n");
                          bufout.write("N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:"+AddressServlet.qpEncodeing(bean.getTrueName())+";");
                          bufout.write("\r\n");
                          if(""!=bean.getMobile()&&bean.getMobile()!=null){
                              bufout.write("TEL;CELL:"+bean.getMobile()+"");
                              bufout.write("\r\n");
                          }
                          if(""!=bean.getWorkMobile()&&bean.getWorkMobile()!=null){
                              bufout.write("TEL;WORK:"+bean.getWorkMobile()+"");
                              bufout.write("\r\n");
                          }
                        
                          if(""!=bean.getTelephone()&&bean.getTelephone()!=null){
                              bufout.write("TEL;HOME:"+bean.getTelephone()+"");
                              bufout.write("\r\n");
                          }
                          if(""!=bean.getEmail()&&bean.getEmail()!=null){
                              bufout.write("EMAIL:"+bean.getEmail()+"");
                              bufout.write("\r\n");
                          }
                          bufout.write("END:VCARD");
                          bufout.write("\r\n");
                response.getOutputStream().flush();
                response.getOutputStream().close();
    }
      catch(IOException   E){
        System.out.println("vcfexport发生I/O错误!");
            } 
qpEncodeing()这个方法是专门编码成这种格式的(http://www.blogjava.net/sundc/archive/2008/08/04/219863.html).

2.从本地上传后导入到DB,我也是在Servlet实现的
FileItem fi=null;
         try {
                FileUpload fu = new FileUpload();
                // 设置最大文件尺寸,这里是2MB
                fu.setSizeMax(2097152);
                // 得到所有的文件:
                DiskFileItemFactory  factory = new DiskFileItemFactory();
                fu.setFileItemFactory(factory);
                List fileItems = fu.parseRequest(requestContext);
                Iterator i = fileItems.iterator();
                while(i.hasNext()) {
                    fi= (FileItem)i.next();
                    // 获得文件名,这个文件名包括路径:
                    String fileName = fi.getName();
                    if(fi.getSize()>2097152){
                        return "文件太大";
                    }
                   
                    if(fileName==null){
                        return "文件错误";
                    }
                 String   fileExt=StringUtils.getFileExt(fileName).toLowerCase();
                    if (fileExt.toLowerCase().equals("vcf")){
                       
                         Properties p=this.createProperties();
                            try {
                                ArrayList li = this.importVCFFileContact(fi.getInputStream(), p);
                                if(li==null||li.size()==0){
                                    return "导入记录0条,可能是导入文件内容格式不正确";
                                }
                                this.addAddresses(li);
                                return "1";
                            } catch (IOException e) {
                                return "文件格式发生错误";
                            }   
                    }
                    else{
                        return "不是vcf文件";
                    }
                   
                   
                }
            }
            catch(Exception e) {
                 if(e.getMessage().indexOf("maximum")>0){
                     return "导入文件发生错误,文件大于2M";
                    }
               log.debug(e.getMessage());
               return "导入文件发生错误"+e.getMessage();
            }
           finally{
               try{
                 //删除临时文件
                    fi.delete();
               }
               catch (Exception e) {
                // TODO: handle exception
            }
             
           }
            return "发生错误";
         
        }
这个上传中用到的代码.下面是把VCF文件解析成bean对象
/**
     * 导入联系人
     * @param in
     * @throws SystemException
     */
    public ArrayList  importVCFFileContact(InputStream in,Properties pp) throws SystemException{
     
             try {
                 BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                    Document document = new DocumentImpl();
                    BufferedWriter writer = null;
                 
                    String line;
                    StringBuffer bu=new StringBuffer();
                    while ((line = DecorGroup.nextLine(reader)) != null) {
                        bu.append(line+"\r\n");
                        }
                    Pattern p=Pattern.compile("BEGIN:VCARD(\\r\\n)([\\s\\S\\r\\n\\.]*?)END:VCARD");//分组,
                    Matcher m=p.matcher(bu.toString());
                     while(m.find()){
                         AddressBean  be=new AddressBean();
                         be.setCateId(gb.getId());
                         be.setUserId(gb.getUserId());
                         String str=m.group(0);
                     
                //姓名
                         Pattern pn=Pattern.compile("N;([\\s\\S\\r\\n\\.]*?)([\\r\\n])");//分组,
                         Matcher mn=pn.matcher(m.group(0));
                         while(mn.find()){
                             String name="";
                           
                            if(mn.group(1).indexOf("ENCODING=QUOTED-PRINTABLE")>-1){
                                name=mn.group(1).substring(mn.group(1).indexOf("ENCODING=QUOTED-PRINTABLE:")+"ENCODING=QUOTED-PRINTABLE:".length());
                                name=name.substring(name.indexOf(":")+1);
                                if(name.indexOf(";")>-1){
                                    name=name.substring(0,name.indexOf(";"));
                                    be.setTrueName(AddressServlet.qpDecoding(name));
                                }
                                else{
                                    be.setTrueName(AddressServlet.qpDecoding(name));
                                }
                               
                            }
                            else{
                                Pattern pnn=Pattern.compile("CHARSET=([A-Za-z0-9-]*?):");
                                Matcher mnn=pnn.matcher(mn.group(1));
                                 while(mnn.find()){
                                     name=mn.group(1).substring(mn.group(1).indexOf(mnn.group(0))+mnn.group(0).length());
                                     be.setTrueName(name);
                                 }
                            }
                               
                         }
                         if(be.getTrueName().length()>20){
                             return null;
                         }
                        String cell="";
                        Pattern p1=Pattern.compile("TEL;CELL:\\d*");//分组,
                        Matcher m1=p1.matcher(str);
                        while(m1.find()){
                            cell=m1.group(0).substring(m1.group(0).indexOf("TEL;CELL:")+"TEL;CELL:".length());
                        }
                        be.setMobile(cell);
                         if(be.getMobile().length()>13){
                             return null;
                         }
                        String work="";
                        Pattern p2=Pattern.compile("TEL;WORK:\\d*");//分组,
                        Matcher m2=p2.matcher(str);
                        while(m2.find()){
                            work=m2.group(0).substring(m2.group(0).indexOf("TEL;WORK:")+"TEL;WORK:".length());
                        }
                        be.setWorkMobile(work);
                         if(be.getWorkMobile().length()>13){
                             return null;
                         }
                        String home="";
                        Pattern p3=Pattern.compile("TEL;HOME:\\d*");//分组,
                        Matcher m3=p3.matcher(str);
                        while(m3.find()){
                        home=m3.group(0).substring(m3.group(0).indexOf("TEL;HOME:")+"TEL;HOME:".length());
                        }
                        be.setTelephone(home);
                        if(be.getTelephone().length()>13){
                             return null;
                         }

                        String email="";
                        Pattern p4=Pattern.compile("\\w+(\\.\\w+)*@\\w+(\\.\\w+)+");//分组,
                        Matcher m4=p4.matcher(str);
                        while(m4.find()){
                            email=m4.group(0);
                        }
                        be.setEmail(email);
                      
                     }
                     reader.close();
            } catch (Exception e) {
                log.debug(e.getMessage());
                throw new SystemException("对不起,系统忙,请梢后再试!");
            }
        return abs;
       
    }
以下是源码中自代的方法,我COPY过来就用了
 public static String nextLine(BufferedReader reader) throws IOException {
       
            String line;
            String nextLine;
           
            do {
                line = reader.readLine();
                if (line == null) return null;
            } while (line.length() == 0);
           
            // Evolution style line folding
            while (line.endsWith("=")) {
                line = line.substring(0, line.length() - 1);
                line += reader.readLine();
                }
            // RFC 2425 line folding
            reader.mark(1000);
            nextLine = reader.readLine();
            if ((nextLine != null)
                && (nextLine.length() > 0)
                && ((nextLine.charAt(0) == 0x20) // white space
                    || (nextLine.charAt(0) == 0x09))) { // tab
                line += nextLine.substring(1);
            } else {
                reader.reset();
            }
           
            line = line.trim();
            return line;
        }
     在这里要提醒大家,有的手机的电话薄可能字选项会多一点.所以,我在这做的是  姓名   手机号码 电话  工作电话   Email这几个大家手机都会有的. 程序通过诺基亚,三星(SAMSUNG),摩托罗拉(MOTO),还有国产波导,哈哈.....

    如有问题,大家可以评论...

你可能感兴趣的:(java解析 VCF文件导入导出数据库)