Apache POI 在读取单元格数据以进行 CSV 转换时出现 Java 空指针异常

标签 java excel apache apache-poi xls

我正在尝试为此应用程序做两件事:一是调用该类时,它将从上到下运行,二是我可以调用公共(public)方法“xlxTOcsvConverter”并提供将来所需的三个参数use...也就是说,如果运行该类,将输入4个文件,并写入4个文件。前三个工作得很好,但最后一个,即带有注释的那个,似乎因给定的错误而失败。现在我遇到的问题是,其中的数据是由外部公司维护的,我们只有读取权限,所以我所能做的就是要求他们维护一组单元格格式,但这可能不会坚持下去。我注意到失败的单元格是它的格式为日期,但为空。所有其他空单元格都是通用格式;它实际上是其周围唯一如此格式化的单元格。我猜这就是它失败的原因。对于 cell_types,我是否缺少其他一些 if ?

/*
* To change this license header, choose License Headers in Project     Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package datarefresh;

import java.io.FileInputStream;
import java.io.FileWriter;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

/**
*
* @author null
*/
public class DataRefresh {

public static String EOL = System.getProperty("line.separator"); //Finding out OS specific EOL and setting it to a string named EOL

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
    String StrInfoXLS = "\\\\path\\Dashboard.xls";
    String POSPwXLS = "\\\\path\\POS Passwords.xls";
    String NetPwXLS = "\\\\path\\Dashboard Data.xls";
    String SnLPwXLS = "\\\\path\\AccessVia ID & Passcodes - Helpdesk.xls";
    String StrInfoCSV = "\\\\path\\StoreInfoTst.csv";
    String POSPwCSV = "\\\\path\\POS PasswordsTst.csv";
    String NetPwCSV = "\\\\path\\Dashboard DataTst.csv";
    String SnLPwCSV = "\\\\path\\AccessVia ID & Passcodes - HelpdeskTst.csv";       
    String StrInfoSht = "Store List";
    String POSPwSht = "Sheet1";
    String NetPwSht = "Network";
    String SnLPwSht = "S & L Store List w Passcode";
    xlxTOcsvConverter(StrInfoXLS,StrInfoSht,StrInfoCSV);
    xlxTOcsvConverter(POSPwXLS,POSPwSht,POSPwCSV);
    xlxTOcsvConverter(NetPwXLS,NetPwSht,NetPwCSV);
    xlxTOcsvConverter(SnLPwXLS,SnLPwSht,SnLPwCSV);   //THIS ONE IS NOT WORKING
}

public static void xlxTOcsvConverter(String inFile, String inSheet, String outFile) {
    DataRefresh GetIt = new DataRefresh();
    String data = "";
    try{
        FileWriter output = new FileWriter(outFile);
        Workbook wb = WorkbookFactory.create(new FileInputStream(inFile));
        Sheet sheet = wb.getSheet(inSheet);
        Row row = null;
        for(int i = 0; i<sheet.getLastRowNum(); i++){
            row = sheet.getRow(i);
            for(int j = 0; j<row.getLastCellNum(); j++){
                Cell cell = row.getCell(j);
                data = GetIt.getCellValue(cell);
                output.write(data + ";");
            }
            output.write(EOL);
        }
        output.close();
    }
    catch(Exception e){
        System.out.println(e);
    }
}

private String getCellValue(Cell cell){
    String data = "";
    if(cell == null){
        return "";
    }
    if(cell.getCellType() == Cell.CELL_TYPE_BLANK){
        return "";
    }
    if(cell.getCellType() == Cell.CELL_TYPE_FORMULA){
        switch (cell.getCachedFormulaResultType()){
            case Cell.CELL_TYPE_NUMERIC:
                if(DateUtil.isCellDateFormatted(cell)){
                    data = String.valueOf(cell.getDateCellValue());
                    return data;
                }else{
                    double temp = cell.getNumericCellValue();
                    data = String.format("%.0f", temp);
                    return data;
                }
            case Cell.CELL_TYPE_STRING:
                data = cell.getStringCellValue();
                return data;
        }
    }
    if(cell.getCellType() == Cell.CELL_TYPE_STRING){
        data = cell.getStringCellValue();
        return data;
    }
    if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
        if(DateUtil.isCellDateFormatted(cell)){
            data = String.valueOf(cell.getDateCellValue());
            return data;
        }else{
            double temp = cell.getNumericCellValue();
            data = String.format("%.0f", temp);
            return data;
        }
    }
    return "";
}

}

这是它的堆栈跟踪:

Exception in thread "main" java.lang.NullPointerException
    at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:214)
    at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:186)
    at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:173)
    at jdk.nashorn.internal.objects.Global.checkObject(Global.java:1500)
    at jdk.nashorn.internal.objects.NativeError.printStackTrace(NativeError.java:187)
    at datarefresh.DataRefresh.xlxTOcsvConverter(DataRefresh.java:68)
    at datarefresh.DataRefresh.main(DataRefresh.java:45)
Java Result: 1
BUILD SUCCESSFUL (total time: 5 seconds)

我将捕获更改为:

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

现在堆栈跟踪返回:

Exception in thread "main" java.lang.NullPointerException
    at datarefresh.DataRefresh.xlxTOcsvConverter(DataRefresh.java:60)
    at datarefresh.DataRefresh.main(DataRefresh.java:47)
Java Result: 1

最佳答案

如果第 0 行和第 sheet.getLastRowNum() 行之间完全是空行,则 rowrow =sheet.getRow(i )。这是因为完全空的行实际上并未存储在 XLS 文件中。

这是你应该考虑的。示例:

public static void xlxTOcsvConverter(String inFile, String inSheet, String outFile) {
    DataRefresh GetIt = new DataRefresh();
    String data = "";
    try {
        FileWriter output = new FileWriter(outFile);
        Workbook wb = WorkbookFactory.create(new FileInputStream(inFile));
        Sheet sheet = wb.getSheet(inSheet);

        Row row = null;
        for(int i = 0; i<=sheet.getLastRowNum(); i++) {
            row = sheet.getRow(i);
            if (row == null) {
                data = "empty row";
                output.write(data);
            } else {
                for(int j = 0; j<row.getLastCellNum(); j++) {
                    Cell cell = row.getCell(j);
                    data = GetIt.getCellValue(cell);
                    output.write(data + ((j<row.getLastCellNum()-1) ? ";" : ""));
                }
            }
            output.write(EOL);
        }


        output.close();
    }
    catch(Exception e) {
        e.printStackTrace();
    }
}

关于Apache POI 在读取单元格数据以进行 CSV 转换时出现 Java 空指针异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30420240/

相关文章:

java - Akka actor消息需要内存池

java - C# 到 Java 字节转换

vba - 如何将特定工作表的列表添加到 ComboBox VBA 的列表中

php - 读取excel文件并将其存储到mysql数据库

vba - 寻求结合如何自定义 UDF 的插入函数向导和使 UDF 操作其他单元格

java - 使用Java使用Pig Latin连接到Cassandra

java - 模拟Mvc。如何在junit测试中涉及自定义对象

php - 正确设置 php,例如通过 .htaccess 添加多个 php 版本支持

apache - Varnish绕过大文件

Apache 无法在 xampp 中运行