Apache POI only last cell is saved to a newly created file - java

So I am pulling data from select cells from sheets in an excel file and then trying to write it to another file. The data is being carried over fine inside the vatAdata array and from what I can tell its being written to the cell in the for loop because it prints out each cell after inserting into (just for debugging purposes). But when I open the file later only the last cell has data in it and all other cells are null. Any idea what is causing this issue?
for(int i=0;i<vatAdata.length;i++){
Cell cellInsert=sheet.createRow(rowIndex).createCell(colIndex+i);
cellInsert.setCellType(vatAtype[i]);
// System.out.println(cellInsert.);
if(vatAtype[i]==0){
cellInsert.setCellValue(Double.parseDouble(vatAdata[i]));
System.out.println(cellInsert.getNumericCellValue()+" written");
}
else{
cellInsert.setCellValue(vatAdata[i]);
System.out.println(cellInsert.getStringCellValue()+" written");
}
}
FileOutputStream out=new FileOutputStream("/home/chris/Documents/test.xlsx");
wb.write(out);
out.close();

cellInsert=sheet.createRow(rowIndex).createCell(colIndex+i);
you need save the new Row value to a variable to reuse it.
row = sheet.createRow(rowIndex);
cellInsert = row.createCell(colIndex+i);

Related

What is causing excel to crash after updating file thru java?

I have some java code that opens an excel sheet, adds auto filter to a group of columns, then saves and closes. The problem is that when a user opens the file and trys to sort smallest to largest or largest to smallest excel will freeze then crash. But if you first filter then you can sort with out issue and it does not freeze and crash.
private static void AddFilter()
{
//Adds filter to the rows in Column 2
try
{
FileInputStream fileIn = new FileInputStream("C:\\Users\\gria\\Desktop\\Fleet Manager Summary.xls");
HSSFWorkbook report = new HSSFWorkbook(fileIn);
Sheet sheet = report.getSheetAt(0);
sheet.setAutoFilter(CellRangeAddress.valueOf("A5:P5"));
FileOutputStream fileOut = new FileOutputStream("C:\\Users\\gria\\Desktop\\Fleet Manager SummaryT.xls");
report.write(fileOut);
fileOut.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
Thank you,
UPDATE:
After some experimenting I have updated the info and code since the original question was asked to better explain the problem.
Try changing
XSSFFormulaEvaluator.evaluateAllFormulaCells(report);
to
HSSFFormulaEvaluator.evaluateAllFormulaCells(report);
XSSFFormulaEvaluator.evaluateAllFormulaCells() works for XSSfWorkbook, but not for the HSSFWorkbook.
Documentation
Also,
you can edit your commented code to:
for(int i = 5; i < sheet.getLastRowNum(); i++)
{
Cell cell = sheet.getRow(i).getCell(6);
//I don't know if you have data in all of the cells,
//So I suggest you to evaluate null
if(cell != null && !cell.getStringCellValue().isEmpty())
{
cell.setCellValue(Double.valueOf(cell.getStringCellValue()).doubleValue());
}
}

Writing 1 million records to Excel file with 300 columns

I am using Apache POI Streaming API- SXSSFWorkbook to write data to excel file.
But Excel file is getting corrupted for more than 100 000 records with 300 columns generally if the size is greater then 100Mb. Is there any way for writing huge data to excel file.
class Test1 {
public static void main(String[] args) throws FileNotFoundException, {
SXSSFWorkbook workbook = new SXSSFWorkbook(100);
workbook.setCompressTempFiles(true);
Sheet sheet = null;
Row row = null;
Cell cell = null;
sheet = workbook.createSheet("Demo1");
FileOutputStream outStream = new FileOutputStream("D:\\Test1.xlsx");
try {
for (int i = 0; i < 100000; i++) {
row = sheet.createRow(i);
for (int j = 0; j < 300; j++) {
cell = row.createCell(j);
cell.setCellValue(" row : "+i +" col: "+ j);
}
}
workbook.write(outStream);
} catch (Exception exception) {
exception.printStackTrace();
} finally {
workbook.dispose();
try {
outStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Edit 1:
What I found is, it is not the problem with Apache POI Streaming Api.It is generating the file with 1 Million records. But Excel is not loading that file. It is giving 'There isn't enough memory to complete this action' error.
I am using Excel 2013 32 bit version which can use only up till 2GB of memory. The excel file I created with 100k records and 300 columns has file size 108MB. When I try to open this file in Excel it is taking up whole lot of System memory. As soon as the memory consumption reaches 1.7 MB Excel is giving an error.
What is the minimum configuration to load 1million rows generated using Apache Streaming API? Any help would be appreciated.
Thanks.
Edit 2:
If I open Excel file generated using Apache Streaming Api in zip format(by renaming .xlsx to .zip),size of the xml file in xl->worksheets folder is around 2GB for 100k records and 300 columns. Is there any way to reduce the size of this xml file.
Never had tried generating more than about 100 to 120 columns myself. But a restriction at 255 columns max is not really surprising (had been this way with older Excel formats). Your observation that 100k rows with 200 columns is working fine, while 100k rows with 300 columns is failing, is a strong indicator of such a restriction.
Then you should be able to generate the 1 million (exactly 1048576) rows sheet with up to 255 columns.,For any extra rows and extra columns you will need to create extra sheets.
So, with your 300 columns target, you would generate sheet1 with the first 255 columns (or some less if there is reasonable logical grouping) and sheet2 with the other columns.
For more rows repeat the 2 sheets approach with a new pair of sheets until all rows have been generated.
BTW,
did you recognize that with using SXSSFWorkbook a rowAccessWindowSize of "1" is giving best performance?

Write items into excel cell

I am absolute new to the Eclipse Java coding. I am trying to finish a project for managing the inventory. The part i am having trouble with is that, when I tried to write the items into the excel cell, I got errors saying that the array is out of bounds.
PS: item and item.getPartname etc are all defined under another class file.
Please help. thanks
FileOutputStream os =new FileOutputStream("orderreceipt");
//Create a new workbook for writing data
HSSFWorkbook wb2 = new HSSFWorkbook();
//Create a new sheet:
HSSFSheet newsheet = wb2.createSheet("MyNewSheet");
//Create a new row:
for (int i=0; i<6; i++){
HSSFRow newrow = newsheet.createRow(i);
sentorder item = (sentorder)items.get(i);
for (short j=0; j<5; j++){
HSSFCell cell = newrow.createCell(j);
cell.setCellValue(item.getPartname());
cell.setCellValue(item.getPartnumber());
cell.setCellValue(item.getQuantity());
cell.setCellValue(new Date());
HSSFCellStyle styleOfCell = wb2.createCellStyle();
styleOfCell.setDataFormat(HSSFDataFormat
.getBuiltinFormat("m/d/yy"));
styleOfCell.setFillForegroundColor(HSSFColor.AQUA.index);
styleOfCell.setFillPattern(HSSFCellStyle.BORDER_THIN);
cell.setCellStyle(styleOfCell);
}}
wb2.write(os);
}
I can see quite a few problems with the attached code:
Missing file extension when creating new FileOutputStream - since you're generating the .xls workbook, you'd probably like to store it in the XLS file (the extension is not added automatically), also just make sure you have a proper file path to the directory you have write permissions (local application dir, as in this case should be ok though).
As already mentioned you are re-setting the same cell value 4 times
You are creating the same cell style multiple times (this is not cached behind the scenes and there is largely limited number of cells styles which can be created so if you were generating a couple thousands of rows you might get into troubles
You don't flush() and close() stream after writing your workbook. Streams in Java a precious resources which need to be manually closed.
Without stack trace it's difficult to say 100% where the ArrayOutOfBound issue you're seeing is coming from, however my guess would be that you're trying to access a item (from items collection) with the index that doesn't exist, which is a consequence that you're driving your report data from row indexes instead of the list of items you have.
Also, since you're quite new to Java a couple of guidelines which will allow you to produce hopefully better and less error-prone code in the future:
Use proper Java naming convention - please follow standard Java naming convention http://java.about.com/od/javasyntax/a/nameconventions.htm , your code will be easier to read and reason about (especially when you're looking for help from community) - i.e. sentorder class should be named as SentOrder.
Try to split your code into smaller, more testable modules i.e. you can have a helper createDataRow method called from your main method, in general having more than a couple of inner loops in one method makes them incredibly difficult to test, debug and reason about.
Unless you really need to generate .xls format, consider using XSSF* classes for generating xlsx document - it has many improvements over HSSF* (including much better dataFormat support).
Having those in mind I've rewritten your example:
public void improved(List<SentOrder> items) throws IOException {
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("MyNewSheet");
HSSFCellStyle styleOfCell = workbook.createCellStyle();
styleOfCell.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy"));
styleOfCell.setFillForegroundColor(HSSFColor.AQUA.index);
styleOfCell.setFillPattern(HSSFCellStyle.BORDER_THIN);
int rowIndex = 0;
for(SentOrder item : items) {
HSSFRow row = sheet.createRow(rowIndex++);
HSSFCell nameCell = row.createCell(0);
nameCell.setCellValue(item.getPartName());
HSSFCell numberCell = row.createCell(1);
numberCell.setCellValue(item.getPartNumber());
HSSFCell quantityCell = row.createCell(2);
quantityCell.setCellValue(item.getQuantity());
HSSFCell dateCell = row.createCell(3);
dateCell.setCellValue(new Date());
dateCell.setCellStyle(styleOfCell);
}
FileOutputStream os = new FileOutputStream("order_receipt.xls");
try {
workbook.write(os);
} finally {
os.flush();
os.close();
}
}

Why am I getting the number of rows in an Excel sheet as 0 using JAVA?

I am trying to write some data into an Excel file with format (.xlsx). But the thing is that the first row of it is written into the file correctly and when I am trying to retrieve the number of rows and then increment the rows so that I could write more rows into the file, I am getting an exception of "Invalid format exception" and sometimes my code is getting executed but I am getting row count as 1. Please solve my issue and I am even attaching the code am working with.
public static int getRows(String memail,String testid) throws FileNotFoundException,IOException, InvalidFormatException{
int rc;
FileInputStream file = new FileInputStream(new File("email1.xlsx"));
XSSFWorkbook wb = new XSSFWorkbook (file);
WorkbookFactory.create(file);
XSSFSheet sheet = wb.getSheet(testid);
rc = sheet.getLastRowNum();
return rc;
}
Remove the following line
WorkbookFactory.create(file);
and try again.
If you have already a created file, while you are creating that again...
You can try Sheet.getPhysicalNumberOfRows(), this will returns the number of physically defined rows (NOT the number of rows in the sheet).One more point are you sure you are getting the correct sheet from wb.getSheet(testid);?

Visit links from excel file using selenium web driver

I have an Excel file where all my links are stored in one single column. One Link on each row. For E.g:
www.example.com
www.test.com
www.demo.com
and so on. What I want to do is visit each link and open it in Firefox. Get the link in address bar and compare it with link in excel cell. If both are same them set the string "Pass" in next cell otherwise set string "Fail". How do I do This. Can you please give me a sample code? I am using selenium web driver with java.
Here is what I tried:
try {
FileInputStream file=new FileInputStream(new File(path));
FileOutputStream outFile=new FileOutputStream(new File(path));
HSSFWorkbook workbook=new HSSFWorkbook(file);
HSSFSheet sheet=workbook.getSheetAt(0);
HSSFCell cell=null;
int s=sheet.getLastRowNum()+1;
for(int i=0; i<s; i++){
cell=sheet.getRow(i).getCell(0);
String url=cell.toString();
driver.get(url);
Thread.sleep(10000);
String urlnew=driver.getCurrentUrl().toString();
HSSFRow row=sheet.getRow(i);
HSSFCell cellresult=row.createCell(1);
if(url==urlnew){
cellresult.setCellValue("Pass");
}else{
cellresult.setCellValue("fail");
}
workbook.write(outFile);
}
file.close();
outFile.close();
}
driver = webdriver.Firefox();
Load the Excel file (you can use this)
In the rows loop, add this code: driver.get(< cell URL>);
In your code you have used the following statement to compare two strings.
if(url==urlnew)
Use the below code. it will work.
if(url.equals(urlnew))
For more information on String comparision, check this link.

Categories