使用ApachePOI从Excel中的空白单元格读取颜色到Java
背景:我正在尝试将Excel文件读入Java程序。 我的Excel文件是用来表示网格或光栅地图的,所以我将每个单元格的高度和宽度设置为1英寸。我的想法是,我可以通过在每个单元格中使用颜色着色来“绘制”地图或图像。然后,我可以将Excel文件读取到我自己用“像素”对象创建的Java程序中,并创建一个更文字化的图像。 我是计算机科学的本科生,目前我只上过四节计算机科学课。我懂OOP,能用Java编程。这不是一门课;这是一个附带项目。我正在使用XSSF(Microsoft 2007及以后版本) 研究:我发现解决这个问题的方法是使用ApachePOI。我已经下载了所需的apachepoijar文件,并在Eclipse中配置了BuildPath来读取它们。我发现使用使用ApachePOI从Excel中的空白单元格读取颜色到Java,java,excel,eclipse,apache-poi,xssf,Java,Excel,Eclipse,Apache Poi,Xssf,背景:我正在尝试将Excel文件读入Java程序。 我的Excel文件是用来表示网格或光栅地图的,所以我将每个单元格的高度和宽度设置为1英寸。我的想法是,我可以通过在每个单元格中使用颜色着色来“绘制”地图或图像。然后,我可以将Excel文件读取到我自己用“像素”对象创建的Java程序中,并创建一个更文字化的图像。 我是计算机科学的本科生,目前我只上过四节计算机科学课。我懂OOP,能用Java编程。这不是一门课;这是一个附带项目。我正在使用XSSF(Microsoft 2007及以后版本) 研究:
迭代器hasNext()
方法会跳过空白单元格,因此解决方案是使用更直接的getCell()
方法。我发现有两个getCell()
方法——一个只使用索引作为输入,另一个同时使用索引输入和MissingCellPolicy。但是,当我尝试使用MissingCellPolicy方法时,将一个RETURN\u NULL\u和\u BLANK
作为输入,它使单元格变为空白,但在这个过程中颜色变为空。MissingCellPolicyCREATE\u NULL\u AS\u BLANK
也有同样的问题
低效的解决方案:当我将文本放入单元格时,它会正确读取颜色。即使迭代器方法也可以正确读取包含文本的单元格。这是因为一旦我将文本放入其中,单元格就会初始化。但是,我尝试创建的网格太大,无法在每个单元格中放置文本。可能有一种方法可以将工作表上的每个单元格设置为具有相同的文本,但我也不能这样做,因为在整个网格中已经有许多单元格具有特定的文本,并且它们无法擦除。这也可能使所有的细胞颜色相同,这一点我也不能做到。此外,如果我可以有没有文本的单元格,我会更喜欢它
TL;DR:我需要使用ApachePOI将Excel中单元格的颜色读入Java,而无需将文本写入单元格。根据我的理解,带有MissingCellPolicy的方法getCell()
不起作用,因为该策略创建了一个新的空白单元格,覆盖了现有的颜色。我看到了很多关于在ApachePOI中读取空白单元格的问题,但我没有看到关于访问颜色的问题
主代码:
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对象。上述代码还可以从单元格中读取文本。但是,一旦到达没有文本的单元格,就会在ExtendedColor行(因此该单元格为空)处产生NullPointerException
。当使用MissingCellPolicy CREATE_NULL_AS_BLANK时,它会在byte[]
行导致NullPointerException
(因此颜色为NULL)。非常感谢您的任何帮助,即使这不是我所要求的,因为我对apachepoi
还不熟悉 最终发生的情况是,您试图处理空单元格或空白单元格,而在遇到它们时却不处理它们。调用getCell()后,您要执行的操作如下:
单个彩色单元格永远不能为空。它必须存在。因此,我们只能在现有单元上循环<代码>单元格样式
根据定义不为空。但是如果没有颜色,则CellStyle.getFillForegroundColorColor
可以返回null。所以我们需要检查一下
假设下表:
代码:
将打印:
Cell A1 of type 1 has color none
Cell B1 of type 0 has color [-1, -1, 0]
Cell C1 of type 2 has color none
Cell B3 of type 0 has color none
Cell C3 of type 3 has color [-110, -48, 80]
Cell D4 of type 1 has color none
Cell B6 of type 3 has color [0, 112, -64]
Cell D7 of type 3 has color [-1, 0, 0]
Cell A9 of type 3 has color [-1, -64, 0]
Cell F12 of type 3 has color [0, -80, 80]
但是在
Excel
中,整列和整行也可能有样式。如果是,则不是单元格将具有颜色,而是列和/或行。因此,如果需要也不获得现有的单元,如当前的电流不存储,因此为空,并且还考虑到可能有列样式(整列)和行样式(整行),那么考虑以下内容:
工作表:
所有单元格(所有列)具有白色背景,第8行具有浅蓝色背景,第E列具有浅绿色背景。有些细胞有自己的细胞背景
代码:
import org.apache.poi.ss.usermodel.*;
导入java.io.*;
导入java.util.array;
类ReadColorsFromExcel{
公共静态void main(字符串[]args)引发异常{
InputStream inp=新文件InputStream(“MyFile.xlsx”);
工作簿=WorkbookFactory.create(inp);
工作表=工作簿。getSheetAt(0);
int lastRow=12;
int-lastCol=6;
对于(int-rowNum=0;rowNumif (cell == null || cell.getCellType() == Cell.CELL_TYPE_BLANK) {
// assign whatever color you want for a blank cell to rgb
} else {
// do your logic to get the ExtendedColor and turn it into an RGBColor
}
import org.apache.poi.ss.usermodel.*;
import java.io.*;
import java.util.Arrays;
class ReadColorsFromExcel {
public static void main(String[] args) throws Exception{
InputStream inp = new FileInputStream("MyFile.xlsx");
Workbook workbook = WorkbookFactory.create(inp);
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) { // cell will always be not-null only existing cells are in loop
CellStyle cellStyle = cell.getCellStyle(); // cellStyle is always not-null
ExtendedColor extendedColor = (ExtendedColor)cellStyle.getFillForegroundColorColor(); // extendedColor may be null
String color = "none";
if (extendedColor != null) {
byte[] bytes = extendedColor.getRGB();
color = Arrays.toString(bytes);
}
System.out.println("Cell " + cell.getAddress() + " of type " + cell.getCellType() + " has color " + color);
}
}
}
}
Cell A1 of type 1 has color none
Cell B1 of type 0 has color [-1, -1, 0]
Cell C1 of type 2 has color none
Cell B3 of type 0 has color none
Cell C3 of type 3 has color [-110, -48, 80]
Cell D4 of type 1 has color none
Cell B6 of type 3 has color [0, 112, -64]
Cell D7 of type 3 has color [-1, 0, 0]
Cell A9 of type 3 has color [-1, -64, 0]
Cell F12 of type 3 has color [0, -80, 80]
import org.apache.poi.ss.usermodel.*;
import java.io.*;
import java.util.Arrays;
class ReadColorsFromExcel {
public static void main(String[] args) throws Exception{
InputStream inp = new FileInputStream("MyFile.xlsx");
Workbook workbook = WorkbookFactory.create(inp);
Sheet sheet = workbook.getSheetAt(0);
int lastRow = 12;
int lastCol = 6;
for (int rowNum = 0; rowNum < lastRow; rowNum++) {
Row row = sheet.getRow(rowNum);
if (row == null) {
row = sheet.createRow(rowNum);
}
CellStyle rowStyle = row.getRowStyle(); // if the whole row has a style
for (int colNum = 0; colNum < lastCol; colNum++) {
CellStyle colStyle = sheet.getColumnStyle(colNum); // if the whole column has a style
Cell cell = row.getCell(colNum, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
CellStyle cellStyle = cell.getCellStyle(); // cellStyle is always not-null
String color = "none";
ExtendedColor extendedColor = (ExtendedColor)cellStyle.getFillForegroundColorColor(); // first we try cellStyle
if (extendedColor == null && rowStyle != null) extendedColor = (ExtendedColor)rowStyle.getFillForegroundColorColor(); // now we try rowStyle
if (extendedColor == null && colStyle != null) extendedColor = (ExtendedColor)colStyle.getFillForegroundColorColor(); // at last we try colStyle
if (extendedColor != null) {
byte[] bytes = extendedColor.getRGB();
color = Arrays.toString(bytes);
}
System.out.println("Cell " + cell.getAddress() + " of type " + cell.getCellType() + " has color " + color);
}
}
}
}