2010-07-22 21 views
3
合併CSV文件

我的第一個CSV文件看起來像這樣與包括報頭(只在頂部包含的頭不是每個條目之後):如何在Java中

NAME,SURNAME,AGE 
Fred,Krueger,Unknown 
.... n records 

我的第二個文件可能是這樣的:

NAME,MIDDLENAME,SURNAME,AGE 
Jason,Noname,Scarry,16 
.... n records with this header template 

合併後的文件應該是這樣的:

NAME,SURNAME,AGE,MIDDLENAME 
Fred,Krueger,Unknown, 
Jason,Scarry,16,Noname 
.... 

基本上,如果標題不匹配,所有新標題標題(列)應該按照該順序添加在原始標題和它們的值之後。

UPDATE:

以上CSV作了小,所以我很能說明我想達到的目標,在現實中CSV文件這(合併)之前產生的一個步驟,並且可達到100列

有沒有人有任何想法,我該怎麼做?我想感謝所有幫助

+0

您可以檢查[CSV合併(https://github.com/riyadparvez/csv-merger)的GitHub項目 – user 2013-03-12 06:10:19

回答

1

我創造了「做大」的格式(本類的實例的簡單類有四個字段和集合)的模型,並實現了兩個解析器,一個第一,一個用於第二種模式。爲兩個csv文件的所有行創建記錄,並實現一個編寫器以正確的格式輸出csv。簡而言之:

public void convert(File output, File...input) { 

    List<Record> records = new ArrayList<Record>(); 
    for (File file:input) { 
    if (input.isThreeColumnFormat()) { 
     records.addAll(ThreeColumnFormatParser.parse(file)); 
    } else { 
     records.addAll(FourColumnFormatParser.parse(file)); 
    } 
    } 
    CsvWriter.write(output, records); 
} 

從您的評論我明白了,你有很多不同的CSV格式,具有一些共同的列。

你可以定義任何行的模型在不同的CSV文件是這樣的:

public class Record { 
    Object id; // some sort of unique identifier 
    Map<String, String> values; // all key/values of a single row 
    public Record(Object id) {this.id=id;} 
    public void put(String key, String value){ 
    values.put(key, value); 
    } 
    public void get(String key) { 
    values.get(key); 
    } 
} 

爲了解析,你會先讀取頭的任何文件和列標題添加到全局密鑰庫(將需要後來輸出),然後創建記錄所有行,如:

//... 
List<Record> records = new ArrayList<Record>() 

for (File file:getAllFiles()) { 
    List<String> keys = getColumnsHeaders(file); 
    KeyStore.addAll(keys); // the store is a Set 
    for (String line:file.getLines()) { 
    String[] values = line.split(DELIMITER); 
    Record record = new Record(file.getName()+i); // as an example for id 
    for (int i = 0; i < values.length; i++) { 
     record.put(keys.get(i), values[i]); 
    } 
    records.add(record); 
    } 
} 
// ... 

現在密鑰庫已全部採用列標題名稱,我們可以遍歷所有記錄的收集,獲取所有值的所有鍵(和如果文件爲null該記錄沒有使用密鑰),組裝csv行並將所有內容寫入新文件。

+0

感謝您的答覆,在我的問題中的csv只是我想要實現的例子,CSV文件和之前生成的一個步驟,並且可能有許多colums,從20直到可能100 – ant 2010-07-22 09:03:00

1

讀入第一個文件的標題並創建列名稱列表。現在閱讀第二個文件的標題,並將列表中已經不存在的任何列名添加到列表的末尾。現在,您可以按照所需的順序填寫列,並且可以先將其寫入新文件。

接下來我會分析每個文件,併爲每一行我想創建一個地圖列名的價值。一旦行被解析,您可以迭代列名稱的新列表,並從地圖中提取值並立即將其寫入新文件。如果值爲空,則不要打印任何內容(如果需要,只需逗號)。

可能有更有效的解決方案可用,但我認爲這符合您所設置了要求。