2015-10-30 82 views
0

在IT公司的實習中,我被分配了一個任務來編寫一個腳本或一個Java程序,以將CSV文件轉換爲LDIF文件格式,我相信很多組織用來填充/修改/刪除許多用戶的目錄。我試圖編寫一個java程序,可以幫助我將CSV文件轉換爲LDIF文件。然後將此LDIF文件導入到電子目錄中以添加新用戶。目前,我有一個簡單的程序,但需要重大改進,但我無法提供。使用java將CSV文件轉換爲LDIF文件


截圖樣品CSV文件的(第一行是報頭):
csv file sample
樣品CSV文件在記事本++:
csv file in Notepad++
(第一行是頭在一排中的每個元素是用逗號(,)分隔)
使用下面給出的示例代碼(OUTPUT)產生
樣品LDIF文件:

dn: cn=demotest1, ou=Data, o=Data 
changetype: add 
ou: Data 
objectClass: dt1 
objectClass: test_demo1 
objectClass: demotest1 
objectClass: Employee 
cn: demotest1 
uid: test_demo1 
SAMAccountName: demt1 
givenName: demotest1 
sn: dt1 

dn: cn=demotest2, ou=Data, o=Data 
changetype: add 
ou: Data 
objectClass: dt2 
objectClass: test_demo2 
objectClass: demotest2 
objectClass: Employee 
cn: demotest2 
uid: test_demo2 
SAMAccountName: demt2 
givenName: demotest2 
sn: dt2 


注意:作爲標題的第一行從輸出中排除。 CSV文件中的每一行都被轉換爲一組數據(lines = dn:to sn :),每一組數據由空行分隔。

下面給出的是我用於生成上述LDIF文件中的代碼示例:

package readcsv; 

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.PrintStream; 
/** 
* 
* @author Dorjee 
*/ 

public class ReadCSV { 

    public static void main(String[] args) { 
     ReadCSV obj = new ReadCSV(); 
     obj.run(); 
    } 

    public void run() { 

     String csvFile = "/Users/Dorjee/Desktop/sampleCSV.csv"; //Path of file to be read. 
     BufferedReader br = null; 
     String line = ""; 
     String csvSplitBy = ",";   
     String[] column; 

     int count = 0; 

     try { 

      PrintStream out = new PrintStream(new FileOutputStream("OutputLDIFFile.ldif")); 
      br = new BufferedReader(new FileReader(csvFile)); 

      while ((line = br.readLine()) != null) { 

       // using comma as separator 
       column = line.split(csvSplitBy); 

       //End format of the ouput file. 
       //Change according to .CSV file. 
       //Count used to exclude the reading of the first line. 
       if (count > 0) { 
        out.println("dn: cn="+column[5]+", ou="+column[7]+", o=Data"+ 
          "\nchangetype: " + column[2] 
          + "\nou: " + column[7] 
          + "\nobjectClass: " + column[3] 
          + "\nobjectClass: " + column[4] 
          + "\nobjectClass: " + column[5] 
          + "\nobjectClass: " + column[6] 
          + "\ncn: " + column[5] 
          + "\nuid: "+column[4] 
          + "\nSAMAccountName: "+column[1] 
          + "\ngivenName: "+column[0] 
          + "\nsn: "+column[3] 
          + "\n" 
        ); 
       } 
       count++; 

      } 

     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      if (br != null) { 
       try { 
        br.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
     System.out.println("Done"); 
    } 

} 

這是一個簡單的碼,有助於產生從CSV文件LDIF文件。這是有幫助的,因爲這裏生成的數據集可以跨越數千行。但是這個代碼顯然是不夠的。正如您所看到的,每次有不同數量的列的不同CSV文件都需要轉換爲LDIF文件時,我將不得不更改上面突出顯示區域的代碼。它佔用了大量的時間,因爲我遇到了超過五十列的文件,並且在手動更改代碼時增加了出錯的機率。最重要的是一些列有空值(需要從輸出中排除)。

•如何排除輸出中的空值?
•即使CSV文件的列數不同,是否可以自動生成輸出?我嘗試了ArrayList,但我無法想出解決問題的方法。

任何形式的幫助將不勝感激。如果可能有很多錯誤,我很抱歉,這是我第一次在這裏問一個問題。因此,任何形式的反饋也將大大幫助。謝謝!

+0

感謝編輯@morels ...想做的事,不知道如何...... – Dorjee

+0

選擇要呈現爲代碼的文本後,編輯器中的「{}」按鈕。 – morels

回答

1

像這樣的東西應該跳過空列:

out.println("dn: cn="+column[5]+", ou="+column[7]+", o=Data"+ 
        "\nchangetype: " + column[2] 
        + ((column[7].length()>0)?"\nou: " + column[7]:"") 
        + ((column[3].length()>0)?"\nobjectClass: " + column[3]:"") 
        + ((column[4].length()>0)?"\nobjectClass: " + column[4]:"") 
        + ((column[5].length()>0)?"\nobjectClass: " + column[5]:"") 
        + ((column[6].length()>0)?"\nobjectClass: " + column[6]:"") 
        + ((column[5].length()>0)?"\ncn: " + column[5]:"") 
        + ((column[4].length()>0)?"\nuid: "+column[4]:"") 
        + ((column[1].length()>0)?"\nSAMAccountName: "+column[1]:"") 
        + ((column[0].length()>0)?"\ngivenName: "+column[0]:"") 
        + ((column[3].length()>0)?"\nsn: "+column[3]:"") 
        + "\n" 
      ); 

如果你還需要檢查的列數:

out.println("dn: cn="+column[5]+", ou="+column[7]+", o=Data"+ 
        "\nchangetype: " + column[2] 
        + ((column.length > 7 && column[7].length()>0)?"\nou: " + column[7]:"") 
        + ((column.length > 3 && column[3].length()>0)?"\nobjectClass: " + column[3]:"") 
        + ((column.length > 4 && column[4].length()>0)?"\nobjectClass: " + column[4]:"") 
        + ((column.length > 5 && column[5].length()>0)?"\nobjectClass: " + column[5]:"") 
        + ((column.length > 6 && column[6].length()>0)?"\nobjectClass: " + column[6]:"") 
        + ((column.length > 5 && column[5].length()>0)?"\ncn: " + column[5]:"") 
        + ((column.length > 4 && column[4].length()>0)?"\nuid: "+column[4]:"") 
        + ((column.length > 1 && column[1].length()>0)?"\nSAMAccountName: "+column[1]:"") 
        + ((column.length > 0 && column[0].length()>0)?"\ngivenName: "+column[0]:"") 
        + ((column.length > 3 && column[3].length()>0)?"\nsn: "+column[3]:"") 
        + "\n" 
      ); 

它看起來有點醜它可能是與助手更容易功能。

static public String check(String column[],String line,int index) { 
    return ((column.length > index && column[index].length()>0)?line + column[index]:""); 
} 

...

out.println("dn: cn="+column[5]+", ou="+column[7]+", o=Data"+ 
        "\nchangetype: " + column[2] 
        + check(column,"\nou: ",7) 
        + check(column,"\nobjectClass: " ,3) 
        + check(column,"\nobjectClass: ",4) 
        + check(column,"\nobjectClass: ",5) 
        + check(column,"\nobjectClass: ",6) 
        + check(column,"\ncn: ",5) 
        + check(column,"\nuid: ",4) 
        + check(column,"\nSAMAccountName: ",1) 
        + check(column,"\ngivenName: ",0) 
        + check(column,"\nsn: ",3) 
        + "\n" 
      ); 
+0

感謝您的協助!非常感激! – Dorjee

1

我要離開上一/接受的答案評論,但我沒有信譽,以便能夠發表評論。相反,我會添加一個無回答的答覆,希望能幫助任何未來看到這個問題的人......

提供的解決方案在處理可能出現的任何可能的數據時似乎不完整。如果你看一下RFC2849你會發現(第5頁上都)喜歡建議:

4) ... Any 
    value that contains characters other than those defined as 
    "SAFE-CHAR", or begins with a character other than those 
    defined as "SAFE-INIT-CHAR", above, MUST be base-64 encoded. 
    Other values MAY be base-64 encoded. 

其中SAFE-INIT-CHAR定義爲

SAFE-INIT-CHAR  = %x01-09/%x0B-0C/%x0E-1F/
         %x21-39/%x3B/%x3D-7F 
         ; any value <= 127 except NUL, LF, CR, 
         ; SPACE, colon (":", ASCII 58 decimal) 
         ; and less-than ("<" , ASCII 60 decimal) 

8) Values or distinguished names that end with SPACE SHOULD be 
    base-64 encoded. 

如果您想要更完整的解決方案,應該更新已接受的解決方案以正確處理編碼。