programing

Excel 스프레드시트에서 마지막 행 찾기

yellowcard 2023. 6. 29. 19:57
반응형

Excel 스프레드시트에서 마지막 행 찾기

Apache for Java의 POI를 사용하여 Excel 스프레드시트에서 마지막 행의 인덱스를 찾으려고 합니다.

저는 이것이 가능해야 한다고 생각했습니다.getLastRowNum()또는getPhysicalNumberOfRows()하지만 그들은 올바른 결과를 제공하지 않는 것 같습니다.예를 들어 한 줄짜리 스프레드시트가 있는데 이 두 함수는 1140의 값을 반환합니다.또 다른 두 줄 스프레드시트의 값은 1162입니다.

또 다른 문제는 유효한 데이터 행 사이에 빈 행이 있을 수 있기 때문에 첫 번째 빈 행만 찾을 수 없다는 것입니다.

그럼 마지막 행의 인덱스를 찾을 수 있는 방법이 있나요?데이터 사이에 빈 행이 없어야 한다는 요구사항을 만들 수 있을 것 같습니다. 하지만 더 나은 해결책을 찾고 있었습니다.

편집: 기록을 위해 반복기를 사용하는 것은 도움이 되지 않았습니다.1140/1162 행으로 추정되는 행을 반복했습니다.

poi-3.와 poi-3.6-20091214를 사용하여 .test.xls의 빈 행 에 세 행이 : 두 개 의 빈 에 개 점 된 유 행 이 음 있 의 세 음 다 행 음 : 있 ▁having 행 이 : 두 ▁rows ▁rows ▁two

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

출력:4

다음 방법을 사용하여 원래 행 수를 가져올 수 있습니다.

HSSFSheet worksheet = workbook.getSheet("Role_Mapping");
int rowsNum = worksheet.getPhysicalNumberOfRows();

저도 예전에 같은 문제가 있었습니다.Excel 셀이 편집된 후 Excel에서 비워져서 발생할 수 있습니다.일단 만지면, 그들은 중고 세포로 나타납니다.

이 방법을 사용하여 셀을 삭제하고(비우기만 하는 것이 아니라) 올바른 반환 행 값을 얻습니다.

  1. Excel 파일을 열고 예상 시트로 이동합니다.
  2. 마지막 행 + 1을 선택합니다. 예를 들어 데이터가 있는 12개 행을 선택한 다음 13행을 클릭합니다.
  3. 전체 행 [Shift]-[스페이스] 선택
  4. 시트 하단의 모든 행 선택 [Ctrl]-[Shift]-[화살표 아래]
  5. 선택한 모든 행 삭제 [Ctrl]-[마이너스]
  6. 워크북 저장
  7. 코드를 다시 실행하고 반환된 값을 확인합니다.

POI 라이브러리의 문제가 아닙니다.

확실하게 알 수 있는 유일한 방법은 행을 테스트하는 것입니다.다음은 동일한 문제에 대해 사용하는 솔루션입니다.

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

VBA를 사용하여 문제를 해결하는 방법은 알고 있지만 Apache POI 인터페이스에서 동일한 정보를 얻는 방법은 잘 모르겠습니다.VBA에서 워크시트 "Sheet1"의 사용된 셀 범위를 가져오려면 다음을 사용합니다.

Worksheets("Sheet1").UsedRange

이는 다음을 반환합니다.Range추가 정보를 제공하는 속성을 가진 개체입니다.예를 들어, 이 항목의 행 수를 가져오는 방법Range사용:

Worksheets("Sheet1").UsedRange.Rows

다시 말씀드리지만 POI API를 통해 이것에 액세스할 수 있는지는 확실하지 않지만, 그렇지 않다면 VBA의 임의 스니펫을 실행하는 방법을 제공하는 것이 아닐까요?

다음 코드를 사용하여 이 작업을 수행할 수 있습니다.

SVTableModel model = new SVTableModel(sheet);
lastRowNum = model.getRowCount();

그러나 Apache POI 3.7에서 이 작업을 수행하려고 하지만 찾을 수 없습니다.SVTableModelAPI에서.이것은 3.2 이후로 제거된 것 같습니다.

저는 HSSF 워크북에서는 작동하지만 XSSF 워크북에서는 작동하지 않기 때문에 어떤 경우에도 작동하지 않았습니다.마침내 해결 방법의 도움으로 이 문제를 해결할 수 있습니다.내용이 끝난 후 시트 끝에 두 개의 열 또는 행을 병합합니다.그럼 코드 아래에 써주세요. sheet.getMergedRegion(0).getLastRow()여기서 0은 내가 병합한 하나의 경우이지만 셀 또는 행을 이미 병합한 경우에는 그에 따라 값을 증가시킵니다.이것이 도움이 되기를 바랍니다.

반복기를 사용하면 null 및 사용되지 않은 행이 반환되지 않습니다.

           Iterator<Row> itr = sheet.iterator();    //iterating over excel file  
            

            while (itr.hasNext())                 
            {  
                Row row = itr.next();
                //your code here 
            }

언급URL : https://stackoverflow.com/questions/2645566/finding-the-last-row-in-an-excel-spreadsheet

반응형