CSV означает «значения, разделенные запятыми». Файлы CSV в основном используются для создания файлов данных для экспорта или импорта данных. Язык Java не обеспечивает собственной поддержки для эффективной обработки файлов CSV. Без использования сторонних библиотек мы можем в конечном итоге создать свой собственный парсер CSV. Обычно нет смысла изобретать велосипед, поэтому рекомендуется использовать такие сторонние инструменты для парсинга файлов CSV.
OpenCSV — это инструмент, который можно использовать для чтения CSV-файла в Java или записи данных в CSV-файл.
1. Настройка
Если мы работаем над проектом Maven, мы можем включить последнюю зависимость OpenCSV maven в файл pom.xml, как показано ниже.
<dependency><groupId>com.opencsv</groupId><artifactId>opencsv</artifactId><version>5.7.0</version></dependency>
В этом уроке мы будем читать и писать следующий файл во всех примерах. Мы поместили этот файл в папку /resources приложения.
ID,FNAME,LNAME,СТРАНА,ВОЗРАСТ1,Локеш,Гупта,Индия,322,Дэвид,Миллер,Англия,34
2. Основные классы OpenCSV
Ниже приведен список наиболее используемых классов OpenCSV, которые нам следует рассмотреть.
- CSVParser : Очень простой парсер CSV, выпущенный под коммерческой лицензией. Он просто реализует разбиение одной строки на поля.
- CSVReader : Вы будете использовать этот класс большую часть времени при чтении CSV-файла из кода вашего приложения Java. Этот класс предоставляет ряд полезных конструкторов для построения CSVReader с различными опциями и возможностями. Например, вы можете указать другой символ-разделитель(по умолчанию запятая), другой символ кавычек(по умолчанию двойные кавычки) и даже указать начальный номер строки, с которой должен начинаться анализ.
- CSVWriter : CSVWriter также очень настраиваемый, как и CSVReader. Вы можете использовать пользовательский разделитель, пользовательский символ кавычек или пользовательский символ конца строки при записи CSV-файла с использованием кода вашего приложения Java.
- CsvToBean : Этот класс будет использоваться, когда вы хотите заполнить ваши Java-бины из содержимого CSV-файла. Ниже вы увидите пример.
- BeanToCsv : если вы хотите экспортировать данные в CSV-файл из вашего Java-приложения, вам также может понадобиться помощь этого класса.
- ColumnPositionMappingStrategy : если вы планируете использовать CsvToBean(или BeanToCsv) для импорта данных CSV, вы будете использовать этот класс для сопоставления полей CSV с полями Java Bean.
3. Анализ и чтение CSV-файла
3.1 Чтение CSV-файла построчно
Как упоминалось выше, для чтения CSV-файла нам понадобится класс CSVReader. Давайте рассмотрим краткий пример чтения CSV-файла построчно.
- Мы можем использовать CSVParserBuilder для предоставления любого пользовательского символа-разделителя.
- Мы можем использовать CSVReaderBuilder, чтобы указать количество строк, которые нужно пропустить. Это полезно, если CSV-файл имеет заголовки в первой строке, а мы не хотим читать заголовки.
import com.opencsv.CSVParser;import com.opencsv.CSVParserBuilder;import com.opencsv.CSVReader;import com.opencsv.CSVReaderBuilder;import java.io.FileReader;import java.net.URL;import java.util.Arrays;public class ParseCSVLineByLine {@SuppressWarnings("resource")public static void main(String[] args) throws Exception {URL fileUrl = ParseCSVLineByLine.class.getClassLoader().getResource("data.csv");//Build reader instance//Read data.csv//Default separator is comma//Start reading from line number 2(line numbers start from zero)CSVParser csvParser = new CSVParserBuilder().withSeparator(',').withIgnoreQuotations(true).build();CSVReader csvReader = new CSVReaderBuilder(new FileReader(fileUrl.getFile())).withSkipLines(1).withCSVParser(csvParser).build();//Read CSV line by line and use the string array as you wantString[] nextLine;while((nextLine = csvReader.readNext()) != null) {if(nextLine != null) {//Verifying the read data hereSystem.out.println(Arrays.toString(nextLine));}}}}
3.2. Чтение всего CSV-файла и итерация по строкам
В приведенном выше примере CSV-файл считывается строка за строкой и выводится на консоль. Мы можем прочитать весь CSV-файл один раз, а затем перебирать данные по своему усмотрению. Ниже приведен пример построения чтения CSV-данных с использованием метода readAll().
import com.opencsv.CSVReader;import java.io.FileReader;import java.net.URL;import java.util.Arrays;import java.util.List;public class ParseFullCSVExample {@SuppressWarnings("resource")public static void main(String[] args) throws Exception {URL fileUrl = ParseCSVLineByLine.class.getClassLoader().getResource("data.csv");//Build reader instanceCSVReader reader = new CSVReader(new FileReader(fileUrl.getFile()));//Read all rows at onceList<String[]> allRows = reader.readAll();//Read CSV line by line and use the string array as you wantfor(String[] row : allRows) {System.out.println(Arrays.toString(row));}}}
4. Запись в CSV-файл
Написать CSV-файл так же просто, как и прочитать его. Создайте экземпляр CSVWriter с соответствующими параметрами конфигурации и начните записывать данные в CSV-файл.
Обратите внимание на необязательный второй аргумент в writeNext(nextLine, applyQuotesToAll). Когда мы устанавливаем applyQuotesToAll в значение true, то все значения, записанные в CSV-файл, будут без двойных кавычек.
import com.opencsv.CSVWriter;import java.io.FileWriter;import java.net.URL;public class WritingCSVFileExample {public static void main(String[] args) throws Exception {URL fileUrl = WritingCSVFileExample.class.getClassLoader().getResource("data.csv");CSVWriter writer = new CSVWriter(new FileWriter(fileUrl.getFile()));//Create recordString[] record = "2,Rahul,Vaidya,India,35".split(",");//Write the record to filewriter.writeNext(record, false);//close the writerwriter.close();}}
5. Добавление к существующему CSV-файлу
Предыдущий пример создает новый CSV-файл и начинает записывать данные с начала, т. е. со строки номер 0. Часто мы хотим добавить данные в существующий CSV-файл вместо записи нового файла. Мы можем добиться этой функциональности, передав режим добавления в качестве второго аргумента экземпляру FileWriter.
CSVWriter writer = new CSVWriter(new FileWriter(fileUrl.getFile(), true));
В библиотеке OpenCSV нет прямой поддержки добавления.
import com.opencsv.CSVWriter;import java.io.FileWriter;import java.net.URL;public class WritingCSVFileExample {public static void main(String[] args) throws Exception {URL fileUrl = WritingCSVFileExample.class.getClassLoader().getResource("data.csv");CSVWriter writer = new CSVWriter(new FileWriter(fileUrl.getFile(), true));//Create recordString[] record = new String[]{"3","Rahul","Vaidya","India","35"};//Write the record to filewriter.writeNext(record, false);//close the writerwriter.close();}}
Теперь проверьте файл data.csv.
ID,FNAME,LNAME,COUNTRY,AGE1,Lokesh,Gupta,India,322,David,Miller,England,343,Rahul,Vaidya,India,35
7. Чтение CSV в Java Bean
OpenCSV также предоставляет функционал для чтения CSV-файлов напрямую в Java-бины. Предположим, что Java POJO — это класс Employee. Для простоты мы создаем все поля типа String.
import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;@Data@AllArgsConstructor@NoArgsConstructorpublic class Employee{private String id;private String firstName;private String lastName;private String country;private String age;}
Ниже приведен пример чтения файла data.csv и заполнения экземпляров Employee. Затем он проверяет данные, выводя их на консоль.
import com.opencsv.CSVReader;import com.opencsv.bean.ColumnPositionMappingStrategy;import com.opencsv.bean.CsvToBean;import java.io.FileReader;import java.net.URL;import java.util.List;public class CSVMappedToJavaBeanExample {@SuppressWarnings({"rawtypes", "unchecked"})public static void main(String[] args) throws Exception {URL fileUrl = CSVMappedToJavaBeanExample.class.getClassLoader().getResource("data.csv");CSVReader csvReader = new CSVReader(new FileReader(fileUrl.getFile()));CsvToBean csv = new CsvToBean();csv.setCsvReader(csvReader);csv.setMappingStrategy(setColumMapping());List list = csv.parse();for(Object object : list) {Employee employee =(Employee) object;System.out.println(employee);}}@SuppressWarnings({"rawtypes", "unchecked"})private static ColumnPositionMappingStrategy setColumMapping() {ColumnPositionMappingStrategy strategy = new ColumnPositionMappingStrategy();strategy.setType(Employee.class);String[] columns = new String[]{"id", "firstName", "lastName", "country", "age"};strategy.setColumnMapping(columns);return strategy;}}
Вывод программы.
Employee(id=ID, firstName=FNAME, lastName=LNAME, country=COUNTRY, age=AGE)Employee(id=1, firstName=Lokesh, lastName=Gupta, country=India, age=32)Employee(id=2, firstName=David, lastName=Miller, country=England, age=34)Employee(id=3, firstName=Rahul, lastName=Vaidya, country=India, age=35)
8. Создание CSV из данных SQL
Теперь это также желаемая активность, которая нам понадобится в приложениях. Для экспорта данных напрямую из таблиц SQL в файлы CSV нам понадобится объект ResultSet. Следующий API можно использовать для записи данных в CSV из ResultSet, используя полученную ссылку ResultSet.
java.sql.ResultSet myResultSet = getResultSetFromSomewhere();writer.writeAll(myResultSet, includeHeaders); //writer — это экземпляр CSVWriter
В приведенном выше методе первый аргумент — это ResultSet, который мы хотим записать в CSV-файл. А второй аргумент — это логическое значение, которое представляет, хотим ли мы записать столбцы заголовков(имена столбцов таблицы) в файл или нет.
9. Заключение
В этом руководстве объяснялось базовое использование библиотеки OpenCSV для чтения и записи CSV-файлов из кода приложения Java. Мы научились читать CSV-файл построчно и весь файл за один раз. Мы также научились настраивать считыватель для предоставления пользовательского разделителя и пропуска строк в случае, если файл имеет заголовок имен столбцов в качестве первой строки.
Наконец, мы научились записывать данные CSV в новый файл и добавлять их к существующему файлу CSV.