2017-01-02 242 views
0

背景:我試圖將Excel文件讀入Java程序。 我的Excel文件是爲了表示網格或柵格地圖,所以我將每個單元格的高度和寬度設置爲一英寸。這個想法是,我可以通過在每個單元格中用一種顏色着色來「繪製」地圖或圖像。然後,我可以將Excel文件讀取到我用「Pixel」對象創建自己的Java程序,並創建更多文字圖像。 我是計算機科學的本科學生,在這一點上我只有四門計算機科學課。我理解OOP並可以用Java編程。這不是一個班級;這是一個側面項目。我正在使用XSSF(Microsoft 2007及之後)。使用Apache POI從Excel中的空白單元讀取顏色使用Apache POI

RESEARCH:我發現解決方案是使用Apache POI。我已經下載了所需的Apache POI jar文件,並在Eclipse中配置了BuildPath以讀取它們。我發現使用IteratorhasNext()方法將會跳過空白單元格,所以解決方法是使用更直接的方法getCell()。我發現有兩個getCell()方法 - 一個只使用索引作爲輸入,另一個使用索引輸入和MissingCellPolicy。但是,當我通過將RETURN_NULL_AND_BLANK作爲輸入嘗試使用MissingCellPolicy方法時,它將該單元格留空,但在該過程中使顏色爲空。 MissingCellPolicy CREATE_NULL_AS_BLANK也有同樣的問題。

無效解決方案:當我將文本放入單元格中時,它正確讀取顏色。即使是迭代器方法也可以正確讀取包含文本的單元格。這是因爲一旦我把文本放進去,單元格就會被初始化。但是,我想要製作的網格太大,無法將文本放入每個單元格中。可能有一種方法可以設置表單上的每個單元格具有相同的文本,但我無法執行此操作,因爲我的整個網格中已經有許多具有特定文本的單元格,並且它們不能被擦除。這也可能使所有的單元格顏色相同,在這一點上我也做不到。此外,如果我可以擁有沒有文字的單元格,我更喜歡它。

TL; DR:我需要使用Apache POI將單元格的顏色讀取到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(因此單元格爲空)。當使用MissingCellPolicy CREATE_NULL_AS_BLANK替代時,它會在byte[]行上生成NullPointerException(因此顏色爲空)。任何幫助表示讚賞,即使它不是我所要求的,因爲我是Apache POI的新手!

回答

0

一個有色細胞能不能爲空。它必須存在。所以我們只能循環現有的單元格。每個定義的CellStyle不爲空。但如果沒有顏色,則CellStyle.getFillForegroundColorColor可以返回null。所以我們需要檢查。

假設如下表:

enter image description here

代碼:

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整列和整行也可以有樣式。如果是這樣,不是單元格將具有顏色,而是列和/或行。因此,如果需要也不存在單元格,例如哪些當前未存儲並因此爲空,並且還考慮到可能存在列樣式(整列)和行樣式(整行),則考慮以下:

表:

enter image description here

所有細胞(所有列)有白色背景,第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); 
    } 
    } 
} 
} 

現在所有可能的風格應該考慮到。

0

最終發生了什麼是你正試圖處理空白或空白單元格,並且在遇到它們時不處理它們。你想要做的是這樣的調用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 
} 
+0

感謝您的快速評論,但這不適用於我的情況。我不希望每個空單元都是相同的顏色,也沒有辦法根據位置分配顏色。空單元格在excel文件中已經有一個顏色。我想提取這種顏色 - 它已經存在。 – Luke1195

+0

你說得對。我誤解了你的問題。 –