簡體   English   中英

使用Apache POI從Excel中的空白單元格讀取顏色到Java

[英]Read a Color from a Blank Cell in Excel to Java using Apache POI

背景 :我正在嘗試將Excel文件讀入Java程序。 我的Excel文件用於表示網格或柵格地圖,因此我將每個像元的高度和寬度都設置為1英寸。 我的想法是,我可以通過在每個單元格中加陰影來“繪制”地圖或圖像。 然后,我可以將Excel文件讀取到使用“ Pixel”對象創建的Java程序中,並創建一個更直觀的圖像。 我是計算機科學專業的本科生,目前我只有四門計算機科學課程。 我了解OOP,並且可以使用Java編程。 這不是上課; 這是一個附帶項目。 我正在使用XSSF(Microsoft 2007及更高版本)。

研究 :我發現解決此問題的方法是使用Apache POI。 我已經下載了必需的Apache POI jar文件,並在Eclipse中配置了BuildPath來讀取它們。 我發現使用Iterator hasNext()方法將跳過空白單元格,因此解決方案是使用更直接的getCell()方法。 我發現有兩種getCell()方法-一種僅將索引作為輸入,另一種同時使用索引輸入和MissingCellPolicy。 但是,當我嘗試通過將RETURN_NULL_AND_BLANK用作輸入來使用MissingCellPolicy方法時,它使單元格為空白,但在此過程中使顏色為空。 MissingCellPolicy CREATE_NULL_AS_BLANK具有相同的問題。

一種無效的解決方案 :當我將文本放在單元格中時,它會正確讀取顏色。 即使是迭代器方法也可以正確讀取其中包含文本的單元格。 這是因為一旦將文本放入其中,單元格就會被初始化。 但是,我嘗試制作的網格太大,無法在每個單元格中放置文本。 可能有一種方法可以將工作表上的每個單元格設置為具有相同的文本,但是我也不能這樣做,因為我在網格中已經有很多具有特定文本的單元格,並且無法刪除它們。 這也可能會使所有單元格具有相同的顏色,這也是我目前無法做到的。 此外,如果我可以有沒有文本的單元格,我會更喜歡。

TL; DR :我需要通過使用Apache POI將Excel中的單元格顏色讀取到Java中,而無需將文本寫入單元格中。 據我了解,帶有MissingCellPolicy的方法getCell()不起作用,因為該策略創建了一個新的空白單元格,覆蓋了現有顏色。 我已經看到了很多有關讀取Apache POI中的空白單元格的問題,但是我沒有看到有關訪問顏色的問題。

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構造函數代碼:

    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:上面的代碼正確讀取單元格的顏色(如果其中包含文本),並從該顏色創建RGBColor對象。 上面的代碼還可以從單元格中讀取文本。 但是,一旦到達沒有文本的單元格,它就會在ExtendedColor行引起NullPointerException (因此該單元格為null)。 當改用MissingCellPolicy CREATE_NULL_AS_BLANK時,它將在byte[]行處引起NullPointerException (因此顏色為null)。 感謝任何幫助,即使它不是我真正想要的,因為我對Apache POI

最終發生的事情是您嘗試處理空單元格或空白單元格,並且在遇到它們時不進行處理。 調用getCell()之后,您要做的是這樣的事情:

if (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
}

單個彩色單元永遠不能為空。 它必須存在。 因此,我們只能遍歷現有單元。 每個定義的CellStyle都不為空。 但是,如果沒有顏色, CellStyle.getFillForegroundColorColor可以返回null。 所以我們需要檢查。

假設以下工作表:

在此處輸入圖片說明

碼:

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]

但是在Excel整個列和整個行也可能具有樣式。 如果是這樣,則單元格不是顏色,而是列和/或行。 因此,如果還需要獲取不存在的單元格(這樣的單元格將不存儲因此為空),並且還考慮到可能存在列樣式(整個列)和行樣式(整個行),請考慮以下內容:

片:

在此處輸入圖片說明

所有單元格(所有列)具有白色背景,第8行具有淺藍色背景,列E具有淺綠色背景。 一些細胞具有自己的細胞背景。

碼:

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);
   }
  }
 }
}

現在應該考慮所有可能的樣式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM