2010-07-22 2 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

ответ

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-файлов и сгенерировал один шаг раньше, и может иметь много колонок от 20 до 100 – ant

1

Прочтите в заголовке первого файла и создайте список имен столбцов. Теперь прочитайте заголовок второго файла и добавьте имена столбцов, которые еще не существуют в списке в конце списка. Теперь у вас есть свои столбцы в том порядке, в котором вы хотите, и сначала можете записать это в новый файл.

Далее я проанализировал бы каждый файл, и для каждой строки я бы создал карту имени столбца для значения. После разбора строки вы можете перебрать новый список имен столбцов и вывести значения из карты и сразу же записать их в новый файл. Если значение равно null, не печатайте ничего (просто запятая, если требуется).

Возможно, имеются более эффективные решения, но я думаю, что это соответствует требованиям, которые вы изложили.

Смежные вопросы