2017-01-02 51 views
0

背景:ExcelファイルをJavaプログラムに読み込もうとしています。 私のExcelファイルはグリッドまたはラスターマップを表すため、各セルの高さと幅を1インチにしました。アイデアは、色で各セルをシェーディングしてマップや画像を「描く」ことができるということです。次に、Excelファイルを「Pixel」オブジェクトで自分自身を作成し​​、よりリテラルなイメージを作成するJavaプログラムに読み込むことができます。 私はコンピュータサイエンスの学士号を取得しています。私はOOPを理解し、Javaでプログラムすることができます。これはクラスのためではありません。これはサイドプロジェクトです。私はXSSF(Microsoft 2007以降)を使用しています。Excelの空白セルからApache POIを使用してJavaへの色を読み取る

RESEARCH:これに対する解決策は、Apache POIを使用することです。私はすでに必要なApache POI jarファイルをダウンロードし、EclipseでBuildPathを設定して読み込みました。私は、IteratorhasNext()メソッドを使用すると空白のセルをスキップするので、解決方法はより直接的な方法を使用することです。getCell()私は、2つの方法があることを発見しました.1つはインデックスだけを入力とし、もう1つはインデックス入力とMissingCellPolicyの両方を使用します。しかし、入力としてRETURN_NULL_AND_BLANKを配置してMissingCellPolicyメソッドを使用しようとすると、セルが空白になりましたが、プロセスでカラーがnullになりました。 MissingCellPolicy CREATE_NULL_AS_BLANKにも同じ問題があります。

不確かな解決:テキストをセルに配置すると、正しく色が読み取られます。イテレータメソッドでも、テキストを含むセルを正しく読み取ることができます。これは、テキストを挿入すると、セルが初期化されるためです。しかし、私がしようとしているグリッドは、すべてのセルにテキストを入れるには大きすぎます。おそらく、シート上のすべてのセルに同じテキストを設定する方法がありますが、グリッド全体に特定のテキストを持つセルが多数存在するため、これを行うことはできません。また、消去できません。それはおそらく、すべての細胞を同じ色にするでしょう。私はこの時点ではできません。さらに、私はテキストがない細胞を持つことができればそれを好むだろう。

TL; DR :Excelのセルの色をApache POIを使用してセルに書き込まずにJavaに読み込む必要があります。私の理解では、メソッドはgetCell() MissingCellPolicyで動作しません、ポリシーは、既存の色を上書きする新しい空のセルを作成するため動作しません。私は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が代わりに使用されると、NullPointerExceptionbyte[]行に表示されます(色はヌルです)。私がApache POIに新しくなったので、私が求めているものではなくても、どんな助けにも感謝しています!

答えて

0

単一色のセルがnullになることはありません。存在しなければならない。既存の細胞だけをループすることができます。 CellStyleは定義ごとにNULLではありません。しかし、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にします列全体と行全体にもスタイルがあります。そうであれば、セルには色はなく列や行があります。したがって、現在の列が格納されていないnullなどの既存のセルを取得する必要もなく、列のスタイル(列全体)と行のスタイル(行全体)が存在する可能性も考慮して、次の点を考慮してください:シート

:すべての細胞(すべての列)は白背景を有する

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

すばらしいコメントをありがとうございますが、これは私の状況では機能しません。私はすべてのnullセルが同じ色になることを望んでいないし、場所に基づいて色を割り当てる方法もありません。ヌルセルにはすでにExcelファイル内に色があります。私はその色を抽出したい - それは既に存在する。 – Luke1195

+0

あなたは正しいです。私はあなたの質問を誤解しました。 –

関連する問題