首页 > 解决方案 > 跳过读取 excel 第 47 行时的 Java 和 org.apache.poi

问题描述

使用 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();
    }
}

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

标签: javaexcelapache-poi

解决方案


似乎 Excel 中的空行不是以相同的方式创建的。尝试在第 47 行的第一个单元格中写一些东西并再次运行。该行将在您的班级中正确列出。即使在删除内容并再次有一个空行之后,它也会起作用。

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


推荐阅读