如何解决SpreadSheetAddRows功能崩溃加入大量查询时?(How do I fix Sp

2019-08-04 05:35发布

EDIT3:由于@Leigh的帮助下我已经缩小的问题在查询日期列。 使用原来的代码集和POI,页面崩溃时SpreadSheetAddRows()尝试添加包含日期样细胞非常大的查询。 我在这里做了一个错误报告: https://bugbase.adobe.com/index.cfm?event=bug&id=3432184 。


我有我加入,似乎当查询行的unweildly量(18583在这个例子中)错误而等试算表对象的查询。 确切的错误如下:

java.lang.ArrayIndexOutOfBoundsException: -32735
at java.util.ArrayList.get(ArrayList.java:324)
at org.apache.poi.hssf.model.WorkbookRecordList.get(WorkbookRecordList.j ava:50)
at org.apache.poi.hssf.model.Workbook.getExFormatAt(Workbook.java:787)
at org.apache.poi.hssf.usermodel.HSSFCell.getCellStyle(HSSFCell.java:901 )
at org.apache.poi.hssf.usermodel.HSSFSheet.autoSizeColumn(HSSFSheet.java :1727)
at coldfusion.excel.Excel.autoResize(Excel.java:1246)
at coldfusion.excel.Excel.autoResize(Excel.java:1240)
at coldfusion.excel.Excel.addRows(Excel.java:1214)
at coldfusion.runtime.CFPage.SpreadSheetAddRows(CFPage.java:7089) at coldfusion.runtime.CFPage.SpreadSheetAddRows(CFPage.java:7076)

下面是相关的代码:

<cfset xls = spreadsheetNew()>
<cfset spreadsheetAddRow(xls, arrayToList( qryTest.getMeta().getColumnLabels() ))>
<cfset SpreadsheetFormatRow(xls, {bold=true,fgcolor="brown",color="white"}, 1)>
<cfset SpreadsheetAddRows(xls, qryTest)>
<cfheader name="Content-Disposition" value="attachment; filename=#filename#">
<cfcontent variable="#spreadsheetReadBinary(xls)#" reset="yes" type="application/vnd.ms-excel">

编辑:我没有用以前cfspreadsheet成功,但它不会产生与头一个电子表格(它也有需要创建一个临时文件服务的缺点。)


EDIT2:继@Leigh建议我在CF9 / lib文件夹更新POI。 现在该错误已更改为以下几点:

<cfset SpreadsheetFormatRow(xls, {bold=true,fgcolor="brown",color="white"}, 1)>提供了以下信息:org.apache.poi.hssf.util.HSSFColor.getIndexHash()Ljava / util的/哈希表;

错误代码:

java.lang.NoSuchMethodError:
org.apache.poi.hssf.util.HSSFColor.getIndexHash()Ljava/util/Hashtable;
at coldfusion.excel.Excel.getHSSFColor(Excel.java:2094)
at coldfusion.excel.Excel.findFont(Excel.java:2237)
at coldfusion.excel.Excel.getCellStyle(Excel.java:2318)
at coldfusion.excel.Excel.formatRow(Excel.java:2948)
at coldfusion.excel.Excel.formatRow(Excel.java:2963)
at coldfusion.excel.Excel.formatRow(Excel.java:2981)
at coldfusion.runtime.CFPage.SpreadSheetFormatRow(CFPage.java:7268)

并表示线路输出端口,它现在再次崩溃: <cfset SpreadsheetAddRows(xls, qryTest)>

错误代码:

java.lang.IllegalStateException: The maximum number of cell styles was exceeded. You can define up to 4000 styles in a .xls workbook 
at org.apache.poi.hssf.usermodel.HSSFWorkbook.createCellStyle(HSSFWorkbook.java:1120) 
at org.apache.poi.hssf.usermodel.HSSFWorkbook.createCellStyle(HSSFWorkbook.java:73) 
at coldfusion.excel.Excel.addRow(Excel.java:1323)
at coldfusion.excel.Excel.addRows(Excel.java:1203) 
at coldfusion.runtime.CFPage.SpreadSheetAddRows(CFPage.java:7089) 
at coldfusion.runtime.CFPage.SpreadSheetAddRows(CFPage.java:7076) 

Answer 1:

我怀疑它有没有关系CF或JRE版本都没有。 至少没有直接。 这听起来像在POI的错误。

如果你看一下例外它清楚地表明,当CF调用试图自动调整列的POI方法(后添加查询数据)出现问题。 快速搜索打开了类似的几份报告ArrayIndexOutOfBoundsException与错误HSSFSheet.autoSizeColumn 像这样的 (这恰好提到的ColdFusion):

如果尝试设置超过32767个细胞,然后ArrayOutOfBoundsException抛出之后,在列中使用org.apache.poi.hssf.usermodel.HSSFSheet和方法autosizecolumn(INT)。

按照bug报告在3.5版本中,这包括使用ColdFusion 9.其中一个POI开发商相同的(主要)版本说明这个问题被固定在以后的版本中存在的问题。 所以,你可以尝试更新POI罐子。 除此之外,如果你能放在一起再现这一问题的测试用例,你可能要提交错误报告 。

我以前使用cfspreadsheet成功,但它不会产生与头一个电子表格(它也有需要创建一个临时文件服务的缺点。)

cfspreadsheet可能不会尝试像自动调整列spreadsheetAddRows做,因此不会发生错误。 因此,明显的解决方法(而不是一个伟大的)是避免尝试调整列宽功能。



Answer 2:

如果从代码退一步,只是检查错误被抛出你从Java文档这和这里是另一个参考

抛出,表明阵列已与非法索引访问。 的索引或者为负,或者大于或等于所述阵列的大小。

该错误也表明你试图非法索引值: -32735

现在你的问题是,由于您使用的是ColdFusion的功能,你没有指定在你的代码本身的指数值。 该函数( SpreadsheetAddRows )正试图查询结果转换到一个数组,然后追加对这些值到Excel电子表格的行。 它利用底层Java运行时来执行这些任务,并且抛出一个错误。 所以,恐怕你有点粘有此限制您遇到。 你可以尝试升级您的ColdFusion安装运行,看看问题是否已在新版本中已解决的JRE版本。 我相信的ColdFusion 9个随Java 1.6.0_14 在这里看到 。 你应该至少运行1.6.0_24反正因为的DOS漏洞的补丁 。 看起来他们是长达1.6.0_38 现在 ,但你必须检查已安装Adobe支持。

如果要升级JRE不能解决问题,那么我相信你将需要改变你的ColdFusion代码以避免此问题。 你说你使用过成功CFSpreadSheet标签。 或者你可以玩不同的方式来传递你的查询结果的SpreadsheetAddRows功能。 (虽然我假设你已经用完即大道。)也许遍历查询,并建立自己的阵列或遍历查询,并添加行一次一个。 我知道这可能不是最优的,但尝试一些不同的方法之一将有望走出来的路来走了。

我也将增加ColdFusion的标签(不带版本号),你的岗位上得到一些更多的目光投向它。

UPDATE

只是想跟进支持的Java版本的ColdFusion 9.我发现查理Arehart这篇博客 ,讨论Adobe的关于Java升级立场ColdFusion的服务器。 链接到这里Adobe官方职务其中规定,任何轻微的升级版本将支持。 所以对于ColdFusion的9“今后所有的JDK版本1.6.0_x支持”。



Answer 3:

(从提取http://poi.apache.org/spreadsheet/quick-guide.html )

请注意,工作簿中的独特的字体的最大数量限制为32767(最大正短)。 在apllications您应该重新使用的字体,而不是创建每个小区的字体。 例子:

错误:

 for (int i = 0; i < 10000; i++) { Row row = sheet.createRow(i); Cell cell = row.createCell((short) 0); CellStyle style = workbook.createCellStyle(); Font font = workbook.createFont(); font.setBoldweight(Font.BOLDWEIGHT_BOLD); style.setFont(font); cell.setCellStyle(style); } 

正确:

 CellStyle style = workbook.createCellStyle(); Font font = workbook.createFont(); font.setBoldweight(Font.BOLDWEIGHT_BOLD); style.setFont(font); for (int i = 0; i < 10000; i++) { Row row = sheet.createRow(i); Cell cell = row.createCell((short) 0); cell.setCellStyle(style); } 

无论如何,你可以试试这个太:

org.apache.poi.hssf.usermodel.HSSFOptimiser.optimiseCellStyles(HSSFWorkbook)


Answer 4:

在我与阵列的经验,当你得到一个OutOfBounds异常,通常是因为我有“超限”的阵列-也就是,我比循环的索引项的总数多一个。 这通常是因为我忘了,当数组从0开始,我只能回路数组长度 - 1。

确保你是不是循环过去的数组的长度。



文章来源: How do I fix SpreadSheetAddRows function crashing when adding a large query?