В этой статье мы рассмотрим простой способ обработки 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 2 3 4 |
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:
1 2 3 4 5 |
<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.
Запустим приведенную выше программу и посмотрим результаты парсинга в консоле:
1 2 3 4 5 |
[ 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; } } |
Обратите внимание, что для идентификации ячеек я добавил хедер-строку — она не обязательна, поэтому можете смело, если она вам не нужна.
Теперь запустим программу и посмотрим в консоль:
1 2 3 4 |
id,name,role,salary 1,Андрей,разработчик,3000 2,Дима,разработчик, 3,Марина,, |
Важно отметить, что при создании обработчиков мы позволили nullable поля с помощью Optional()
, поэтому Super CSV просто добавил пустоту.
С помощью UniqueHashCode()
мы указываем на уникальность каждого идентификатора, поэтому при нахождении дубликатов id будет выброшен Exception SuperCsvConstraintViolationException()
.
Больше информации и примеров использования найдете на официальной странице SuperCSV.
Подписывайтесь на новые статьи по Java разработке!