Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException
вообще.
См. также: A хороший список лучших практик
Я бы добавил, очень важно, хорошо использовать модификатор final
. Использование "окончательной" модификатор, когда это применимо в Java
Сводка:
final
для обеспечения хорошей инициализации. @NotNull
и @Nullable
if("knownObject".equals(unknownObject)
valueOf()
поверх toString (). StringUtils
StringUtils.isEmpty(null)
. SDK OpenXML является правильным инструментом для этого задания, но вам нужно быть осторожным, чтобы использовать подход SAX (простой API для XML), а не подход DOM . Из связанной статьи wikipedia для SAX:
Если DOM работает с документом в целом, SAX-парсеры последовательно работают с каждой частью XML-документа
blockquote>значительно уменьшает объем памяти, потребляемой при обработке больших файлов Excel.
Здесь есть хорошая статья - http://polymathprogrammer.com/2012/ 08/06 / how-to-right-use-openxmlwriter-to-write-large-excel-files /
Адаптировано из этой статьи, вот пример, который выводит строки 115k с 30 столбцами :
public static void LargeExport(string filename) { using (SpreadsheetDocument document = SpreadsheetDocument.Create(filename, SpreadsheetDocumentType.Workbook)) { //this list of attributes will be used when writing a start element List<OpenXmlAttribute> attributes; OpenXmlWriter writer; document.AddWorkbookPart(); WorksheetPart workSheetPart = document.WorkbookPart.AddNewPart<WorksheetPart>(); writer = OpenXmlWriter.Create(workSheetPart); writer.WriteStartElement(new Worksheet()); writer.WriteStartElement(new SheetData()); for (int rowNum = 1; rowNum <= 115000; ++rowNum) { //create a new list of attributes attributes = new List<OpenXmlAttribute>(); // add the row index attribute to the list attributes.Add(new OpenXmlAttribute("r", null, rowNum.ToString())); //write the row start element with the row index attribute writer.WriteStartElement(new Row(), attributes); for (int columnNum = 1; columnNum <= 30; ++columnNum) { //reset the list of attributes attributes = new List<OpenXmlAttribute>(); // add data type attribute - in this case inline string (you might want to look at the shared strings table) attributes.Add(new OpenXmlAttribute("t", null, "str")); //add the cell reference attribute attributes.Add(new OpenXmlAttribute("r", "", string.Format("{0}{1}", GetColumnName(columnNum), rowNum))); //write the cell start element with the type and reference attributes writer.WriteStartElement(new Cell(), attributes); //write the cell value writer.WriteElement(new CellValue(string.Format("This is Row {0}, Cell {1}", rowNum, columnNum))); // write the end cell element writer.WriteEndElement(); } // write the end row element writer.WriteEndElement(); } // write the end SheetData element writer.WriteEndElement(); // write the end Worksheet element writer.WriteEndElement(); writer.Close(); writer = OpenXmlWriter.Create(document.WorkbookPart); writer.WriteStartElement(new Workbook()); writer.WriteStartElement(new Sheets()); writer.WriteElement(new Sheet() { Name = "Large Sheet", SheetId = 1, Id = document.WorkbookPart.GetIdOfPart(workSheetPart) }); // End Sheets writer.WriteEndElement(); // End Workbook writer.WriteEndElement(); writer.Close(); document.Close(); } } //A simple helper to get the column name from the column index. This is not well tested! private static string GetColumnName(int columnIndex) { int dividend = columnIndex; string columnName = String.Empty; int modifier; while (dividend > 0) { modifier = (dividend - 1) % 26; columnName = Convert.ToChar(65 + modifier).ToString() + columnName; dividend = (int)((dividend - modifier) / 26); } return columnName; }
Excel способен открывать довольно большие файлы, если на вашем компьютере достаточно памяти. Это в большинстве случаев ограничивающий фактор ...
99% библиотек там не были созданы для обработки большого набора данных, и в итоге у вас появятся ошибки в памяти, если вы тоже попытаетесь выбросить много данных у них.
Некоторые из них, например Spout , которые я создал, были созданы для решения этой проблемы. Хитрость заключается в том, чтобы передавать данные и избегать хранения вещей в памяти. Я не уверен, какой язык вы используете (а не PHP), но для вашего языка может быть подобная библиотека. Если нет, вы можете взглянуть на Spout - это open-source - и конвертировать его на ваш язык.
Похоже, вы используете электронную таблицу, где должна использоваться база данных. У этого есть свои ограничения, и это может быть легко одним из них. Читайте дальше только в том случае, если вам абсолютно необходимо придерживаться существующего решения. Однако я не рекомендую его. Потому что есть еще один вопрос: если Excel не может сохранить такой большой файл, сможет ли он открыть такой файл?
Итак, если вы не можете переключиться на платформу базы данных и стандартные библиотеки, о которых вы говорили выше, внутренне неспособный обрабатывать такое количество данных, то, возможно, вы сами по себе при создании большого XLSX. Я имею в виду, например, такой подход:
file.xlsx\xl\worksheets\sheet1.xml
и file.xlsx\xl\worksheets\sharedStrings.xml
), склеивая эти части вместе с помощью библиотеки XML-манипулирования (это не должно приводить к сбою OutOfMemoryException, потому что вы больше не работаете со сложными объектами электронных таблиц), переупаковывая файлы результатов обратно на главную XLSX (вы можете взять первый пакетный выходной файл в качестве основного XLSX) Я показал вам возможный способ достижения результата, но я бы этого избежал. Excel никогда не был платформой для хранения больших объемов данных. По сравнению с вышеуказанной задачей было бы легче убедить руководство в том, что пришло время изменить инструменты / процессы в этой области.
GetColumnName
верен, но я не написал кучу тестов для подтверждения. – petelids 19 May 2017 в 16:0626
- это просто количество букв в алфавите; когда мы дойдем доZ
, следующий столбец станетAA
, затем изAZ
переходим кBA
и т. д.65
- это значение ASCII дляA
... У меня нет других ответы, которые объясняют эту логику, но у меня есть ответ, который объясняет это другим способом (например, преобразование ссылки на ячейку в индекс столбца), что может помочь объяснить вещи немного больше. Это можно найти здесь здесь . – petelids 19 May 2017 в 16:28