Issue while writing cells in excel file using apache POI - java

I am facing issue while writing the data to excel file.
I am using apache POI 4.1.2 version library.
Below is the sample code.
try {
outputStream = new FileOutputStream(EXCEL_FILE_PATH);
} catch (Exception e) {
System.out.println("Exception While writing excel file " + e.getMessage());
}
Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet("FileCompare");
Row row = sheet.createRow(0);
Cell cellfilename = row.createCell(0);
cellfilename.setCellValue("File Name");
Cell cellfilename1 = row.createCell(1);
cellfilename1.setCellValue("Difference in File 1");
Cell cellfilenam2 = row.createCell(2);
cellfilenam2.setCellValue("Difference in File 2");
for (int diffcol = 1; diffcol < 3; diffcol++) {
for (int i = 1; i < 57; i++) {
Row rows = sheet.createRow(i);
// System.out.println("Difference Coln number " + diffcol);
Cell diffcell = rows.createCell(diffcol);
diffcell.setCellValue("abacds");
/*
* Cell diffcell2 = row.createCell(2); diffcell2.setCellValue("abacds");
*/
}
}
try {
workbook.write(outputStream);
} catch (Exception e) {
e.printStackTrace();
} finally {
outputStream.flush();
outputStream.close();
workbook.close();
}
In this only last column cells is getting saved in excel file , previous cells are kept as blank.
Kindly help and let me know if I am doing something wrong?

Not sure about the actual api but I think you inner loop should create columns and your outer one should create rows like this
for (int row=1:row<57;row++)
{
Row rows = sheet.createRow(row);
for (int diffCol = 1; diffCol < 3; difCol++)
{
Cell diffcell = rows.createCell(diffcol);
diffcell.setCellValue("abacds");
}
}

The problem is that inside your loop you're always using sheet.createRow(i) to retrieve the row you need, but as the docs says (docs that are written not so clear, actually) this method is always recreating a brand new & empty row, deleting the existing one (if a row at that i-position was already present).
It means that each iteration of yuor loop is actually deleting previous rows creating brand new rows: at the end only rows created by the last iteration are surviving!
To solve you're problem, use sheet.createRow(i) only one time in order to create the row at i-position and then only use sheet.getRow(i) to retreive it.
So replace (in your code) the following wrong line
Row rows = sheet.createRow(i);
with the following code
Row row = sheet.getRow(i);
if (row == null) row = sheet.createRow(i);
where new row is created only if it does not already exist!
And you're done, it works like a charm!

Related

Getting Blank columns in Excel file created through JAVA in Spring Frameworks(REST API)

I am having some problems while creating an excel file. I am using Spring frameworks and Rest API. My procedure is as follows:
1:Getting a DataList from SQL.
2: In the DataList, I have two dates; the StartDate and the EndDate. I extract the data that is present between these two dates.
The problem:
While i can successfully retrieve the data for first two rows, the third row shows incomplete data. I get only first few columns, and the rest are just blank. I am assuming this could be because i have a column named CreatedDate, where the date in 2 rows is 2017-09-24 14:13 and 2017-09-19 14:33. Again, I am not sure if this is causing the error.
Any help will be highly appreciated.
workbook=new HSSFWorkbook();
HSSFSheet Sheet=workbook.createSheet("List Order Details");
Row rowHeading=Sheet.createRow(0);
rowHeading.createCell(0).setCellValue("Invoice ID");
rowHeading.createCell(1).setCellValue("Food Court Name");
rowHeading.createCell(2).setCellValue("Food Stall Name");
rowHeading.createCell(3).setCellValue("Customer Name");
rowHeading.createCell(4).setCellValue("Total Price");
rowHeading.createCell(5).setCellValue("order status");
rowHeading.createCell(6).setCellValue("Delivery Location");
rowHeading.createCell(7).setCellValue("Delivery Date");
rowHeading.createCell(8).setCellValue("Delivery Time");
for(int i=0;i<9;i++){
CellStyle stylerrowHeading=workbook.createCellStyle();
HSSFFont font=workbook.createFont();
font.setBold(true);
font.setFontName(HSSFFont.FONT_ARIAL);
font.setFontHeightInPoints((short)11);
stylerrowHeading.setFont(font);
stylerrowHeading.setVerticalAlignment(CellStyle.ALIGN_CENTER);
rowHeading.getCell(i).setCellStyle( stylerrowHeading);
}
if (null == excelList)
return null;
int r=1;
Row row=Sheet.createRow(r++);
//id coloumn
Cell cellId=(Cell) row.createCell(0);
orderDO.setId(String.valueOf(orderEntity.getId()));
cellId.setCellValue(""+orderEntity.getId());
r++;
//foodstall name
Cell cellStallName=(Cell) row.createCell(2);
cellStallName.setCellValue(foodStallEntity.getName());
r++;
//foodCourtname
Cell cellCourtName=(Cell) row.createCell(1);
cellCourtName.setCellValue(foodCourtEntity.getName());
//customername
Cell cellCustomerName=(Cell) row.createCell(3);
cellCustomerName.setCellValue(customerEntity.getName());
r++;
//total price
Cell cellTotalPrice=(Cell) row.createCell(4);
CellStyle styleprice=workbook.createCellStyle();
HSSFDataFormat cf=workbook.createDataFormat();
styleprice.setDataFormat(cf.getFormat(" $#,##0.00"));
cellTotalPrice.setCellStyle(styleprice);
//orderstatus
Cell cellOrderStatus=(Cell) row.createCell(5);
orderDO.setStatus(OrderStatusDTO.valueOf(orderEntity.getOrderstatus()));
cellOrderStatus.setCellValue(orderEntity.getOrderstatus());
//deliveryLocation
Cell cellBuilding=(Cell) row.createCell(6);
DeliveryLocationEntity deliveryLocationEntity = deliveryLocationRepository
.findById(orderEntity.getDeliverylocationid());
orderDO.setDeliveryBuilding(deliveryLocationEntity.getBuilding());
cellBuilding.setCellValue(deliveryLocationEntity.getBuilding());
//deliverydate
Cell cellDeliveryDate=(Cell) row.createCell(7);
String s1 = String.valueOf(orderEntity.getOrderDate());
orderDO.setOrderDate(s1.substring(0, 10));
cellDeliveryDate.setCellValue(orderEntity.getOrderDate());
CellStyle styleCreationDate=workbook.createCellStyle();
HSSFDataFormat dfCreationDate=workbook.createDataFormat();
styleCreationDate.setDataFormat(dfCreationDate.getFormat(" m/d/yy"));
cellDeliveryDate.setCellStyle(styleCreationDate);
//deliverytime
Cell cellDeliveryTime=(Cell) row.createCell(8);
orderDO.setDeliveryTime(orderEntity.getDeliverytime());
cellDeliveryTime.setCellValue(orderEntity.getDeliverytime());
for(int i=0;i<9;i++)
Sheet.autoSizeColumn(i);
FileOutputStream out=new FileOutputStream(new File("attachment; filename=listproducts.xls"));
//response.setHeader("Content-disposition", "attachment; filename=listproducts.xls");
workbook.write(out);
out.close();
workbook.close();
System.out.println("data enter Sucessfully...");
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
return workbook;
}
Observe this part of your code:
int r=1;
for (OrderEntity orderEntity : excelList) {
Row row=Sheet.createRow(r++);
// more code
r++;
// more code
r++;
// more code
r++;
// more code
r++;
// more code
r++;
}
you are increasing the r variable by calling r++; far too many times for no apparent reason. So the first time it is used in the Sheet.createRow(r++); call it has value 1, it then gets increased 6 (or more, the end of the for loop is missing) times before the createRow(r++) is called again for the next row. This r++ I think is not needed, you should remove these calls.
However your code still looks incomplete so I do not know if my answer will completely solve your problem. I cannot see where your for loop ends so there may be some more r++ somewhere.

Not able to write to excel at run time using POI

I am trying to write my test results/data to excel at runtime for which I have written the below code. I am not getting any error while compiling this code however the results are not getting written in this. Can someone help me out with the problem?
public void WritetoExcel(String filepath, String OrderID) throws IOException
{
FileInputStream ExcelFile = new FileInputStream(filepath);
System.out.println(filepath);
ExcelWBook = new XSSFWorkbook(ExcelFile);
System.out.println("WorkBook Sucessfully");
ExcelWSheet = ExcelWBook.getSheetAt(0);
System.out.println("Sheet Sucessfully");
Iterator<Row> rowIterator= ExcelWSheet.iterator();
int RowNum =0;
while (rowIterator.hasNext())
{
Row row=rowIterator.next();
RowNum++;
}
try
{
Row = ExcelWSheet.createRow(RowNum);
Iterator<Cell> cellIterator=Row.iterator();
Cell = Row.getCell(0);
if (Cell==null)
{
Cell=Row.createCell(0);
Cell.setCellValue(OrderID);
}
else
{
Cell.setCellValue(OrderID);
}
FileOutputStream fileOut = new FileOutputStream(filepath);
ExcelWBook.write(fileOut);
fileOut.flush();
fileOut.close();
}
catch (Exception e )
{
throw (e);
}
}
I was going to make this a comment, but it is too long.
There are a few comments I can make about your code.
First, it seems you are iterating through and counting rows that exist in the sheet. Then you are creating a new row at that index. Since a spreadsheet could have missing rows, this will only work for a very specific type of spreadsheet. That is, one which has no missing rows, and you always want to add the next row in the next empty spot. Instead of:
Iterator<Row> rowIterator= ExcelWSheet.iterator();
int RowNum =0;
while (rowIterator.hasNext())
{
Row row=rowIterator.next();
RowNum++;
}
try
{
Row = ExcelWSheet.createRow(RowNum);
You can just as easily use:
int rowNum = ExcelWSheet.getLastRowNum() + 1;
Row row = ExcelWSheet.createRow(rowNum);
Then you write orderId in the first column of that row. Instead of:
Iterator<Cell> cellIterator=Row.iterator();
Cell = Row.getCell(0);
if (Cell==null)
{
Cell = Row.createCell(0);
Cell.setCellValue(OrderID);
}
else
{
Cell.setCellValue(OrderID);
}
You could just use:
Cell cell = row.createCell(0, MissingCellPolicy.CREATE_NULL_AS_BLANK);
cell.setCellValue(OrderID);
In addition, for this you don't even need the iterators, but when you really need to iterate through the rows and cells of a spreadsheet it is better to use the for each syntax like this:
for (Row row : sheet) {
for (Cell cell : row) {
// do something with the cell
}
}

Apache POI Pivot table error when same index is used for both column and row label

I am trying to create a pivot table to do cohort analysis
pivotTable.addColumnLabel(DataConsolidateFunction.COUNT, 1);
pivotTable.addRowLabel(1);
this is giving me an error while opening the file that the file is corrupt do you want to still open the file, when I say yes and open it, the result looks fine, the only issue is the error.
I did a workaround to have a duplicate column data with different name
for ex:
say column 1 is email added a duplicate column 36 with name dup email and did as shown below, it works fine
pivotTable.addColumnLabel(DataConsolidateFunction.COUNT, 1);
pivotTable.addRowLabel(35);
why in the first place it failed when I give both column and row label as 1.
Any help is greatly appreciated
If you set pivotTable.addRowLabel(1) using apache poi, then apache poi sets pivot field 1 only to be axisRow but it needs to be dataField too if you also want to pivotTable.addColumnLabel(DataConsolidateFunction.COUNT, 1). So we neeed to correct this.
Example:
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import java.io.*;
class PivotTableTest5 {
private static void setCellData(Sheet sheet) {
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("Name");
cell = row.createCell(1);
cell.setCellValue("City");
for (int r = 1; r < 15; r++) {
row = sheet.createRow(r);
cell = row.createCell(0);
cell.setCellValue("Name " + ((r-1) % 4 + 1));
cell = row.createCell(1);
cell.setCellValue("City " + (int)((new java.util.Random().nextDouble() * 3)+1) );
}
}
public static void main(String[] args) {
try {
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet();
//Create some data to build the pivot table on
setCellData(sheet);
XSSFPivotTable pivotTable = sheet.createPivotTable(
new AreaReference(new CellReference("A1"), new CellReference("B15")), new CellReference("H5"));
//Count the second column. This needs to be second column a data field.
pivotTable.addColumnLabel(DataConsolidateFunction.COUNT, 1);
//Use second column as row label
pivotTable.addRowLabel(1);
//Apache poi sets pivot field 1 (second column) only to be axisRow but it needs to be dataField too.
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(1).setDataField(true);
FileOutputStream fileOut = new FileOutputStream("PivotTableTest5.xlsx");
wb.write(fileOut);
fileOut.close();
wb.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

poi cannot write data into .xlsx

the problem is when I tried to write data into cells, the cell either hasn't been created or it just doesn't show the data in it.
For instance,
Row[] rownames = new Row[names.size()];
for(int i = 0; i < names.size(); i++){
rownames[i] = sheet.createRow(i+3);
Cell machine = rownames[i].createCell(0);
machine.setCellType(Cell.CELL_TYPE_STRING);
machine.setCellValue(names.get(i).toString());
}
names[] is an array that contains a list of names.
Cell machine = rownames[i].createCell(0); creates a cell at (i+3,0), in which i means row.
machine.setCellValue(names.get(i).toString()); sets cell value to the corresponding name[i].
I tried print names[] and machine.getStringCellValue(), and both of them can return the exact correct data (like output to console). but there's nothing in xlsx file. many thanks in advance.
EDIT:
Let me explain more clearly, so if everything goes well, the very part of this xlsx file should be like this:
harry | (row 3, col 0)
kate | (row 4, col 0)
jim | (row 5, col 0)
aaron | (row 6, col 0)
...
...
But now the situation is:
| (row 3, col 0)
| (row 4, col 0)
| (row 5, col 0)
| (row 6, col 0)
...
...
Right now the xlsx is 4KB. it contains some other information, which have been put there via this very program. Those parts don't have this problem.
Looks like you create row by same index multiple times in further (non posted) code.
How poi creates XSSFRow:
public XSSFRow createRow(int rownum) {
CTRow ctRow;
XSSFRow prev = _rows.get(rownum);
if(prev != null){
// the Cells in an existing row are invalidated on-purpose, in order to clean up correctly, we
// need to call the remove, so things like ArrayFormulas and CalculationChain updates are done
// correctly.
// We remove the cell this way as the internal cell-list is changed by the remove call and
// thus would cause ConcurrentModificationException otherwise
while(prev.getFirstCellNum() != -1) {
prev.removeCell(prev.getCell(prev.getFirstCellNum()));
}
ctRow = prev.getCTRow();
ctRow.set(CTRow.Factory.newInstance());
}
...
}
So, if row exists and contains cell, all cells with data will be removed.
To avoid this, use CellUtil class:
Get a row from the spreadsheet, and create it if it doesn't exist.
CellUtil.getRow(rowIndex, sheet);
Get a specific cell from a row. If the cell doesn't exist, then create it.
CellUtil.getCell(row, columnIndex);
You have not posted file opening and closing code. Based on description, it seems that you are not writing data back to Excel file. Do something like this:
FileOutputStream out = new FileOutputStream(new File("path of excel file"));
wb.write(out);
wb.close();
out.close();
After executing entire code, then check excel file for the output generated.
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
This is my code...
HSSFFont boldFont;
HSSFFont bodyFont;
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("namefile");
HSSFRow row = sheet.createRow((short)0);
//HSSFCellStyle cellStyle = workbook.createCellStyle();
//cellStyle.setFillBackgroundColor(HSSFColor.GREY_25_PERCENT.index);
//cellStyle.setFillForegroundColor(HSSFColor.LAVENDER.index);
//cellStyle.setFillPattern(HSSFCellStyle.ALIGN_CENTER);
row.setHeightInPoints(23);
sheet.setColumnWidth((short)0, (short)2000);
sheet.setColumnWidth((short)1, (short)3000);
sheet.setColumnWidth((short)2, (short)3000);
sheet.setColumnWidth((short)3, (short)3000);
sheet.setColumnWidth((short)4, (short)3000);
sheet.setColumnWidth((short)5, (short)3000);
sheet.setColumnWidth((short)6, (short)3000);
sheet.setColumnWidth((short)7, (short)3000);
sheet.setColumnWidth((short)8, (short)3000);
sheet.setColumnWidth((short)9, (short)3000);
sheet.setColumnWidth((short)10, (short)3000);
sheet.setColumnWidth((short)11, (short)3000);
row.createCell((short)0).setCellValue("FLT NO");
row.createCell((short)1).setCellValue("LEG");
row.createCell((short)2).setCellValue("DATE");
row.createCell((short)3).setCellValue("AC-REG");
row.createCell((short)4).setCellValue("SCHED DEP");
row.createCell((short)5).setCellValue("OFFBLK");
row.createCell((short)6).setCellValue("AIRBORNE");
row.createCell((short)7).setCellValue("LANDING");
row.createCell((short)8).setCellValue("ONBLK");
row.createCell((short)9).setCellValue("SCHED ARR");
row.createCell((short)10).setCellValue("FUEL_USED_PILOT");
row.createCell((short)11).setCellValue("ACTUAL FUEL");
ProofSheetFPRModel model = new ProofSheetFPRModel();
int rownum = 1;
for (int i=0; i<DataList.size(); i++)
{
model = DataList.get(i);
row = sheet.createRow((short)rownum);
row.createCell((short)0).setCellValue(model.getFlightNo());
row.createCell((short)1).setCellValue(model.getLEG());
row.createCell((short)2).setCellValue(model.getDate());
row.createCell((short)3).setCellValue(model.getAC_REG());
row.createCell((short)4).setCellValue(model.getSCHED_DEP());
row.createCell((short)5).setCellValue(model.getOFF_BLK());
row.createCell((short)6).setCellValue(model.getAIRBORNE());
row.createCell((short)7).setCellValue(model.getLANDG());
row.createCell((short)8).setCellValue(model.getON_BLK());
row.createCell((short)9).setCellValue(model.getSCHED_ARR());
row.createCell((short)10).setCellValue(model.getFUEL_USED_PILOT());
row.createCell((short)11).setCellValue(model.getACTUAL_FUEL());
rownum++;
}
try
{
FileOutputStream out = new FileOutputStream(new File(filePath));
workbook.write(out);
out.close();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}

Problems with starting a new row in Excel with Apache POI

I'm using the apache poi package to create a spreadsheet of figures which represent features of a shape (area, perimeter, centroid). The problem is that i have a method: writeDatabase() which outputs the features of the shape as they are found, the output spreadsheet looks like this:
http://s23.postimg.org/hqsfg76jv/Capture.png
All of these figures need to be in the same line, and then a new line needs to be taken for the next record. the writeDatabase method is shown below
public static void writeDatabase(int value, int cellNum){
try {
Cell cell1=null;
FileInputStream file = new FileInputStream(new File("features.xls"));
Workbook workbook = new HSSFWorkbook(file);
Sheet sheet = workbook.getSheetAt(0);
int lastRow = sheet.getPhysicalNumberOfRows();
cell1 = sheet.createRow(lastRow).createCell(cellNum);
cell1.setCellValue(value);
FileOutputStream outFile =new FileOutputStream(new File("features.xls"));
workbook.write(outFile);
outFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I think the problem is with this line being called each time, but i cant think of an alternative:
int lastRow = sheet.getPhysicalNumberOfRows();
Any ideas?
You need to provide some indication of whether a new line should be started or not (unless you can tell that a new line is starting simply because cellNum is 0?)
Then, you can either create a new row, or use the existing row:
int lastRow = sheet.getPhysicalNumberOfRows();
Row row;
if (startNewRow) {
row = sheet.createRow(lastRow);
} else {
row = sheet.getRow(lastRow - 1);
}
cell1 = row.createCell(cellNum);
cell1.setCellValue(value);
Where startNewRow might be set based on cellNum, or might be an additional parameter that is passed into writeDatabase, whichever is appropriate.

Categories

Resources