Научитесь читать или писать огромные файлы Excel с помощью библиотеки fastexcel, которая является отличной альтернативой Apache POI. Хотя POI является самой популярной библиотекой для работы с файлами Excel, она не подходит для работы с большими файлами Excel из-за высокого потребления памяти и вычислительной мощности.
- Непотоковый API Apache POI примерно в десять раз медленнее, чем fastexcel, и использует в 12 раз больше динамической памяти.
- Потоковое API Apache POI обеспечивает почти аналогичную производительность.
В целом, FastExcel предоставляет довольно простой и упрощенный API для начала работы. Он гораздо эффективнее обрабатывает память и очень хорошо обрабатывает большие файлы. Обратите внимание, что FastExcel поддерживает ограниченный набор функций — он фокусируется на скорости и сокращении памяти.
1. Знаток
Начните с добавления последней версии следующих зависимостей:
- fastexcel : для написания файлов Excel.
- fastexcel-reader : для чтения файлов Excel.
<dependency><groupId>org.dhatim</groupId><artifactId>fastexcel</artifactId><version>0.14.0</version></dependency><dependency><groupId>org.dhatim</groupId><artifactId>fastexcel-reader</artifactId><version>0.14.0</version></dependency>
2. Написание большого файла Excel
2.1.АПИ
Чтобы написать файл Excel, начните с создания нового экземпляра org.dhatim.fastexcel.Workbook и получите ссылку org.dhatim.fastexcel.Worksheet с помощью метода newWorksheet().
OutputStream os = new FileOutputStream("file.xlsx");Workbook wb = new Workbook(outputStream, "DemoExcel", "1.0");Worksheet ws = wb.newWorksheet("Sheet 1");
Теперь мы можем использовать различные методы в Worksheet для установки значений в ячейках.
ws.value(0, 0, "Some Value"); //A1ws.value(0, 1, LocalDateTime.now()); //A2ws.value(0, 2, 100); //A3ws.value(1, 0, "Some Value"); //B1ws.value(1, 1, LocalDateTime.now()); //B2ws.value(1, 2, 100); //B3
Мы также можем применять формулы в ячейках.
ws.formula(10, 0, "SUM(A1:A10)");
2.2 Пример
Ниже приведен пример записи 1 000 000 строк в таблицу, где каждая строка содержит 10 значений ячеек. Мы также используем API StopWatch для измерения производительности.
import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.util.concurrent.TimeUnit;import org.apache.commons.lang3.time.StopWatch;import org.dhatim.fastexcel.Workbook;import org.dhatim.fastexcel.Worksheet;public class WriteExcel {public static void main(String[] args) throws IOException {try(OutputStream os = new FileOutputStream("c:/temp/fastexcel-demo.xlsx")) {Workbook wb = new Workbook(os, "DemoExcel", "1.0");Worksheet ws = wb.newWorksheet("Sheet 1");StopWatch watch = new StopWatch();watch.start();ws.value(0, 0, "Column 1");ws.value(0, 1, "Column 2");ws.value(0, 2, "Column 3");ws.value(0, 3, "Column 4");ws.value(0, 4, "Column 5");ws.value(0, 5, "Column 6");ws.value(0, 6, "Column 7");ws.value(0, 7, "Column 8");ws.value(0, 8, "Column 9");ws.value(0, 9, "Column 10");for(int i = 1; i < 1_000_000; i++) {String value = "data-" + i;ws.value(i, 0, i);ws.value(i, 1, value);ws.value(i, 2, value);ws.value(i, 3, value);ws.value(i, 4, value);ws.value(i, 5, value);ws.value(i, 6, value);ws.value(i, 7, value);ws.value(i, 8, value);ws.value(i, 9, value);}wb.finish();watch.stop();System.out.println("Processing time :: " + watch.getTime(TimeUnit.MILLISECONDS));} catch(Exception e) {e.printStackTrace();}}}
Вся программа выполняется на моем компьютере примерно за 5-6 секунд и записывает файл Excel размером 37 МБ.
3. Чтение большого файла Excel
3.1.АПИ
FastExcel предоставляет потоковый API, который выполняет итерацию по всем строкам и предоставляет методы get() для чтения значений ячеек в соответствии с типами значений ячеек.
try(Stream<Row> rows = sheet.openStream()) {rows.forEach(r -> {BigDecimal num = r.getCellAsNumber(0).orElse(null);......});}
Для чтения значений ячеек можно использовать следующие методы get:
- getCellAsNumber(): возвращает тип Optional<BigDecimal>.
- getCellAsString(): возвращает тип Optional<String>.
- getCellAsDate(): возвращает тип Optional<LocalDateTime>.
- getCellAsBoolean(): возвращает необязательный<логический> тип.
- getCellText(): возвращает тип String.
- getCellRawValue(): возвращает тип Optional<String>.
3.2 Пример
Следующая программа считывает файл Excel, созданный в предыдущем разделе, и записывает значения ячеек в консоль, чтобы упростить код.
import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.math.BigDecimal;import java.util.concurrent.TimeUnit;import java.util.stream.Stream;import org.apache.commons.lang3.time.StopWatch;import org.dhatim.fastexcel.reader.ReadableWorkbook;import org.dhatim.fastexcel.reader.Row;public class ReadExcel {public static void main(String[] args) throws IOException {try(InputStream is = new FileInputStream("c:/temp/fastexcel-demo.xlsx");ReadableWorkbook wb = new ReadableWorkbook(is)) {StopWatch watch = new StopWatch();watch.start();wb.getSheets().forEach(sheet ->{try(Stream<Row> rows = sheet.openStream()) {rows.skip(1).forEach(r -> {BigDecimal num = r.getCellAsNumber(0).orElse(null);String str = r.getCellAsString(1).orElse(null);System.out.println("Cell str value :: " + num);System.out.println("Cell str value :: " + str);});} catch(Exception e) {e.printStackTrace();}watch.stop();System.out.println("Processing time :: " + watch.getTime(TimeUnit.MILLISECONDS));});}}}
На моем компьютере вся программа выполняется примерно за 7-8 секунд.
4. Заключение
В этом уроке Java мы научились использовать библиотеку FastExcel для эффективного чтения и записи больших файлов Excel. Мы изучили API для операций чтения и записи, а также простые примеры для них. Вы можете настроить программы в соответствии с требованиями вашего проекта.