Файл *.xlsx
, который Excel
хранится в Office Open XML и который apache poi
обрабатывает как XSSF
, представляет собой ZIP
архив, содержащий данные в XML
файлах в структуре каталогов.Таким образом, мы можем разархивировать файл *.xlsx
и получить данные непосредственно из файлов XML
.
В нем есть /xl/sharedStrings.xml
, содержащий все значения строковых ячеек.И есть /xl/workbook.xml
, описывающий структуру рабочей книги.И есть /xl/worksheets/sheet1.xml, /xl/worksheets/sheet2.xml, ...
, которые хранят данные листов.И /xl/styles.xml
имеет настройки стиля для всех ячеек на листах.
По умолчанию при создании XSSFWorkbook
все эти части файла *.xlsx
станут объектными представлениями как XSSFWorkbook
, XSSFSheet
, XSSFRow
, XSSFCell
, ... и другие объекты размером org.apache.poi.xssf.*.*
в памяти.
Чтобы получить представление о том, как потребляют память XSSFSheet
, XSSFRow
и XSSFCell
Посмотрите на источники будет хорошо.Каждый из этих объектов содержит несколько List
s и Map
s в качестве внутренних членов и, конечно, также несколько методов.Теперь представьте лист с сотнями тысяч строк, каждый из которых содержит до сотен ячеек.Каждая из этих строк и ячеек будет представлена в памяти XSSFRow
или XSSFCell
.Это не может быть обвинением в apache poi
, потому что эти объекты необходимы, если необходима работа с этими объектами.Но если на самом деле нужно только извлечь содержимое из листа Excel
, то эти объекты не являются необходимыми.Вот почему XSSF и SAX (Event API) подходят.
Поэтому, если нужно только читать данные с листов, можно просто проанализировать XML
всех файлов /xl/worksheets/sheet[n].xml
безнеобходимость создания объектов, потребляющих память, для каждого листа и для каждой строки и для каждой ячейки в этих листах.
Синтаксический анализ XML
в режиме на основе событий означает, что код идет сверху вниз через XML
и имеет определенные методы обратного вызова, которые вызываются, если код обнаруживает начало элемента, конец элемента илисодержание символа в элементе.Затем соответствующие методы обратного вызова обрабатывают, что делать в начале, в конце или с символьным содержимым элемента.Таким образом, чтение файла XML
означает только однократную пробежку по файлу сверху вниз, обработку событий (начало, конец, символьное содержимое элемента) и возможность извлечь из него весь необходимый контент.Таким образом, потребление памяти сокращается до хранения текстовых данных, полученных из XML
.
XSSF и SAX (Event API) использует класс SheetHandler
, который расширяет DefaultHandler для этого.
Но если мы уже находимся на этом уровне, где мы получаем базовые данные XML
и обрабатываем их, то мы могли бы также сделать еще один шаг назад.Родной Java
способен обрабатывать ZIP
и анализировать XML
.Поэтому нам даже не понадобятся дополнительные библиотеки.См. , как читать файл Excel, имеющий более 100000 строк в Java? , где я это показал.Мой код использует пакет javax.xml.stream , который также обеспечивает использование событий на основе XMLEventReader
, но не с использованием обратных вызовов, а с использованием линейного кода.Возможно, этот код проще для понимания, потому что он все в одном.
Для определения того, является ли числовой формат форматом даты, и поэтому отформатированная ячейка содержит значение даты / времени, один единственный apache poi
класс org.apache.poi.ss.usermodel.DateUtil
используется.Это сделано для упрощения кода.Конечно, даже этот класс мы могли бы закодировать сами.