BACKGROUND: I am trying to read an Excel file into a Java Program. My Excel file is meant to represent a grid or raster map, so I made the height and width of each cell one inch. The idea is that I can "draw" a map or image by shading in each cell with a color. Then, I can read the Excel file to a Java program I created myself with a "Pixel" object and create a more literal image. I am an undergraduate in Computer Science, and I've only had four computer science classes at this point. I understand OOP and can program in Java. This is not for a class; this is a side project. I am using XSSF (Microsoft 2007 and after).
RESEARCH: I have discovered that the solution to this is to use Apache POI. I have already downloaded the required Apache POI jar files and configured the BuildPath in Eclipse to read them. I have discovered that using an Iterator
hasNext()
method will skip over blank cells, so the solution is to use the more direct getCell()
method. I have discovered that there are two getCell()
methods -- one with only the index as an input, and one that uses both the index input and MissingCellPolicy. However, when I tried using the MissingCellPolicy method by placing a RETURN_NULL_AND_BLANK
as the input, it made the cell blank, but made the color null in the process. The MissingCellPolicy CREATE_NULL_AS_BLANK
has the same problem.
AN INEFFICIENT SOLUTION: When I put text in a cell, it correctly reads the color. Even the iterator method can correctly read cells that have text in them. This is because once I put text in them, the cell is initialized. However, the grid I am trying to make is too large for me to put text in every cell. There is probably a way to set every cell on the sheet to have the same text, but I can't do this either because I already have many cells with specific text throughout my grid, and they can't be erased. That would also probably make all of the cells the same color, which I also can't do at this point. Besides, I would prefer it if I could have cells with no text.
TL;DR: I need to read the color of a cell in Excel into Java by using Apache POI without writing text into the cell. From my understanding, the method getCell()
with a MissingCellPolicy does not work because the Policy creates a new blank cell, overwriting the existing color. I have seen a lot of questions regarding reading blank cells in Apache POI, but I did not see one about accessing color.
MAIN CODE:
try {
FileInputStream file = new FileInputStream(new File("My FilePath"));
XSSFWorkbook workbook = new XSSFWorkbook(file);
XSSFSheet sheet = workbook.getSheetAt(0);
for(int i=0; i<5040; i++) {
Row row = sheet.getRow(i);
for(int j=0; j<10080; j++) {
Cell cell = row.getCell(j, Row.MissingCellPolicy.RETURN_NULL_AND_BLANK);
ExtendedColor color = (ExtendedColor) cell.getCellStyle().getFillForegroundColorColor();
//NOTE: getFillBackgroundColorColor did not work! It only returns the color black.
byte[] bytes = color.getRGB();
RGBColor rgb = new RGBColor(bytes);
String text = cell.getStringCellValue();
Coordinate coordinate = new Coordinate(j, i);
Tile tile = new Tile(rgb, text);
map[j][i] = tile;
// Coordinate and Tile are other objects I made myself.
// The map is a two-dimensional array of Tiles, declared previously.
// I left this code here because it works.
}
}
workbook.close();
file.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
RGBColor
Constructor Code:
public RGBColor(byte[] bytes) {
if(bytes != null) {
this.red = (int) bytes[0];
this.green = (int) bytes[1];
this.blue = (int) bytes[2];
if(red<0) {red = red+256;}
if(green<0) {green = green+256;}
if(blue<0) {blue = blue+256;}
}
RESULT:
The above code correctly reads the color of a cell if it has text in it and creates an RGBColor object from the color. The above code can also read text from a cell. However, as soon as it reaches a cell without text, it causes a NullPointerException
at the ExtendedColor line (So the cell is null). When the MissingCellPolicy CREATE_NULL_AS_BLANK is used instead, it causes a NullPointerException
at the byte[]
line (So the color is null). Any help is appreciated, even if it isn't exactly what I ask for, because I am new to Apache POI
!
A single colored cell can never be null. It must exists. So we can loop over existing cells only.
CellStyle
is not-null per definition. ButCellStyle.getFillForegroundColorColor
can return null if there is not a color. So we need to check.Supposing the following sheet:
Code:
Will print:
But in
Excel
whole columns and whole rows also may have styles. If so, not the cells will have the color but the columns and/or rows. So if the need is also to get not existing cells, such which current are not stored and so be null, and also take into account that there may be column styles (whole columns) and row styles (whole rows), then consider the following:Sheet:
All cells (all columns) have white background, row 8 has light blue background, column E has light green background. Some cells have their own cell background.
Code:
Now all possible styles should be taken into account.