POI 3.2 Excel file Data has been lost - java

I'm generating an Excel file in Java with POI 3.2 (Latest version I can use for my client).
Here is my code. As you can see I'm using HSSF because I need to make a XLS file.
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("Reporting");
sheet.setColumnWidth(250,250);
HSSFRow Row;
HSSFCell Cell;
//Content part (doesn't matter)
IWDResource resource = WDResourceFactory.createCachedResource(
wb.getBytes(),
"workbook.xls",
WDWebResourceType.XLS);
wdContext.currentContextElement().setXls(resource);
Now after I've downloaded the XLS file, I want to open it but the file seems to be corrupt.
Image on link: http://tinyurl.com/nop52sh
When I'm pressing 2 times on 'Don't send', de excell file opens in correct form.
Any idea why?

Don't call wb.getBytes(), it doesn't do what you want. From the getBytes() javadoc
Method getBytes - get the bytes of just the HSSF portions of the XLS file. Use this to construct a POI POIFSFileSystem yourself.
Instead, if you want the overall xls file as a byte array, do
ByteArrayOutStream baos = new ByteArrayOutStream();
wb.write(baos);
byte[] xlsBytes = baos.toByteArray();
Finally, Apache POI 3.2 is ancient, over 5 years old now! You really ought to upgrade, see the changelog for an idea of all the bugs fixed since then

Related

Apache poi workbookfactory create HSSFWorkbook from xlsx, But I expect XSSFWorkbook

I'm trying to create XSSFWorkbook from file.xlsx by calling:
1. XSSFWorkbookFactory.create(file) -> return HSSFWorkbook
2. WorkbookFactory.createXSSFWorkbook(file) -> While trying to invoke 'createWorkbook' on factory org.apache.poi.xssf.usermodel.XSSFWorkbookFactory and arguments [path to file.xlsx]
3. OPCPackage.open(file) -> The supplied data appears to be in the OLE2 Format. You are calling the part of POI that deals with OOXML (Office Open XML) Documents. You need to call a different part of POI to process this data (eg HSSF instead of XSSF)
XSSFWorkbook wb = new XSSFWorkbook(pkg);
4. XSSFWorkbookFactory.createWorkbook(new FileInputStream(file)) -> The supplied data appears to be in the OLE2 Format. You are calling the part of POI that deals with OOXML (Office Open XML) Documents. You need to call a different part of POI to process this data (eg HSSF instead of XSSF)
I need to read a file as XSSFWorkbook to read and set new params to chart.
Any ideas, why I catch this errors and why way from item 1 returns HSSFWorkbook?
I checked several times, the file has .xlsx extension.

Force read only first sheet in Apache POI

I am using Apache POI to read the data only in the first sheet of an excel file. The xlsx files that are submitted usually have only 1 sheet and are around 2.5MB (with a little more than 130k rows of data), and everything goes slow but smooth with no errors. However, if the submitted xlsx has more than one sheet, and if the other sheet(s) also have a lot of data in them, the execution throws an OutOfMemoryError: Java heap space error. Now I am trying to figure out if it somehow possible to always only read the data on the first sheet without worrying about the memory errors (i am running this with -Xmx1024m -Xms512m arguments)
EDIT: here is my code
InputStream inputStream = new FileInputStream(new File(excelfile));
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
if (workbook.getNumberOfSheets() != 1) {
throw new Exception("Make sure excel only has 1 sheet");
}
The program is throwing an error on the second line (if the excel file has a lot of data on the second sheet as well)
Apache POI usually triggers a lot of issues related to memory, I strongly recommend to use monitorjbs instead https://github.com/monitorjbl/excel-streaming-reader
InputStream is = new FileInputStream(new File(filePath));
Workbook workbook = StreamingReader.builder()
.rowCacheSize(100) // number of rows to keep in memory (defaults to 10)
.bufferSize(2048) // buffer size to use when reading InputStream to file (defaults to 1024)
.open(is)) {
Sheet sheet = workbook.getSheetAt(0);

Can not read .xlsm file - POI

I have written a code to access .xlsm file but it fails to do so. I have tried the same file using both XSSFWorkBook and the Generic WorkBook which is done using WorkBookFactory.
Scenario 1:
org.apache.poi.ss.usermodel.Workbook workbook = WorkbookFactory.create(new File(
"/filename.xlsm"));
Error:
The supplied spreadsheet seems to be an Encrypted .xlsx file. It must be decrypted before use by XSSF, it cannot be used by HSSF.
So I left the generic way of reading the file and used XSSF.
Scenario 2:
XSSFWorkbook workBook = new XSSFWorkbook(new FileInputStream(new
File("/fileName.xlsm")));
Error:
org.apache.poi.POIXMLException: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13]
Both the scenarios do work on some .xlsm files. Properties and data with working and non working files are the same.
Can someone help in fixing this.?
Promoting a comment to an answer... You need to upgrade your version of Apache POI!
You can view the Apache POI changelog here, and see quite how many changes there have been since 3.9 came out 3 years ago. It's quite a number of pages of fixes! And you need at least one of those...

Out of Memory Error - Java Heap Space while writing to Excel

I have a data of almost 100,000 records and I am trying to write the data to .xlsx file using XSSFWorkbook through Java code. I am able to fetch all the data from database to an ArrayList. By iterating the ArryList, I am writing the data to .xlsx file cell by cell.
As it reaches to 8000 rows, java code throws Out of Memory Heap Space Error.
I have read somewhere that SXSSFWorkbook will be lighter when compared to XSSFWorkbook, so I tried using SXSSFWorkbook. But still I am facing the same problem.
So is there anything that I am missing with the Workbooks or with my Java Code??
Initially, when I have 60,000 records data, I had used .xls file. The same java code is able to generate the .xls file with HSSFWorkbook.
Increasing the Java Heap Space is not at all an option as my data will be increased tremendously in future.
Any help will be greatly appreciated.
Small piece of code, the way I am writing the data to Excel.
int rowNum = sheet.getLastRowNum();
Row lastRow = null ;
Cell cell = null;
ReportingHelperVo reportingHelperVo = null;
for (ReportingVo reportingVo : reportingVos) {
rowNum++;
lastRow = sheet.createRow(rowNum);
reportingHelperVo = reportingVo.reportingHelperVo;
cell = lastRow.createCell(0);
cell.setCellValue(reportingHelperVo.getLocation());
cell.setCellStyle(style);
cell = lastRow.createCell(1);
cell.setCellValue(reportingHelperVo.getCity());
cell.setCellStyle(style);
cell = lastRow.createCell(2);
cell.setCellValue(reportingHelperVo.getCountry());
cell.setCellStyle(style);
}
SXSSFWorkbook is not like light weight,but there is a advantage with this.
If you declare as
SXSSFWorkbook workbook= new SXSSFWorkbook(200);
then for every 200 rows written on the workbook, memory will be flushed to diskspace so there will be no burden in heapspace.
XSSFWorkbook - creates an object representation for all Excel documents (should work like DOM).
SXSSFWorkbook - should require constant memory. When is OOM thrown by JMV? What type of ResultSet did you use? Try to use FORWARD_ONLY to restrict caching data by JDBC driver retrieved from DB.
BTW best weay to fix OutOfMemoryError is to analyze heap dump.
Use -XX:+HeapDumpOnOutOfMemoryError parameter and MAT to understand how your application works.
I am writing the data to .xlsx file cell by cell. As it reaches to
8000 rows, java code throws Out of Memory Heap Space Error.
Re-use exsiting java objects, instead of creating new ones each iteration.
And/or use a csv file instead of excel.
Workbook workBook = new SXSSFWorkbook();
You can export more than 1 lakh (100000) records.
Page results from the database rather than reading them all in one go.
I had similar problems long time ago attempting to write from R to an excel file (but using XLConnection).
In the end, I solved by using write.csv and then opening it with Excel and using the botton "Text to column".
It is increadibly fast and reliable.
I have got the same issue when my excel was reaching 3000 lines. In my case the main memory related issue with POI Excel generation happens with the style sheet. Following are the things which I removed from my code.
Try to use style sheet setting in a row level.
If at all you need to set the style sheet for every cell.. avoid setting border for each and every cell.
Hi Use latest Apache POI JAR//And Use SXSSF for streaming or downloading
SXSSFWorkbook workbook = new SXSSFWorkbook(100);
workbook.setCompressTempFiles(true);
Sheet sh = workbook.createSheet();
((SXSSFSheet) sh).setRandomAccessWindowSize(100);
//write your logic
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;
filename="+filename+".xlsx");
workbook.write(response.getOutputStream());
workbook.close();
workbook.dispose();
I had an out of memory issues writing a XSSFWorkbook to a file.
The Suggestions above helped a lot.
See http://poi.apache.org/components/spreadsheet/how-to.html#xssf_sax_api
Changing XSSFWorkbook wb = new XSSFWorkbook();
to SXSSFWorkbook wb = new SXSSFWorkbook(-1);
SXSSFSheet sh = ... to SXSSFSheet sh = ...
XSSFRow to SXSSFRow
XSSFCell to SXSSFCell
inside the for loop USE sh.flushRows(100); for every 100th row
after wb.write(out);
ADD wb.dispose();

Edit existing excel files using jxl api / Apache POI

I am interested and would like to learn more about java , how to write into existing excel sheets / manipulating the existing data. I was wondering if you could give me an idea on how to edit an existing excel file and save it using the jxl api / Apache POI
or perhaps give me a sample program on how to edit some data in an existing excel file and then save it
Thanks in advance !!
The tutorials here are very helpful and well-written. They use an external JAR developed by the Apache POI project.
Here's an simple example of editing one cell:
InputStream inp = new FileInputStream("wb.xls");
Workbook wb = WorkbookFactory.create(inp);
Sheet sheet = wb.getSheetAt([sheet index]);
Row row = sheet.getRow([row index]);
Cell cell = row.getCell([cell index]);
String cellContents = cell.getStringCellValue();
//Modify the cellContents here
// Write the output to a file
cell.setCellValue(cellContents);
FileOutputStream fileOut = new FileOutputStream("wb.xls");
wb.write(fileOut);
fileOut.close();
Hope it helps
One very important tip that I learned the hard way.
Open the OutputStream only after you have completed writing to your excel workbook. Zabbala's example is spot on and shows this correctly. If you open the OutputStream any earlier, your changes would not be written to the file after your program exits and you would be scratching your head as I did.
I refresh the formulas with another tab for this I use the next sentence
HSSFSheet worksheetse = workbook.getSheetAt(0);
worksheetse.setForceFormulaRecalculation(true);
but it's necesary that you apply the method setForceFormulaRecalculation for all the tabs that have the formulas.
Sorry for my English
Hello i have the same problem than neXGen. But strangely if i open the file with openoffice, it works!
Edit: perhaps i found a solution, put this after changing the values:
HSSFFormulaEvaluator.evaluateAllFormulaCells(workbook);

Categories

Resources