Java and org.apache.poi while reading excel line 47 被跳过

Java and org.apache.poi while reading excel line 47 is skipped

使用 Java 1.8、org.apache.poi 5.1.0 和 org.apache.poi.ooxml 5.1.0。 我有一个包含 54 行的 excel 文件。我以 5 行为单位阅读了这个文件。如果我到达第 47 行,它会跳过该行并给我新块的第一行,同时它应该给我现在块上方的第一个空行。

使用调试器我可以看到它从第 46 行转到第 48 行,而我期望是第 47 行。 在第51行添加断点(位置见java代码中的注释)。您可以看到 currentRow 属性 'r' 如何从第 46 行跳到第 48 行。

我不知道为什么会这样,但它毁了我的一天,使我的程序变得无用。

您可以在下面找到我的文件。我将它降低到最低限度,同时仍然使错误可重现。

我的build.gradle文件

plugins {
    id 'java'
    id 'application'
}

group 'nl.karnhuis'

sourceCompatibility = 1.8

application {
    mainClass = 'nl.karnhuis.test.Testfile'
}

repositories {
    mavenCentral()
    maven {
        url "https://mvnrepository.com/artifact"
    }
}

dependencies {
    implementation 'org.apache.poi:poi:5.1.0'
    implementation 'org.apache.poi:poi-ooxml:5.1.0'
}

我的gradle.settings文件

rootProject.name = 'testfile'

我的java代码

package nl.karnhuis.test;

import java.io.*;
import java.util.*;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;

public class Testfile {

    public void run() {
        File inputFile = new File("schema.xlsx");
        handleFile(inputFile);
    }

    private void handleFile(File inputFile) {
        try {
            // Create Workbook instance holding reference to .xlsx file
            XSSFWorkbook workbook = new XSSFWorkbook(inputFile);

            // Get first/desired sheet from the workbook
            Sheet datatypeSheet = workbook.getSheetAt(0);
            Iterator<Row> iterator = datatypeSheet.iterator();
            Row currentRow = null;

            // Go over all rows
            while (iterator.hasNext()) {

                if (checkForLastLine(currentRow)) {
                    break;
                }

                currentRow = iterator.next();
                // First two rows can be skipped.
                if ((currentRow.getRowNum()) < 2) {
                    continue;
                }

                currentRow = iterator.next();
                // do something important

                currentRow = iterator.next();
                // do something important

                currentRow = iterator.next();
                // do something important

                // The next row is empty, so it can be skipped.
                currentRow = iterator.next();
                System.out.println(currentRow.getRowNum()); //Add breakpoint here 
            }

        } catch (IOException | InvalidFormatException e) {
            e.printStackTrace();
        }
    }

    private boolean checkForLastLine(Row currentRow) {
        if (currentRow == null) {
            return false;
        } else {
            for (Cell currentCell : currentRow) {
                // Reached end of file? Get out of da loop!
                return currentCell.getColumnIndex() == 0
                        && (currentCell.getStringCellValue().trim().startsWith("primaire")
                        || currentCell.getStringCellValue().trim().startsWith("secondaire"));
            }
        }
        return false;
    }

    public static void main(String[] args) {
        Testfile mc = new Testfile();
        mc.run();
    }
}

excel 文件可以从 https://www.karnhuis.nl/schema.xlsx

下载

Excel 中的空行似乎不是以相同的方式创建的。尝试在第 47 行的第一个单元格中写入内容,然后再次 运行。该行将在您的 class 中正确列出。即使在删除内容并再次出现空行后,它仍然有效。

Apache POI 具有逻辑行(具有或以前具有内容)的概念,不会 return 始终为空的行。如果您无法控制 Excel 文件的生成方式,请不要使用计数行。例如,您可以在第一列中查找文本,然后计算 4 行。