19

Apache の POI for Java を使用して、Excel スプレッドシートの最後の行のインデックスを見つけようとしています。

getLastRowNum()これはorで可能だと思いましgetPhysicalNumberOfRows()たが、正しい結果が得られないようです。たとえば、1 行のスプレッドシートがあり、これら 2 つの関数は 1140 の値を返します。別の 2 行のスプレッドシートは 1162 の値を取得します。

もう 1 つの問題は、有効なデータの行の間に空の行が存在する可能性があるため、最初の空の行を探すことができないことです。

最後の行のインデックスを見つける方法はありますか? データ間に空の行がないことを要件にすることができると思いますが、より良い解決策を望んでいました。

編集:イテレータを使用したレコードは役に立ちませんでした。1140/1162 の想定される行を反復処理しただけです。

4

9 に答える 9

19

poi-3.6-20091214 を使用して、test.xls2 つの空の行とそれに続く 3 つの占有行を使用して、期待される出力を取得します。

InputStream myxls = new FileInputStream("test.xls");
Workbook book = new HSSFWorkbook(myxls);
Sheet sheet = book.getSheetAt(0);
System.out.println(sheet.getLastRowNum());

出力:4

于 2010-04-15T16:34:53.147 に答える
2

確実に知る唯一の方法は、行をテストすることです。同じ問題に使用しているソリューションは次のとおりです。

int lastRowIndex = -1;
if( sheet.getPhysicalNumberOfRows() > 0 )
{
    // getLastRowNum() actually returns an index, not a row number
    lastRowIndex = sheet.getLastRowNum();

    // now, start at end of spreadsheet and work our way backwards until we find a row having data
    for( ; lastRowIndex >= 0; lastRowIndex-- ){
        Row row = sheet.getRow( lastRowIndex );
        if( row != null ){
            break;
        }
    }
}

注: これは、空の文字列を含むセルなど、空のように見えてもそうではない行をチェックしません。そのためには、次のようなより完全なソリューションが必要です。

private int determineRowCount()
{
    this.evaluator = workbook.getCreationHelper().createFormulaEvaluator();
    this.formatter = new DataFormatter( true );

    int lastRowIndex = -1;
    if( sheet.getPhysicalNumberOfRows() > 0 )
    {
        // getLastRowNum() actually returns an index, not a row number
        lastRowIndex = sheet.getLastRowNum();

        // now, start at end of spreadsheet and work our way backwards until we find a row having data
        for( ; lastRowIndex >= 0; lastRowIndex-- )
        {
            Row row = sheet.getRow( lastRowIndex );
            if( !isRowEmpty( row ) )
            {
                break;
            }
        }
    }
    return lastRowIndex;
}

/**
 * Determine whether a row is effectively completely empty - i.e. all cells either contain an empty string or nothing.
 */
private boolean isRowEmpty( Row row )
{
    if( row == null ){
        return true;
    }

    int cellCount = row.getLastCellNum() + 1;
    for( int i = 0; i < cellCount; i++ ){
        String cellValue = getCellValue( row, i );
        if( cellValue != null && cellValue.length() > 0 ){
            return false;
        }
    }
    return true;
}

/**
 * Get the effective value of a cell, formatted according to the formatting of the cell.
 * If the cell contains a formula, it is evaluated first, then the result is formatted.
 * 
 * @param row the row
 * @param columnIndex the cell's column index
 * @return the cell's value
 */
private String getCellValue( Row row, int columnIndex )
{
    String cellValue;
    Cell cell = row.getCell( columnIndex );
    if( cell == null ){
        // no data in this cell
        cellValue = null;
    }
    else{
        if( cell.getCellType() != Cell.CELL_TYPE_FORMULA ){
            // cell has a value, so format it into a string
            cellValue = this.formatter.formatCellValue( cell );
        }
        else {
            // cell has a formula, so evaluate it
            cellValue = this.formatter.formatCellValue( cell, this.evaluator );
        }
    }
    return cellValue;
}
于 2015-05-29T21:30:44.597 に答える
1

VBAを使用して問題を解決する方法は知っていますが、ApachePOIインターフェイスから同等の情報を取得する方法がわかりません。VBAで、ワークシート「Sheet1」で使用されているセルの範囲を取得するには、次を使用します。

Worksheets("Sheet1").UsedRange

Rangeこれにより、詳細情報を提供するプロパティを持つオブジェクトが返されます。たとえば、この行の数を取得するには、次をRange使用します。

Worksheets("Sheet1").UsedRange.Rows

繰り返しになりますが、これがPOI APIを介してアクセス可能かどうかはわかりませんが、アクセスできない場合は、VBAの任意のスニペットを実行する方法を提供しますか?

于 2010-04-15T13:39:37.093 に答える
-4
int total = sheet.getPhysicalNumberOfRows() - sheet.getLastRowNum();
于 2015-06-15T16:28:58.487 に答える