Избранное сообщение

Фетісов В. С. Комп’ютерні технології в тестуванні. Навчально-методичний посібник. 2-ге видання, перероблене та доповнене / Мои публикации

В 10-х годах я принимал участие в программе Европейского Союза Tempus "Освітні вимірювання, адаптовані до стандартів ЄС". В рамк...

Благодаря Интернету количество писателей и поэтов увеличивается в геометрической прогрессии. Поголовье читателей начинает заметно отставать.

четверг, 19 января 2017 г.

Чтение и запись CSV файла с помощью SuperCSV в Java / Программирование на Java

В этой статье мы рассмотрим простой способ обработки CSV файлов c помощью библиотеки Super CSV. На простых примерах научимся парсить (считывать) данные и создавать новые CSV файлы. Недавно мы рассматривали простой способ обработки CSV в Java без использования сторонней библиотеки — Как читать CSV файл в Java: задавали разделитесь и считывали информацию с помощью класса Scanner. Но как быть с созданием новых CSV файлов, элементарной поддержкой кодировки, обработки спецсимволов? Для этого есть библиотека SuperCSV —  быстрый, удобный и бесплатный инструмент для обработки CSV в Java.

Краткий обзор библиотеки Super CSV

  • SuperCSV берет на себя работу с кодировкой, правильной обработкой запятых, кавычек, пробелов и escape-последовательностей согласно спецификации CSV.
  • SuperCSV позволяет разработчику использовать свой собственный разделитель или просто выбрать одну из предопределенных конфигураций, включая запятые, табуляцию, точку с запятой и другие.
  • SuperCSV работает с потоками, то есть дает максимальный контроль ввода/вывода при работе с CSV.
  • SuperCSV позволяет быстро и удобно парсить дату, применять форматирование, а также использовать регулярные выражения для преобразования значений.
В примере ниже мы парсим CSV-файл и преобразовываем считанную информацию в список объектов Java. Также мы рассмотрим быстрый способ создания нового CSV файла в Java.

Читаем CSV файл с помощью библиотеки SuperCSV

Создадим файл test.csv с таким наполнением:

1,Андрей,программист,3000 USD
2,Ваня,тестер,2000 USD
3,Дима,программист,3000 USD
4,Оля,тестер,2000 USD
Теперь создадим модель данных:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class Employee {

    private String id;
    private String name;
    private String role;
    private String salary;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public String getSalary() {
        return salary;
    }

    public void setSalary(String salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "\nId=" + getId() + ";Имя=" + getName() + ";Должность="
                + getRole() + ";Зарплата=" + getSalary();
    }
}
Теперь создадим maven проект и добавим в файле pom.xml зависимость Super CSV:

<dependency>
<groupId>net.sf.supercsv</groupId>
<artifactId>super-csv</artifactId>
<version>2.4.0</version>
</dependency>
Если вы хотите добавить jar файл в проект, то скачайте последнюю версию библиотеки по этой ссылке и воспользуйтесь инструкцией по добавлению jar файла в проект Intellij IDEA.
Теперь напишем парсер, с помощью которого будем считывать информацию с csv файла:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package com.javadevblog.csv;

import org.supercsv.cellprocessor.Optional;
import org.supercsv.cellprocessor.constraint.NotNull;
import org.supercsv.cellprocessor.constraint.UniqueHashCode;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.ICsvBeanReader;
import org.supercsv.prefs.CsvPreference;

import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class CsvParserTest {

    public static void main(String[] args) throws IOException {

        List<Employee> employeeList = new ArrayList<>();
        ICsvBeanReader csvBeanReader = new CsvBeanReader(new FileReader("test.csv"),CsvPreference.STANDARD_PREFERENCE);

        // указываем как будем мапить
        String[] mapping = new String[]{"id", "name", "role", "salary"};

        // получаем обработчики
        CellProcessor[] procs = getProcessors();
        Employee employee;
        // обходим весь csv файлик до конца
        while ((employee = csvBeanReader.read(Employee.class, mapping, procs)) != null) {
            employeeList.add(employee);
        }
        System.out.println(employeeList);
        csvBeanReader.close();
    }

    /**
     * Задаем обработчики ячеек
     */
    private static CellProcessor[] getProcessors() {
        return new CellProcessor[]{
                new UniqueHashCode(), // для идентификатора (id)
                new NotNull(), // name не должно быть null
                new Optional(), // указываем, что это необязательное поле role
                new NotNull() // salary также не должно быть null
        };
    }
}
Обратите внимание, что мы сами задаем как именно нужно обрабатывать csv: мы явно указали обработчики для каждого поля и указали правила парсинга информации. Например, если поле role будет null, то парсер примет это как должное и дальше продолжит обработку файла просто записав null.
Запустим приведенную выше программу и посмотрим результаты парсинга в консоле:

[
Id=1;Имя=Андрей;Должность=программист;Зарплата=3000 USD,
Id=2;Имя=Ваня;Должность=тестер;Зарплата=2000 USD,
Id=3;Имя=Дима;Должность=программист;Зарплата=3000 USD,
Id=4;Имя=Оля;Должность=тестер;Зарплата=2000 USD]

Пишем в CSV файл с помощью библиотеки SuperCSV

Создать новый CSV файл с помощью Super CSV также просто, как и парсить данные, только теперь мы будем работать с классом CsvBeanWriter:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.javadevblog.csv;

import org.supercsv.cellprocessor.Optional;
import org.supercsv.cellprocessor.constraint.NotNull;
import org.supercsv.cellprocessor.constraint.UniqueHashCode;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.io.ICsvBeanWriter;
import org.supercsv.prefs.CsvPreference;

import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

public class CsvWriterTest {

    public static void main(String[] args) throws IOException {
        List<Employee> employees = generateData();

        StringWriter writer = new StringWriter();
        // создаем CsvBeanWriter со стандартными настройками (кодировка, переносы строк, разделители и т.д.)
        ICsvBeanWriter csvBeanWriter = new CsvBeanWriter(writer,CsvPreference.STANDARD_PREFERENCE);
        String[] header = new String[]{"id", "name", "role", "salary"};

        // создаем заголовок
        csvBeanWriter.writeHeader(header);

        for (Employee employee : employees) {
            csvBeanWriter.write(employee, header, getProcessors());
        }

        csvBeanWriter.close();

        System.out.println(writer.toString());
    }

    private static CellProcessor[] getProcessors() {
        return new CellProcessor[]{
                new UniqueHashCode(),
                new NotNull(),
                new Optional(),
                new Optional()
        };
    }

    private static List<Employee> generateData() {
        List<Employee> employees = new ArrayList<>();
        Employee employee = new Employee();
        employee.setId("1");
        employee.setName("Андрей");
        employee.setRole("разработчик");
        employee.setSalary("3000");

        Employee employee1 = new Employee();
        employee1.setId("2");
        employee1.setName("Дима");
        employee1.setRole("разработчик");

        Employee employee2 = new Employee();
        employee2.setId("3");
        employee2.setName("Марина");

        employees.add(employee);
        employees.add(employee1);
        employees.add(employee2);

        return employees;
    }

}
Обратите внимание, что для идентификации ячеек я добавил хедер-строку — она не обязательна, поэтому можете смело, если она вам не нужна.
Теперь запустим программу и посмотрим в консоль:

id,name,role,salary
1,Андрей,разработчик,3000
2,Дима,разработчик,
3,Марина,,
Важно отметить, что при создании обработчиков мы позволили nullable поля с помощью Optional(), поэтому Super CSV просто добавил пустоту.
С помощью UniqueHashCode() мы указываем на уникальность каждого идентификатора, поэтому при нахождении дубликатов id будет выброшен Exception SuperCsvConstraintViolationException().
Больше информации и примеров использования найдете на официальной странице SuperCSV.

Смотри также:

Комментариев нет:

Отправить комментарий