有一個安卓手機導出的通訊錄文件是.vcf格式的,想把這里面的聯系人都提取出來,轉換成Excel表格,網上有轉換工具,不過吧是收費的,
看了一下Vcf文件還是很有規律的,感覺使用Io流讀取信息,然后生成Excel問題還是不大的,我這里只提取了簡單的名字和手機號碼,應該可以有更多的信息 比如聯系地址,單位等
首先創建一個maven工程 主要是導出Excel要用第三方jar包
1 <dependency> 2 <groupId>cn.hutool</groupId> 3 <artifactId>hutool-all</artifactId> 4 <version>5.0.6</version> 5 </dependency> 6 7 <dependency> 8 <groupId>org.apache.poi</groupId> 9 <artifactId>poi-ooxml</artifactId> 10 <version>3.17</version> 11 </dependency>
一個是hutoll工具類框架,另外一個是Apache的處理Excel的POI
然后把代碼貼出來
1 import cn.hutool.poi.excel.ExcelUtil; 2 import cn.hutool.poi.excel.ExcelWriter; 3 4 import java.io.*; 5 import java.util.ArrayList; 6 import java.util.Arrays; 7 import java.util.List; 8 9 /** 10 * @Description: 讀取Vcf文件並轉換為Excel 11 * @Author: Tan 12 * @CreateDate: 2020/2/5 13 **/ 14 public class VcfToExcel { 15 public static void main(String[] args) throws Exception { 16 long start=System.currentTimeMillis(); 17 //讀取vcf文件 18 BufferedReader bufferedReader=new BufferedReader(new FileReader("vcf文件路徑")); 19 //計數器 統計當前有多少記錄 20 int count=0; 21 //創建導出Excel數據集合 22 List<List<String>> exportList=new ArrayList<>(); 23 //添加一行 算標題 第一行 24 exportList.add(Arrays.asList("編號","姓名","手機號碼")); 25 //讀取的信息 26 String info; 27 //循環讀取 28 while ((info=bufferedReader.readLine())!=null){ 29 //讀取到的這一行以FN開頭 代表名字 30 if(info.startsWith("FN")){ 31 //截取名字編碼部分 32 String name=info.substring(info.indexOf(":")+1); 33 //名字編碼的下一行為手機號也可能是名字編碼的剩余字符 34 String phone=bufferedReader.readLine(); 35 //判斷是否是=開頭 如果是就是名字編碼的剩余部分,也拼接到名字,下一行就是手機號 36 if(phone.startsWith("=")){ 37 name+=phone.substring(1); 38 phone=bufferedReader.readLine(); 39 }else if("".equals(phone)){ 40 phone=bufferedReader.readLine(); 41 } 42 //截取手機號 43 phone=phone.substring(phone.indexOf(":")+1); 44 45 //判斷名字編碼最后一位是否是= 如果是要刪除掉 46 if(name.charAt(name.length()-1)==61){ 47 name= name.substring(0,name.length()-1); 48 } 49 //將編號 名字進行解碼 和手機號 添加到導出數據 50 exportList.add(Arrays.asList(Integer.toString(++count),qpDecoding(name),phone)); 51 } 52 53 } 54 //關閉緩存流 55 bufferedReader.close(); 56 57 //創建hutool工具類的寫Excel對象 58 ExcelWriter writer = ExcelUtil.getWriter("導出Excel的路徑.xlsx"); 59 60 //寫入數據 生成Excel 61 writer.write(exportList, true); 62 63 //關閉writer,釋放內存 64 writer.close(); 65 66 System.out.println("生成完畢,耗費時間 "+(System.currentTimeMillis()-start)); 67 68 } 69 70 71 72 73 //解碼方法 如果拋出數組越界異常 可能是數據不規范 檢查解碼字符串 74 public final static String qpDecoding(String str) 75 { 76 if (str == null) 77 { 78 return ""; 79 } 80 try 81 { 82 StringBuffer sb = new StringBuffer(str); 83 for (int i = 0; i < sb.length(); i++) 84 { 85 if (sb.charAt(i) == '\n' && sb.charAt(i - 1) == '=') 86 { 87 // 解碼這個地方也要修改一下 88 // sb.deleteCharAt(i); 89 sb.deleteCharAt(i - 1); 90 } 91 } 92 str = sb.toString(); 93 byte[] bytes = str.getBytes("US-ASCII"); 94 for (int i = 0; i < bytes.length; i++) 95 { 96 byte b = bytes[i]; 97 if (b != 95) 98 { 99 bytes[i] = b; 100 } 101 else 102 { 103 bytes[i] = 32; 104 } 105 } 106 if (bytes == null) 107 { 108 return ""; 109 } 110 ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 111 for (int i = 0; i < bytes.length; i++) 112 { 113 int b = bytes[i]; 114 if (b == '=') 115 { 116 try 117 { 118 int u = Character.digit((char) bytes[++i], 16); 119 int l = Character.digit((char) bytes[++i], 16); 120 if (u == -1 || l == -1) 121 { 122 continue; 123 } 124 buffer.write((char) ((u << 4) + l)); 125 } 126 catch (ArrayIndexOutOfBoundsException e) 127 { 128 e.printStackTrace(); 129 } 130 } 131 else 132 { 133 buffer.write(b); 134 } 135 } 136 return new String(buffer.toByteArray(), "UTF-8"); 137 } 138 catch (Exception e) 139 { 140 e.printStackTrace(); 141 return ""; 142 } 143 } 144 145 }
主要問題就在於 我這個vcf文件其中名字的數據並不是直接是中文的而是一個特殊的QUOTED-PRINTABLE編碼
數據類似這樣 =E5=BC=A0=E4=B8=89 所以需要提取到這個編碼的字符串 然后調用我這個qpDecoding()方法進行解碼
就這樣,希望可以幫助到有需要的人
