Update excel using Java - java

I am trying to update a column in the excel sheet but only the first row is getting update. The second iteration is not working. Could anyone help me on this? Below is my code that I am trying.
String excelPath = "path";
String YES = "Updated YES";
String NO = "Updated NO";
try {
FileInputStream fis= new FileInputStream(excelPath);
HSSFWorkbook workSheet = new HSSFWorkbook(fis);
Cell cell = null;
FileOutputStream output_file =new FileOutputStream(excelPath);
for (int i = 0; i < TCID.size(); i++) {
HSSFSheet sheet1 = workSheet.getSheetAt(0);
String data = sheet1.getRow(i+1).getCell(i).toString();
if(data.equals(TCID.get(i))){
cell = sheet1.getRow(i+1).getCell(i+2);
cell.setCellValue(YES);
workSheet.write(output_file);
}else {
cell.setCellValue(NO);
workSheet.write(output_file);
}
}
fis.close();
output_file.close();
workSheet.close();
}catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
My latest code is below. Now it is updating the columns but the last row is not getting updated. What am i missing.
FileInputStream fis= new FileInputStream(excelPath);
HSSFWorkbook workSheet = new HSSFWorkbook(fis);
HSSFSheet sheet1 = workSheet.getSheetAt(0);
//FileOutputStream output_file =new FileOutputStream(excelPath);
for (int i = 0; i < TCID.size(); i++) {
String data = sheet1.getRow(i+1).getCell(0).toString();
Cell cell = sheet1.getRow(i+1).getCell(2);
if(data.equals(TCID.get(i))){
cell.setCellValue(YES);
}else {
cell.setCellValue(NO);
}
}
fis.close();
//output_file.close();
//workSheet.close();
FileOutputStream output_file =new FileOutputStream(excelPath);
workSheet.write(output_file);
output_file.close();

The row and the column are both keyed off 'i', so you'll be traversing the sheet diagonally.
But certainly do the things the other people are recommending too, they are all good suggestions.
Typically when working with a two dimensional block of information, I find it useful to have one loop for rows and then nested inside that a loop for columns (or vice versa)
e.g.
for (y = startRow; y <= maxRow; y++) {
....
for (x = startCol; x <= maxCol; x++) {
.... // do something to each column in the current row
cell = sheet1.getRow(y).getCell(x);
.....

Ok, so there are a couple of things.
Declare HSSFSheet sheet1 = workSheet.getSheetAt(0); outside of your loop. You are working with the same sheet each iteration of your for loop, so this only has to be invoked once.
Your logic to get the cell data (String data = sheet1.getRow(i+1).getCell(i).toString();) will not return you the same column. On your first iteration, you'll get (R)ow 1 : (C)olumn 0. The next iteration will return R2 : C1, then R2:C2, then R3:C3, etc. Notice the pattern that you are going diagonally down the columns, not vertically.
Rows start at 0.
You only need to workSheet.write(output_file); once you have done all your processing.
If the Row does not exist you will get a NullPointerException
As you are working with a unique Cell each iteration, you just declare it in the loop (so no need for Cell cell = null; outside your loop).
Here is a an example:
try {
FileInputStream fis = new FileInputStream(excelPath);
Workbook workbook = new HSSFWorkbook(fis);
Sheet sheet = workbook.getSheetAt(0);
for (int i = 0; i < 5; i++) {
Row row = sheet.getRow(i);
if (row != null) {
Cell cell = row.getCell(0);
cell.setCellValue("Updated cell.");
}
}
FileOutputStream output_file = new FileOutputStream(excelPath);
workbook.write(output_file);
output_file.close();
fis.close();
} catch (Exception e) {
e.printStackTrace();
}

I think moving Cell reference inside for loop should fix it for you.
Cell cell = null;
Also you might also need to move outside if-block incase you face NullPointerException in else-block
cell = sheet1.getRow(i+1).getCell(i+2)
Something like this...
HSSFSheet sheet1 = workSheet.getSheetAt(0);
for (int i = 0; i < TCID.size(); i++) {
String data = sheet1.getRow(i+1).getCell(0).toString();
Cell cell = sheet1.getRow(i+1).getCell(2);
if(data.equals(TCID.get(i))){
cell.setCellValue(YES);
}else {
cell.setCellValue(NO);
}
workSheet.write(output_file)
}

Related

How can I print the passing string row by row in excel

I am printing some string values in excel
In excel currently last string is printing, but I need to print them all row by row
Code
for(String a:arrOfStr)
{
System.out.println(a);
//CustomKeywords.'WriteExcel.demoKey'(a)
CustomKeywords.'WriteExcel.demoKey'(a)
}
keyword
#Keyword
public void demoKey(String name) throws IOException{
FileInputStream fis = new FileInputStream("C:\\Users\\lahiruh\\Katalon Studio\\Project Decypha\\Decypha data files\\Demo1.xlsx");
XSSFWorkbook workbook = new XSSFWorkbook(fis);
XSSFSheet sheet = workbook.getSheet("Sheet1");
int rowCount = sheet.getLastRowNum()-sheet.getFirstRowNum();
Row row = sheet.createRow(rowCount+);
Cell cell = row.createCell(0);
cell.setCellType(cell.CELL_TYPE_STRING);
cell.setCellValue(name);
FileOutputStream fos = new FileOutputStream("C:\\Users\\lahiruh\\Katalon Studio\\Project Decypha\\Decypha data files\\Demo1.xlsx");
workbook.write(fos);
fos.close();
Now I can get the output like(overriding each value and giving last string )
I want to see like
Try this
for(int i = 0; i < arrOfStr.size(); i++)
{
String a = arrOfStr[i];
System.out.println(a);
//CustomKeywords.'WriteExcel.demoKey'(a)
CustomKeywords.'WriteExcel.demoKey'(a,i)
}
#Keyword
public void demoKey(String name, int index) throws IOException{
FileInputStream fis = new FileInputStream("path");
XSSFWorkbook workbook = new XSSFWorkbook(fis);
XSSFSheet sheet = workbook.getSheet("Sheet1");
Row row = sheet.createRow(index + 1);
Cell cell = row.createCell(0);
cell.setCellType(cell.CELL_TYPE_STRING);
cell.setCellValue(name);
FileOutputStream fos = new FileOutputStream("path");
workbook.write(fos);
fos.close();
}
}
You have to do in the following manner.
First create a set of rows
Create cell and define the cell data type.
Store the value in the cell
I provide below the structure to store the data row by row.
int rowNumber = 0; // Row number starting with 0
for (i = 0 ; i < 10 ; i++) { //This for loop can be your data set
Row row = sheet.createRow(rowNumber++);
int columnNumber = 0; //Cell or Column number starting with 0
for (j = 0 ; j < 5 ; j++) { //This for loop can be your data set
Cell cell = row.createCell(columnNumber++);
cell.setCellValue("Some string value");
}
}

How to store an excel table into a double String array using apache POI?

I want to save the values from a table in excel and store them into a String[][] variable in order to make it easier to manipulate, here is my code:
public class TakingDataFromExcel {
public static void main(String[] args) {
try{
FileInputStream file = new FileInputStream(new File("C:\\Book1.xls"));
Workbook workbook = new HSSFWorkbook(file);
Sheet sheet = workbook.getSheetAt(0);
String[][] headers= null;
String value = null;
for (int i= 0;i < sheet.getPhysicalNumberOfRows(); i++) {
DataFormatter formatter = new DataFormatter();
for (int j=0; j<=6;j++) {
Row row = sheet.getRow(i);
value = formatter.formatCellValue(row.getCell(j));
headers[i][j].concat(value.toString());
}
}
System.out.println(headers);
System.out.println(sheet.getPhysicalNumberOfRows());
String[] cdsid=null;
cdsid=headers[1][1].split(" ");
for (int x=0; x<cdsid.length;x++) {
System.out.println(cdsid[x]);
}
file.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
I'm still getting a null pointer exception error but I can´t see where it is. I am open to any suggestions if you think there is is an easier way to do this task.
And here is the error:
java.lang.NullPointerException
at com.ford.samples.TakingDataFromExcel.main(TakingDataFromExcel.java:26)
You never initialize your 2 dimensional String[] .
String[][] headers= null; should be
String[][] headers= new String[SOME_X][SOME_Y]
getPhysicalNumberOfRows() will just count the number of rows in the sheet that are defined. You are iterating over rows assuming that they are sequential. Is it possible that you have an empty row in your spreadsheet and getRow(j) is returning null?
You can try something like this:
Iterator<Row> rowIt = sheet.rowIterator();
while (rowIt.hasNext()) {
Row row = rowIt.next();
}

Why can't set a value for a row and column with the Apache POI?

I need to set a value for a specific row and column of the spreadsheet, but I get a null pointer before even i = 1. I've tried changing the code but this error keeps happening and I have no more idea why.Does anyone have any idea why this happens?
My code
public Workbook build(Planilha planilha) {
File file = new File(TEMPLATE_PATH);
if (!file.exists()) {
Log.error(this, String.format("File %s not exists.", file.getAbsolutePath()));
throw new NotFoundException("File not exists.");
}
Workbook wb = null;
try (FileInputStream fs = new FileInputStream(file)) {
wb = new XSSFWorkbook(fs);
wb = writeMetadatas(planilha, wb);
Map<String, Integer> header = getHeader(wb);
Sheet sheet = wb.getSheetAt(0);
Row row;
Cell cell;
for (int i = 0; i <= 10; i++) {
row = sheet.getRow(i);
for (int j = 0; j <= 10; j++) {
cell = row.getCell(j, Row.CREATE_NULL_AS_BLANK);
if (cell.getColumnIndex() == 0 && row.getRowNum() == 7) {
cell.setCellValue("teste");
}
}
}
} catch (Exception e) {
Log.error(this, "Erro: Planilha não existe", e);
System.err.print("Erro");
}
String tmpDir = System.getProperty("java.io.tmpdir");
File f = FileUtil.file(PATH, System.currentTimeMillis() + ".xlsx");
try {
FileOutputStream fout = new FileOutputStream(f);
wb.write(fout);
fout.flush();
fout.close();
} catch (Exception e) {
Log.error(this, "Erro ao abrir arquivo p escrever.");
}
return wb;
}
**NullPointer happens in cell.setCellValue("teste");
I'm trying to set that cell
First, you can test if the row number is a certain number outside of your for loop that loops over the cells in a row. Pull that if outside your j for loop.
It looks like the Cell doesn't exist. row.getCell(j) is returning null.
You can use a MissingCellPolicy to determine whether you want to return a new Cell if the Cell doesn't already exist. The CREATE_NULL_AS_BLANK value will create a blank Cell for you if it doesn't already exist.

FileOutputStream (Apachhe POI) taking too long time to save

When I am edit a .xlsx file using Apache poi, its taking too long to save. The .xlsx file contains, formulas formatting and freeze pane. I am using the following code,
try {
FileInputStream file = new FileInputStream(new File(path));
XSSFWorkbook fWorkbook = new XSSFWorkbook(file);
XSSFSheet fSheet = fWorkbook.getSheetAt(0);
for(int i = 0; i < jTable1.getRowCount(); i++){
if(jTable1.getModel().getValueAt(i, index1).equals("1")){
XSSFCell cell = fSheet.getRow(i+1).getCell(index1);
cell.setCellType(XSSFCell.CELL_TYPE_NUMERIC);
cell.setCellValue(new Double(1));
XSSFCellStyle cs = fWorkbook.createCellStyle();
cs.setDataFormat(fWorkbook.getCreationHelper().createDataFormat().getFormat("dd/MMMM/yyyy"));
cell =fSheet.getRow(i+1).getCell(index2);
cell.setCellValue(new Date());
cell.setCellStyle(cs);
}
}
file.close();
FileOutputStream fileOutputStream = new FileOutputStream(path);
fWorkbook.write(fileOutputStream);
fileOutputStream.close();
JOptionPane.showMessageDialog(this, "Data saved successfully.");
parent.removeContent();
}catch(Exception e){
e.printStackTrace();
}
Edit 1:
The excel file: http://ge.tt/5orGWSJ2/v/0?c
Loading Data into JTable from Excel:
try {
FileInputStream file1 = new FileInputStream(new File("c:\\sample.xlsx"));
XSSFWorkbook workbook = new XSSFWorkbook(file1);
XSSFSheet sheet = workbook.getSheetAt(0);
int rowc=sheet.getLastRowNum()+1;
int colc=sheet.getRow(0).getLastCellNum();
Object heading[] = new Object[colc+1];
XSSFRow row1 = sheet.getRow(0);
for(int i=0, column =0; i < colc; i++){
if(i == 1){
heading[column++] = "";
}
heading[column++] = cellToString(row1.getCell(i));
}
Object [][]j=new Object[rowc-1][colc+1];
for (int i = 1; i < rowc; i++) {
row1 = sheet.getRow(i);
for (int jj = 0, column = 0; jj < colc; jj++) {
if(column == 1){
j[i-1][column++] = new Boolean(false);
j[i-1][column] = cellToString(row1.getCell(jj));
}
else{
j[i-1][column]=cellToString(row1.getCell(jj));
}
column++;
}
}
jTable1.setModel(new DefaultTableModel(j, heading){
public Class getColumnClass(int columnIndex) {
if(columnIndex == 0){
return java.lang.Integer.class;
}
else if(columnIndex == 1){
return java.lang.Boolean.class;
}
else{
return java.lang.Object.class;
}
}
});
jTable1.getColumnModel().getColumn(1).setMaxWidth(60);
jTable1.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
jTable1.getTableHeader().setReorderingAllowed(false);
} catch (IOException ex) {
JOptionPane.showMessageDialog(BarcodePrint.this, ex);
}
Writing data into excel after editing column BarcodePrint:
try {
FileInputStream file = new FileInputStream(new File("c:\\sample.xlsx"));
XSSFWorkbook fWorkbook = new XSSFWorkbook(file);
XSSFCellStyle cs = fWorkbook.createCellStyle();
cs.setDataFormat(fWorkbook.getCreationHelper().createDataFormat().getFormat("dd/MMMM/yyyy"));
Date currentdate = new Date();
XSSFSheet fsheet = fWorkbook.getSheetAt(0);
Double barcodeprintstatus = new Double(1);
int newindex = 24;
int printdate = 26;
int uniqueid = 27;
for(int i = 0; i < jTable1.getModel().getRowCount(); i++){
if(jTable1.getModel().getValueAt(i, newindex).equals("1")){
for(int k=1; k < fsheet.getPhysicalNumberOfRows(); k++){
XSSFCell cell = fsheet.getRow(k).getCell(uniqueid-1);
String uid = cell.getRawValue();
if(jTable1.getModel().getValueAt(i, uniqueid).toString().equals(uid)){
cell = (fsheet.getRow(i+1)).getCell(newindex-1);
cell.setCellType(XSSFCell.CELL_TYPE_NUMERIC);
cell.setCellValue(barcodeprintstatus);
cell = fsheet.getRow(i+1).getCell(printdate-1);
cell.setCellValue(currentdate);
cell.setCellStyle(cs);
}
}
}
}
file.close();
FileOutputStream fileOutputStream = new FileOutputStream("c:\\sample.xlsx");
fWorkbook.write(fileOutputStream); // this is taking so much of time. Approximately 1 min.
fileOutputStream.close();
}catch(Exception e){
e.printStackTrace();
}
I am unable to solve this problem. fWorkbook.write(fileOutputStream); is taking so much of time as I mentioned above. Please help. Is there any other way to save the excel file? Or can I write data partially for a single column rather than the hole workbook?
Try to improve the code.
You call fSheet.getRow(i+1) twice. Try to introduce a variable and reuse the row rather than obtain it.
cell.setCellValue(new Double(1));
Create the 1 double once before the for loop and reuse it.
XSSFCellStyle cs = fWorkbook.createCellStyle();
cs.setDataFormat(fWorkbook.getCreationHelper().createDataFormat().getFormat("dd/MMMM/yyyy"));
Move the cell style creation and initializing out of the for loop. Create it before the loop and reuse.
cell.setCellValue(new Date());
Introduce a Date variable and create the Date just once. Again before the for loop.
Add a BufferedOutputStream around the FileOutputStream.

getting null pointer exception java while reading from excel XSSFCell cell = row.getCell(j);

private String[][] data;
// to read from excel file
public void readFile() throws IOException {
// Path to the excel file
// File datafile = new File("C:\\Users\\atomar\\Documents\test.xlsx");
// A Buffered File Input Stream to read the data
FileInputStream f = new FileInputStream(
"C:\\Users\\atomar\\Documents\\test.xlsx");
System.out.println("file found");
// InputStream fis = new BufferedInputStream(new FileInputStream("f"));
// We create a workbook which represents the excel file
XSSFWorkbook book = new XSSFWorkbook(f);
// Next a sheet which represents the sheet within that excel file
XSSFSheet sheet = book.getSheet("Sheet1");
// No of rows in the sheet
int rowNum = sheet.getLastRowNum() + 1;
System.out.println("rowNum");
// No of columns in the sheet
int colNum = sheet.getRow(0).getLastCellNum();
// A Two dimensional array of Strings which represents the data in the
// sheet
data = new String[rowNum][colNum];
{
for (int i = 0; i < rowNum; i++) {
// Get the row
XSSFRow row = sheet.getRow(i);
for (int j = 0; j < colNum; j++) {
// Get the columns or cells for the first row and keep
// looping
// for the other rows
XSSFCell cell = row.getCell(j);
// Make a call to the method cellToString which actually
// converts the cell contents to String
data[i][j] = cellToString(cell);
// data[i][j] = value;
// Here is where you write the logic to handle the data.I am
// just printing out the contents here.
//System.out.println("The value is " + data[i][j]);
}
}
Here I am calling that function
public void InterestedParty() throws InterruptedException {
try {
readFile();
} catch (IOException e1) {
}
}
Getting error: There are no support for this type of cell
I deleted two row data from input excel file then it started before it was working fine. But now I have deleted those row completely the also issue is there
if there is no data, XSSFCell will be null. Check whether it is null or not. After call your cellToString() method.
XSSFCell cell = row.getCell(j);
if(cell != null) {
data[i][j] = cellToString(cell);
} else {
// if you would like to set value when cell is null
row.createCell(j).setCellValue(your value);
}
You can have a row with data, an empty row next then another row with data. The middle row can be viewed as null if is undefined, so my advice is to use an iterator for the rows.
RowIteratior here is a good start.
Also, once you have the row, you can use cell iterator to iterate over the cells. Keep in mind that an undefined cell will be viewed as null and skipped, but an empty cell is not null!
Cell iterator is doc'ed here.
Your approach is also good, but you need to check for nulls or empty at each iteration before working with the objects.

Categories