POI Bug 58260: Fix checks for limit on number of styles in XSSF/SXSSF and fix having more than 32k styles in SXSSF workbooks
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1696586 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a6caec985c
commit
c275dea88c
@ -563,11 +563,12 @@ public class StylesTable extends POIXMLDocumentPart {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public XSSFCellStyle createCellStyle() {
|
public XSSFCellStyle createCellStyle() {
|
||||||
int xfSize = styleXfs.size();
|
if (getNumCellStyles() > MAXIMUM_STYLE_ID) {
|
||||||
if (xfSize > MAXIMUM_STYLE_ID)
|
|
||||||
throw new IllegalStateException("The maximum number of Cell Styles was exceeded. " +
|
throw new IllegalStateException("The maximum number of Cell Styles was exceeded. " +
|
||||||
"You can define up to " + MAXIMUM_STYLE_ID + " style in a .xlsx Workbook");
|
"You can define up to " + MAXIMUM_STYLE_ID + " style in a .xlsx Workbook");
|
||||||
|
}
|
||||||
|
|
||||||
|
int xfSize = styleXfs.size();
|
||||||
CTXf xf = CTXf.Factory.newInstance();
|
CTXf xf = CTXf.Factory.newInstance();
|
||||||
xf.setNumFmtId(0);
|
xf.setNumFmtId(0);
|
||||||
xf.setFontId(0);
|
xf.setFontId(0);
|
||||||
|
@ -189,7 +189,12 @@ public class SheetDataWriter {
|
|||||||
String ref = new CellReference(_rownum, columnIndex).formatAsString();
|
String ref = new CellReference(_rownum, columnIndex).formatAsString();
|
||||||
_out.write("<c r=\"" + ref + "\"");
|
_out.write("<c r=\"" + ref + "\"");
|
||||||
CellStyle cellStyle = cell.getCellStyle();
|
CellStyle cellStyle = cell.getCellStyle();
|
||||||
if (cellStyle.getIndex() != 0) _out.write(" s=\"" + cellStyle.getIndex() + "\"");
|
if (cellStyle.getIndex() != 0) {
|
||||||
|
// need to convert the short to unsigned short as the indexes can be up to 64k
|
||||||
|
// ideally we would use int for this index, but that would need changes to some more
|
||||||
|
// APIs
|
||||||
|
_out.write(" s=\"" + (cellStyle.getIndex() & 0xffff) + "\"");
|
||||||
|
}
|
||||||
int cellType = cell.getCellType();
|
int cellType = cell.getCellType();
|
||||||
switch (cellType) {
|
switch (cellType) {
|
||||||
case Cell.CELL_TYPE_BLANK: {
|
case Cell.CELL_TYPE_BLANK: {
|
||||||
|
@ -30,6 +30,7 @@ import java.io.IOException;
|
|||||||
import java.text.AttributedString;
|
import java.text.AttributedString;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
import org.apache.poi.hssf.util.PaneInformation;
|
import org.apache.poi.hssf.util.PaneInformation;
|
||||||
@ -775,8 +776,7 @@ public abstract class BaseTestBugzillaIssues {
|
|||||||
|
|
||||||
|
|
||||||
// References to try
|
// References to try
|
||||||
String ext = "xls";
|
String ext = _testDataProvider.getStandardFileNameExtension();
|
||||||
if (! (wb instanceof HSSFWorkbook)) ext += "x";
|
|
||||||
String refLocal = "'[test."+ext+"]Sheet1'!$A$2";
|
String refLocal = "'[test."+ext+"]Sheet1'!$A$2";
|
||||||
String refHttp = "'[http://example.com/test."+ext+"]Sheet1'!$A$2";
|
String refHttp = "'[http://example.com/test."+ext+"]Sheet1'!$A$2";
|
||||||
String otherCellText = "In Another Workbook";
|
String otherCellText = "In Another Workbook";
|
||||||
@ -1172,4 +1172,74 @@ public abstract class BaseTestBugzillaIssues {
|
|||||||
ev.evaluateFormulaCell(cell);
|
ev.evaluateFormulaCell(cell);
|
||||||
assertEquals("ab", cell.getStringCellValue());
|
assertEquals("ab", cell.getStringCellValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bug58260() throws IOException {
|
||||||
|
//Create workbook and worksheet
|
||||||
|
Workbook wb = _testDataProvider.createWorkbook();
|
||||||
|
Sheet worksheet = wb.createSheet("sample");
|
||||||
|
|
||||||
|
//Loop through and add all values from array list
|
||||||
|
// use a fixed seed to always produce the same file which makes comparing stuff easier
|
||||||
|
Random rnd = new Random(4352345);
|
||||||
|
int maxStyles = (wb instanceof HSSFWorkbook) ? 4009 : 64000;
|
||||||
|
for(int i = 0;i < maxStyles;i++) {
|
||||||
|
//Create new row
|
||||||
|
Row row = worksheet.createRow(i);
|
||||||
|
|
||||||
|
//Create cell style
|
||||||
|
final CellStyle style;
|
||||||
|
try {
|
||||||
|
style = wb.createCellStyle();
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
throw new IllegalStateException("Failed for row " + i, e);
|
||||||
|
}
|
||||||
|
style.setAlignment(CellStyle.ALIGN_RIGHT);
|
||||||
|
if((wb instanceof HSSFWorkbook)) {
|
||||||
|
// there are some predefined styles
|
||||||
|
assertEquals(i+21, style.getIndex());
|
||||||
|
} else {
|
||||||
|
// getIndex() returns short, which is not sufficient for > 32767
|
||||||
|
// we should really change the API to be "int" for getIndex() but
|
||||||
|
// that needs API changes
|
||||||
|
assertEquals(i+1, style.getIndex() & 0xffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create cell
|
||||||
|
Cell cell = row.createCell(0);
|
||||||
|
|
||||||
|
//Set cell style
|
||||||
|
cell.setCellStyle(style);
|
||||||
|
|
||||||
|
//Set cell value
|
||||||
|
cell.setCellValue("r" + rnd.nextInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
// should fail if we try to add more now
|
||||||
|
try {
|
||||||
|
wb.createCellStyle();
|
||||||
|
fail("Should fail after " + maxStyles + " styles, but did not fail");
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
// expected here
|
||||||
|
}
|
||||||
|
|
||||||
|
/*//add column width for appearance sake
|
||||||
|
worksheet.setColumnWidth(0, 5000);
|
||||||
|
|
||||||
|
// Write the output to a file
|
||||||
|
System.out.println("Writing...");
|
||||||
|
OutputStream fileOut = new FileOutputStream("C:\\temp\\58260." + _testDataProvider.getStandardFileNameExtension());
|
||||||
|
|
||||||
|
// the resulting file can be compressed nicely, so we need to disable the zip bomb detection here
|
||||||
|
double before = ZipSecureFile.getMinInflateRatio();
|
||||||
|
try {
|
||||||
|
ZipSecureFile.setMinInflateRatio(0.00001);
|
||||||
|
wb.write(fileOut);
|
||||||
|
} finally {
|
||||||
|
fileOut.close();
|
||||||
|
ZipSecureFile.setMinInflateRatio(before);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
wb.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user