2016-03-30 8 views
1

Excelファイルからデータを取得したい。私はwhileループ、イテレータとhasNext()メソッドをすべての行を使用して使用しています。 私の問題:データを含む行の後に、空の行があることがあります(セル型の文字列と値 ""またはnull)がありますが、これは反復したくありません。 だから私はこの方法isCellEmpty()追加:break文またはcontinue文を使用せずにすべての行を反復処理する方法はありますか?

public static boolean isCellEmpty(final Cell cell) { 
    if (cell == null || cell.getCellType() == Cell.CELL_TYPE_BLANK) { 
     return true; 
    } 
    if (cell.getCellType() == Cell.CELL_TYPE_STRING && cell.getStringCellValue().isEmpty()) { 
     return true; 
    } 
    return false; 
} 

をし、mainメソッドでループしながら、主演の後にこれを追加しました:

​​

しかし、今、私はbreak文を持っています。ブレークや継続を使わずに、空の行ではないすべての方法で反復処理を行うにはどうすればよいですか?今すぐ(ブレークあり)アルゴリズムが正常に動作しています - 私は必要なデータを取得しています。私はちょうどbreakまたはcontinueなしでコードを書くことが可能かどうか疑問に思っています。

+3

を続行 '意味しますか;'? – beirtipol

+1

'break'がループを終了する間、' continue'はそれがあなたが探しているものなら次の繰り返しを開始します – nyname00

+0

いいえ、駄目な私のアルゴリズムが正常に動作しています - 私は必要なデータを取得しています。私はちょうどそれが休憩なしでコードを書くことが可能かどうか、または続行することを考えています。 それを明確にするために質問を編集しました。 – kamil

答えて

4

あなたwhileループを維持し、休憩を回避したい場合は、最も簡単には私はreading the Apache POI documentation on iterating over rows and cells、あなたが取ることができる他の方法があるのをお勧めしたい、そうでなければ、おそらく、例えば

boolean inData = true; 
while (rowIterator.hasNext() && inData) { 
    row = rowIterator.next(); 
    if (row == null || isCellEmpty(row.getCell(2))) { 
     inData = false; 
    } else { 
     // Use the row 
    } 
} 

ステータスブールでありますもっとうまくいくかもしれません!

ああ、あなたは

+0

シートのデータが行1から50まで塗りつぶされているが、その間に空白の行番号30があると、行番号30の後には反復されません。 –

1

質問が正しいかどうかわからない場合は、このようなものをお探しですか?

Row row; 
while (rowIterator.hasNext() 
      && !isCellEmpty((row = rowIterator.next()).getCell(2))) { 
    // do something with row 
} 

これは、空のセルを見つけてループを終了するまで、すべての行を処理します。

+0

これはもっとelegentです – vine

+0

コレクションに 'null'行がある場合、' NullPointerException'をスローします。まあ、たぶんその私だけかもしれませんが、私の目には少し読みにくいコードになっています。 –

2

は、POIのように見えるセルを取得しようとする前に、単に非空の行を反復処理するには、no enanchementsや機能を持っていないことを確認する必要があるので、行は、nullことができることを忘れないでください。

彼らはすでにこの件について述べました。行方不明/空白のセルの代わりにwhilesまたはループを実装する

の制御で、Apache POI HSSF+XSSFセクション行とセル以上反復および細胞オーバー反復を見て私はのApache Commonsのを使用しています。 POIはイテレーターで動作するため、Apache IteratorUtilsを使用できます。

このUtilsのは、そのは非常に一般的な第3回パーティのlibの依存関係としてそれを見つけるためにするので、おそらくあなたのクラスパスにあるのApache-共通のコレクションが付属しています。

コードをきれいにして丁寧にするためです。これは、ソリューション、あなたのメインコードで次に

import org.apache.commons.collections.Predicate; 

public class ValidRowPredicate implements Predicate{ 
    @Override 
    public boolean evaluate(Object object) { 
     Row row = (Row) object; 
     Cell cell = row.getCell(2); 
     if (cell == null || cell.getCellType() == Cell.CELL_TYPE_BLANK) { 
      return false; 
     } else if (cell.getCellType() == Cell.CELL_TYPE_STRING && 
        cell.getStringCellValue().isEmpty()) { 
     return false; 
     } 
     return true; 
    } 
} 

次のようになります。

Iterator<Row> rawIterator = rowIterator; 
Iterator<Row> cleanIterator = IteratorUtils.filteredIterator(rawIterator , new ValidRowPredicate()); 

while(cleanIterator.hasNext()){ 
    Row row = cleanIterator.next(); 
    // some code 
} 

あなたは私たちが本の上に2回ループしている事をしてもよいです。いいえ、私たちはしません。最初のループは実行しますが、さらに反復は有効な行のサブセットで行われます。その利点を見てください。このようにしてポータブルの妥当性確認空のセル2を作成したので、コード内の任意の場所でいつでもそれを再現することができます。

我々はまた、我々が空白または空に心配する私を必要としないので、のみ有効な行を持って有効 Iteratorを得ました。このイテレータを他のコンポーネントやレイヤーに移動することができます。ターゲットを再度チェックアウトする必要はありません。

述語は、多くの可能性を与える。述語を継承で連鎖させるように、述語をスタンドアロンで実行すると、パラメータ化することができます。

その主な反復子全体の最初のループはコストです。しかし、それに値する結果。

IteratorUtilsとしてCollectionUtilsは本当に良いutilsのであり、私たちはしばしば私たちのクラスパスと誰もそれを使用するためにあえてへhave'm。質問はなぜでしょうか

希望すると助かります!

+0

あなたの解決策は、彼はそのような追加の機能が必要な場合。 –

0

機能を変更してくださいisCellEmpty()switchnested if-elseよりも変更してください。今

public static boolean isCellEmpty(final Cell cell) { 
    switch(cell.getCellType()){ 
     case Cell.CELL_TYPE_BLANK : 
     case cell.CELL_TYPE_STRING : 
      if(StringUtils.isBlank(cell.getCellValue()) 
       return true; 
      else 
       return false; 
     break; 
     default : 
       return false; 
    break;    
    } 

}

行はnull値が含まれている場合、このwhile (rowIterator.hasNext() && hasCellData)ループは時間の時点で停止します

boolean hasCellData= true; 
while (rowIterator.hasNext() && hasCellData) { 
    row = rowIterator.next(); //iterate through each rows. 
    if (row == null || isCellEmpty(row.getCell(2))) { 
     hasData = false; 
    } else { 
     //if row contains data then do your stuffs. 
    } 
} 

このコードを使用します。この行の外側にデータがあるかどうかは決して確認しません。

: - 仮定するあなたのシートのデータが行1から50まで充填されているが、その間に、この行番号30

後に反復しませんブランクで行番号30が存在します

ありがとうございます。

1

あなたはbreakを使用せずにループを終了するには、いくつかのオプションがあります。

  • は、例えば、いくつかの他の制御フローを使用しますreturn,throw;
  • は、ループガードに余分な条件を追加します。

    boolean shouldContinue = true; 
    while (shouldContinue && rowIterator.hasNext()) { 
        row = rowIterator.next(); 
        if (isCellEmpty(...)) { 
        shouldContinue = false; 
        } 
    } 
    
  • 排気ループ本体内部イテレータ:

    while (rowIterator.hasNext()) { 
        row = rowIterator.next(); 
        if (isCellEmpty(...)) { 
        while (rowIterator.hasNext()) rowIterator.next(); 
        } 
    } 
    

それともbreakを使用します。そう悪くはない。

0

あまりにも単純すぎるかもしれませんが、十分ではないでしょうか?

while (rowIterator.hasNext()) { 
    row = rowIterator.next(); 
    if (!isCellEmpty(row.getCell(2))) { 
     // some code ... 
    } 
} 

空の行/セルは、以下のアプローチを取ることができる遭遇したら、私たちは反復を停止したい場合:

for(boolean shouldContinue = true; shouldContinue && rowIterator.hasNext();) { 
    if (!isCellEmpty(row.getCell(2))) { 
     // some code ... 
    } else { 
     shouldContinue = false; 
    } 
} 
+0

OPは「中断」ではなく「続行」ではありません:) –

+0

あなたのフィードバックを完全には得ていません。チケット内では、次のことが記述されています。_ブレークまたは継続を使用せずに、空の行ではないすべての行でどのように反復処理できますか?さて、私のアルゴリズムは正常に動作しています。だから、私は考えて、休憩ステートメントを削除することができます:) – uniknow

+0

このソリューションは*ループ*を破ることはありません*むしろそれを繰り返します*後にも空のセルが見つかった場合は、機能的には両方とも同等ではありません。 –

関連する問題