Ошибка памяти электронной таблицы ColdFusion
Я использую ColdFusion для экспорта довольно небольшого числа строк (около 1000), но большого количества столбцов (около 300) в Excel. Это многослойный файл Excel, в котором по крайней мере два листа содержат большое количество столбцов. С помощью cfspreadsheet
выдает ошибку кучи Java. Обновление значения параметров JVM не показывает улучшения. Каков наилучший способ экспорта в Excel без возникновения ошибки кучи Java?
Изменить: я пробовал несколько способов исправить проблему в программе. Я использую книгу xml в cfsavecontent для создания нескольких листов и рендеринга результата с использованием cfcontent. В этом случае cfcontent может использовать большой объем памяти, что приводит к ошибке пространства кучи.
<cfsavecontent variables="REQUEST.xmlData">
<cfoutput>
<xml version="1.0"?>
<?mso-application progid="Excel.sheet"?>
<Workbook>
...other contents
</Workbook>
</cfoutput>
</cfsavecontent>
Для второго обходного пути я использую querynew для создания содержимого и вывода окончательного результата в Excel с помощью <Cfspreadsheet action="write">
, Для последующих листов я использую <cfspreadsheet action="update">
, Конечная цель - служить Excel, используя <cflocation url="excelPath">
, но в этом случае обновление cfspreadsheet всегда приводит к ошибке из памяти.
Если обновление jvm не вариант, какие другие способы вы предлагаете для решения проблем с памятью.
1 ответ
Я немного опоздал на вечеринку...
Из того, что я могу сказать, cfspreadsheet
пытается материализовать весь файл в памяти перед сбросом на диск. С cfsavecontent
Вы делаете это явно.
Вы знакомы с созданием Workbook XML, так что все, что ваше cfsavecontent
Подход требует потоковой передачи на диск.
Это может быть достигнуто, копаясь в базовых библиотеках Java. java.io.FileWriter
можно добавить в файл, не сохраняя весь файл в памяти:
var append = true;
var writer = createobject("java", "java.io.FileWriter").init(filename, append);
try {
writer.append("<xml version=""1.0""?>\n<?mso-application progid=""Excel.sheet""?>\n<Workbook>\n");
// Build your workbook in chunks
// for (var row in query)
// writer.append(markup)
writer.append("</Workbook>");
} finally {
writer.close();
}
Я думаю, что после тестирования FileWriter
Запускает flush
регулярно, поэтому я пропустил это, но я не могу найти документацию, подтверждающую, что это так. Я никогда не видел, чтобы использование памяти становилось очень высоким, но YMMV.