[英]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.