I am trying to write a huge excel file, my requirement allows me to write the row and forget, so i am using SXSSF which allows to keep only a few number of rows in memory and rest all are written to the document. this helps in overcoming outofmemory exception for large files.
我正在尝试写一个巨大的excel文件,我的要求允许我写行并忘记,所以我使用SXSSF,它允许在内存中保留少量行,其余全部写入文档。这有助于克服大文件的outofmemory异常。
but I also need to set styles to cells using sxssf workbook. i am not able to find a way to define and use custom colors in SXSSF (like in XSSF, we can define a custom color directly, and in HSSF we can replace an entry in the palette with a custom color)
但我还需要使用sxssf工作簿将样式设置为单元格。我无法找到在SXSSF中定义和使用自定义颜色的方法(比如在XSSF中,我们可以直接定义自定义颜色,在HSSF中我们可以用自定义颜色替换调色板中的条目)
i can find no way to access a palette from SXSSF workbook.
我找不到从SXSSF工作簿访问调色板的方法。
I can not create a new HSSF palette as the constructor is protected.
我无法创建新的HSSF调色板,因为构造函数受到保护。
the only way that seems feasible right now is to somehow find a similar color from a list of all predefined colors and use it, instead of the original (but that would require having a rgb color matching algo, which would be another task)
现在看来可行的唯一方法是以某种方式从所有预定义颜色的列表中找到相似的颜色并使用它而不是原始颜色(但这需要具有rgb颜色匹配算法,这将是另一项任务)
Can someone suggest a workaround (or maybe suggest a primitive rgb color matching algorithm)
有人可以建议一个解决方法(或者可能建议一个原始的rgb颜色匹配算法)
2 个解决方案
#1
11
So, after a bit of searching through the web and reading the docs, i got a hint that SXSSF is actually a wrapper around XSSF, so i typecasted the CellStyle returned by SXSSF workbook to XSSF and was able to use XSSFColor directly for generating colors.
因此,在通过网络搜索并阅读文档之后,我得到了一个提示,即SXSSF实际上是XSSF的包装器,因此我将SXSSF工作簿返回的CellStyle转换为XSSF,并且能够直接使用XSSFColor生成颜色。
SXSSFWorkbook workbook = new SXSSFWorkbook(50);
Sheet sheet = workbook.createSheet("Image Data");
....
Cell cell = row.createCell(j);
cell.setCellValue(j);
XSSFCellStyle cs1 = (XSSFCellStyle) workbook.createCellStyle();
cs1.setFillForegroundColor(new XSSFColor(new java.awt.Color(red,green,blue)));
cs1.setFillPattern(CellStyle.SOLID_FOREGROUND);
cell.setCellStyle(cs1);
#2
4
To avoid the need of typecast for the cellStyles, create first a XSSFWorkbook with cellStyles (XSSFCellStyle) applying the custom colors and then wrap it with a SXSSFWorkbook constructor like the sample below:
为了避免对cellStyles进行类型转换的需要,首先使用cellStyles(XSSFCellStyle)创建应用自定义颜色的XSSFWorkbook,然后使用SXSSFWorkbook构造函数将其包装,如下例所示:
/**
* Sample based on POI <a href="http://poi.apache.org/spreadsheet/how-to.html#sxssf">Spreadsheet How-To</a>.
*
* @see <a href="https://poi.apache.org/apidocs/org/apache/poi/xssf/streaming/SXSSFWorkbook.html">SXSSFWorkbook</a>
*/
public static void main(String[] args) throws Throwable {
XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
XSSFColor colorGrey = new XSSFColor(new Color(210, 210, 210));
XSSFCellStyle cellStyleGrey = xssfWorkbook.createCellStyle();
cellStyleGrey.setFillPattern(CellStyle.SOLID_FOREGROUND);
cellStyleGrey.setFillForegroundColor(colorGrey);
// keep 100 rows in memory, exceeding rows will be flushed to disk
SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(xssfWorkbook, 100);
Sheet sheet = sxssfWorkbook.createSheet();
for (int rownum = 0; rownum < 1000; rownum++) {
Row row = sheet.createRow(rownum);
for (int cellnum = 0; cellnum < 10; cellnum++) {
Cell cell = row.createCell(cellnum);
String address = new CellReference(cell).formatAsString();
cell.setCellValue(address);
// for even rows apply the grey cellStyle
if (rownum % 2 == 0) {
cell.setCellStyle(cellStyleGrey);
}
}
}
// Omitted asserts block from original sample...
FileOutputStream out = new FileOutputStream("/temp/sxssf.xlsx");
sxssfWorkbook.write(out);
out.close();
// dispose of temporary files backing this workbook on disk
sxssfWorkbook.dispose();
}
#1
11
So, after a bit of searching through the web and reading the docs, i got a hint that SXSSF is actually a wrapper around XSSF, so i typecasted the CellStyle returned by SXSSF workbook to XSSF and was able to use XSSFColor directly for generating colors.
因此,在通过网络搜索并阅读文档之后,我得到了一个提示,即SXSSF实际上是XSSF的包装器,因此我将SXSSF工作簿返回的CellStyle转换为XSSF,并且能够直接使用XSSFColor生成颜色。
SXSSFWorkbook workbook = new SXSSFWorkbook(50);
Sheet sheet = workbook.createSheet("Image Data");
....
Cell cell = row.createCell(j);
cell.setCellValue(j);
XSSFCellStyle cs1 = (XSSFCellStyle) workbook.createCellStyle();
cs1.setFillForegroundColor(new XSSFColor(new java.awt.Color(red,green,blue)));
cs1.setFillPattern(CellStyle.SOLID_FOREGROUND);
cell.setCellStyle(cs1);
#2
4
To avoid the need of typecast for the cellStyles, create first a XSSFWorkbook with cellStyles (XSSFCellStyle) applying the custom colors and then wrap it with a SXSSFWorkbook constructor like the sample below:
为了避免对cellStyles进行类型转换的需要,首先使用cellStyles(XSSFCellStyle)创建应用自定义颜色的XSSFWorkbook,然后使用SXSSFWorkbook构造函数将其包装,如下例所示:
/**
* Sample based on POI <a href="http://poi.apache.org/spreadsheet/how-to.html#sxssf">Spreadsheet How-To</a>.
*
* @see <a href="https://poi.apache.org/apidocs/org/apache/poi/xssf/streaming/SXSSFWorkbook.html">SXSSFWorkbook</a>
*/
public static void main(String[] args) throws Throwable {
XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
XSSFColor colorGrey = new XSSFColor(new Color(210, 210, 210));
XSSFCellStyle cellStyleGrey = xssfWorkbook.createCellStyle();
cellStyleGrey.setFillPattern(CellStyle.SOLID_FOREGROUND);
cellStyleGrey.setFillForegroundColor(colorGrey);
// keep 100 rows in memory, exceeding rows will be flushed to disk
SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(xssfWorkbook, 100);
Sheet sheet = sxssfWorkbook.createSheet();
for (int rownum = 0; rownum < 1000; rownum++) {
Row row = sheet.createRow(rownum);
for (int cellnum = 0; cellnum < 10; cellnum++) {
Cell cell = row.createCell(cellnum);
String address = new CellReference(cell).formatAsString();
cell.setCellValue(address);
// for even rows apply the grey cellStyle
if (rownum % 2 == 0) {
cell.setCellStyle(cellStyleGrey);
}
}
}
// Omitted asserts block from original sample...
FileOutputStream out = new FileOutputStream("/temp/sxssf.xlsx");
sxssfWorkbook.write(out);
out.close();
// dispose of temporary files backing this workbook on disk
sxssfWorkbook.dispose();
}