Apache poi方法将数据写入现有工作簿

时间:2015-01-14 10:11:01

标签: java excel apache-poi

这是我读写现有excel文件的类。我一直通过传递filePath和fileName来调用主类中的这些函数。

   public class NewExcelFile {

    Workbook workbook;

    /******* Methods *******/
    // returns a workbook on giving the excel file's path and name
    public Workbook readExcel(String filePath, String fileName) {
        // Create object of File class to open xlsx file
        File file = new File(filePath + "\\" + fileName);
        // Create an object of FileInputStream class to read excel file
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            System.out.println("Error: Unable to find " + fileName + " in "
                    + filePath);
            e.printStackTrace();
        }
        Workbook workbook = null;
        // Find the file extension by spliting file name in substring and
        // getting only extension name
        String fileExtensionName = fileName.substring(fileName.indexOf("."));
        // Check condition if the file is xlsx file
        if (fileExtensionName.equals(".xlsx")) {
            // If it is xlsx file then create object of XSSFWorkbook class
            try {
                workbook = new XSSFWorkbook(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // Check condition if the file is xls file
        else if (fileExtensionName.equals(".xls")) {
            // If it is xls file then create object of XSSFWorkbook class
            try {
                workbook = new HSSFWorkbook(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        this.workbook = workbook;
        return workbook;

    }

    public void writeExcel(String filePath, String fileName, String sheetName,
            String dataToWrite, int rowno) {

        System.out.println("WriteExcel" + filePath + " " + fileName + " "
                + sheetName + " " + dataToWrite + " " + rowno);

        Workbook newWorkbook = readExcel(filePath, fileName);
        Sheet sheet = newWorkbook.getSheet(sheetName);
        System.out.println("Sheet: " + sheet.getSheetName());

        Cell resultcell;

        ******resultcell = sheet.getRow(rowno).createCell(8);
        resultcell.setCellType(Cell.CELL_TYPE_STRING);
        resultcell.setCellValue(dataToWrite);

        CellStyle style = workbook.createCellStyle();
        if (dataToWrite == "P") {
            style.setFillBackgroundColor(IndexedColors.GREEN.getIndex());
            style.setFillPattern(CellStyle.ALIGN_FILL);
            resultcell.setCellStyle(style);
        } else if (dataToWrite == "F") {
            style.setFillBackgroundColor(IndexedColors.RED.getIndex());
            style.setFillPattern(CellStyle.ALIGN_FILL);
            resultcell.setCellStyle(style);
        }
        // Create an object of FileOutputStream class to create write data in
        // excel file
        File file = new File(filePath + "\\" + fileName);
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            System.out.println("File not found");
            e.printStackTrace();
        }

        // write data in the excel file and close output stream
        try {
            workbook.write(outputStream);
            outputStream.close();
        } catch (IOException e) {
            System.out.println("Error in writing to file");
            e.printStackTrace();
        }

    }

当我使用readExcel在main中获取工作簿并调用此函数时:

Row row = testScriptsSheet.getRow(24);

我得到了正确的行,并且能够调用此行上的所有函数。但是对于writeExcel()中完全相同的表中的完全相同的行,我得到一个空指针异常(前面带有***的行)在上面的代码中)。 getRow()在这里给我null。我在这里做错了什么?

另外,我应该将工作簿作为数据成员保留,并在需要时执行myNewExcelFile.workbook或将其作为从主类中的readExcel返回的变量保留吗? 此外,我想知道现在发生了什么,我没有关闭readExcel函数末尾的inputStream。无论是否关闭inputStream,我都会得到相同的错误。

编辑 - 添加主要功能

public class NewDriver {

public static void main(String[] args) {
    System.out.println("Starting the framework");
    // initialise the workbook
    NewExcelFile testExecution = new NewExcelFile();
    testExecution.readExcel(System.getProperty("user.dir") + "\\",
            "abc.xlsx");

    // initialise sheets of workbook
    Sheet testSuiteSheet = testExecution.workbook.getSheet("TestSuite");
    Sheet testScriptsSheet = testExecution.workbook.getSheet("TestCases");
    Row row = testScriptsSheet.getRow(24);//gives the correct row

    //calling writeExcel gives npe in that line


        }
    }
}

}

2 个答案:

答案 0 :(得分:1)

docs getRow(int)方法:

  

返回基于0的逻辑行(非物理行)。如果你要求排   没有定义你得到一个null。这就是说第4行代表   一张纸上的第五行。

因此,如果未定义行,则必须先创建行,然后创建单元格。

答案 1 :(得分:0)

根据我的理解,这似乎是一个概念错误。在调用WriteExcel()方法之前,您在main方法中所做的所有更改都在缓冲区中,而不是写在硬盘中的excel表/工作簿中。但是在WriteExcel()方法中,您没有传递保存在缓冲区中的工作表或工作簿,而是传递实际存在于硬盘驱动器中的工作簿的地址。因此,您在main函数中所做的任何更改都不存在,因此显示空指针异常。

e.g。我在D Drive中有一个工作簿,A0值为1。现在我已经以编程方式将其设为2但不执行写操作,并将执行置于保持状态。同时我去了我的D驱动器并打开工作表将有1而不是2,因为更新的值在缓冲区中,直到我在该工作簿上执行写操作。

建议:为什么不传递在main方法中使用的工作簿,而不是传递工作簿的地址。

更新:实际上不是主要方法,而是readExcel(String filePath, String fileName)方法。