简体   繁体   English

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

[英]Apache poi method to write data to an existing workbook

This is my class to read and write existing excel files. 这是我的课程,用于读写现有的excel文件。 I have been calling these functions in the main class by passing the filePath and fileName. 我一直在通过传递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();
        }

    }

When I get a workbook in the main using readExcel and call this function: 当我使用readExcel在主体中获得工作簿并调用此函数时:

Row row = testScriptsSheet.getRow(24);

I get the correct row and am able to call all functions on this row.But for the exact same row in the exact same sheet in the writeExcel(), I get a null pointer exception(the line preceded by *** in the code above). 我得到正确的行并能够调用该行上的所有函数,但是对于writeExcel()中完全相同的工作表中的完全相同的行,我得到了一个空指针异常(代码中以***开头的行)以上)。 getRow() gives me null here. getRow()在这里给我空值。 What am I doing wrong here? 我在这里做错了什么?

Also, should I keep workbook as a data member and do myNewExcelFile.workbook whenever I need it or keep it as a variable returned from the readExcel in the main class? 另外,是否应该将工作簿保留为数据成员,并在需要时使用myNewExcelFile.workbook还是将其保留为从主类中的readExcel返回的变量? Also I was wondering what is happening now that I am not closing the inputStream at the end of the readExcel function. 我也想知道现在发生了什么,因为我没有在readExcel函数的末尾关闭inputStream。 I get the same error whether I close the inputStream or not. 无论是否关闭inputStream,我都会遇到相同的错误。

EDIT - Adding the main function 编辑-添加主要功能

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


        }
    }
}

} }

From the docs the getRow(int) method: 文档中获取getRow(int)方法:

Returns the logical row (not physical) 0-based. 返回从0开始的逻辑行(非物理行)。 If you ask for a row that is not defined you get a null. 如果您请求未定义的行,则会得到一个空值。 This is to say row 4 represents the fifth row on a sheet. 也就是说,第4行代表纸张上的第五行。

So when a row is not defined, you must first create the row and then create the cell. 因此,当未定义行时,必须首先创建该行,然后再创建该单元格。

As per my understanding it seems a conceptual error. 根据我的理解,这似乎是一个概念上的错误。 Before calling WriteExcel() method, all the changes that you have made in main method are in buffer, not written in the excel sheet/workbook present in your harddisk. 在调用WriteExcel()方法之前,您对main方法所做的所有更改都在缓冲区中,而不是写入硬盘中存在的excel工作表/工作簿中。 But in WriteExcel() method you are not passing the sheet or workbook you kept in buffer, but the address of the one physically present in the hard drive. 但是在WriteExcel()方法中,您不是传递保存在缓冲区中的工作表或工作簿,而是传递物理存在于硬盘驱动器中的地址。 So any change you have done in main function is not there, hence showing null pointer exception. 因此,您对主函数所做的任何更改都不存在,因此显示了空指针异常。

eg I have one workbook in say my D Drive, having value 1 in A0. 例如,我的D盘中有一个工作簿,A0中的值为1。 Now I have programmatically made it 2 but not perform the write operation, and put the execution on hold. 现在,我已以编程方式将其设置为2,但未执行写入操作,并暂停了执行。 Meanwhile I went to my D drive and open the sheet there will be 1 not 2, as the updated value is in buffer, till I have perform write operation on that workbook. 同时,我去D驱动器并打开工作表,结果为1而不是2,因为更新的值在缓冲区中,直到我对该工作簿执行写操作为止。

Suggestion: Instead of passing the address of the workbook, why not you just pass the workbook you have used in main method. 建议:为什么不传递工作簿的地址,为什么不传递主要方法中使用的工作簿呢?

UPDATE: Not the main method but readExcel(String filePath, String fileName) method actually. 更新:不是主要方法,但readExcel(String filePath, String fileName)方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM