Bug 56574 - Excel file crashes while opening XLSX after writing/changing formulas in existing file
Summary: Excel file crashes while opening XLSX after writing/changing formulas in exis...
Status: RESOLVED FIXED
Alias: None
Product: POI
Classification: Unclassified
Component: XSSF (show other bugs)
Version: 3.10-FINAL
Hardware: All All
: P2 major (vote)
Target Milestone: ---
Assignee: POI Developers List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-05-29 07:39 UTC by Ranganath
Modified: 2015-05-19 13:14 UTC (History)
0 users



Attachments
Above description is achived in this file. (9.68 KB, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)
2014-05-29 07:39 UTC, Ranganath
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ranganath 2014-05-29 07:39:41 UTC
Created attachment 31676 [details]
Above description is achived in this file.

Step 1 : Create ".xlsx" file write any formula at A1 cell like "=Today()".
Step 2 : Drag "A1" Cell up to "A20" and save the file.
Step 3 : Through POI refer saved excel file and 
remove formula by using (cell.setFormula(null)) and write data to sheet containing formulas, write starts from Cells "A1" to "A10".
Step 4 : Execute your java program.
Step 5 : Try to open excel file, its giving error "Excel found unreadable content.". After opening below formulas cells formula and styles are overwriting to written style.
Comment 1 Dominik Stadler 2014-05-29 08:28:17 UTC
Can you provide the actual code that you use? Preferably as self-contained unit test so we can incorporate the steps into our test-suite and avoid the
Comment 2 Ranganath 2014-06-02 05:49:27 UTC
(In reply to Dominik Stadler from comment #1)
> Can you provide the actual code that you use? Preferably as self-contained
> unit test so we can incorporate the steps into our test-suite and avoid the

Below is the code I am using to remove formula from excel file.
               Row row = sheet.getRow(1);
                if (row == null){
			row = sheet.createRow(1);
		}

		Cell cell = row.getCell(1);
		if(cell == null){
			cell = row.createCell(1);
		} else {
                       /** Code to remove formula from cell **/
			if(cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
				cell.setCellFormula(null);
				cell.getCellStyle().setDataFormat((short) 0);
			}
                       /** End **/
		}
Comment 3 Ranganath 2014-06-02 08:48:42 UTC
Below is the entire code I used for above bug

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ExcelFormulaDrag {
	public static Workbook workbook07;
	public static Map<String, Object[]> data;
	public void setData() {
		//This data needs to be written (Object[])
        data = new TreeMap<String, Object[]>();
        data.put("1", new Object[] {"ID", "NAME", "LASTNAME"});
        data.put("2", new Object[] {2, "Amit", "Shukla"});
        data.put("3", new Object[] {1, "Lokesh", "Gupta"});
        data.put("4", new Object[] {4, "John", "Adwards"});
        data.put("5", new Object[] {2, "Brian", "Schultz"});
	}

	public void format2007() throws IOException {
        XSSFSheet sheet = (XSSFSheet) workbook07.getSheet("Emp");
		if(sheet == null){
		   sheet = (XSSFSheet) workbook07.createSheet("Emp");
		}
		Set<String> keyset = data.keySet();
        int rownum = 1;
        for (String key : keyset)
        {
            Row row = sheet.createRow(rownum++);
            this.writeToSheet(row, key);
        }
	}



	public void writeToSheet(Row row, String key){
            Object [] objArr = data.get(key);
            int cellnum = 0;
            for (Object obj : objArr)
            {
            	Cell cell = row.getCell(cellnum);
        		if(cell == null){
        			cell = row.createCell(cellnum);
        		} else {
        			if(cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
        				if(cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
        					cell.setCellFormula(null);
        					cell.getCellStyle().setDataFormat((short) 0);
        				}
        			}
        		}
               if(obj instanceof String) {
                    cell.setCellValue((String)obj);
               } else if(obj instanceof Integer) {
                    cell.setCellValue((Integer)obj);
               }
				XSSFFormulaEvaluator.evaluateAllFormulaCells((XSSFWorkbook) workbook07);
				workbook07.getCreationHelper().createFormulaEvaluator().evaluateAll();
               cellnum++;
            }
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
    	try {
    		ExcelFormulaDrag excelFormulaDrag = new ExcelFormulaDrag();
    		excelFormulaDrag.setData();
    		workbook07 = new XSSFWorkbook(new FileInputStream("D:\\testing7.xlsx"));
			excelFormulaDrag.format2007();
			FileOutputStream out = new FileOutputStream(new File("D:\\testing4.xlsx"));
			workbook07.write(out);
			out.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}


In .xlsx file in cell A1 type '=TODAY()' and drag up to A20, and refer same to above code and execute.
Comment 4 Dominik Stadler 2015-05-19 09:12:03 UTC
The problem in your code is 

    Row row = sheet.createRow(rownum++);

with this you are effectively overwriting an existing row and POI seems to not handle this nicely right now. 

By using 

    Row row = sheet.getRow(rownum++);

your example works as expected.
Comment 5 Dominik Stadler 2015-05-19 13:14:16 UTC
I have also fixed the case with using createRow() under r1680280, the Cells were invalidated, but not correctly removed when a createRow() overwrites an existing row. This should work correctly now.