Cannot read files written using SXSSFWorkbook in java - java

I want to read and write large excel files. Therefore, I used SXSSFWorkbook to write the excel file and XSSF and SAX EVENT API to read the files.
However, the cell content is empty when the excel file is read, and if the excel file is written using SXSSFWOrkbook. If I open the written excel file and save it again, the content is shown correctly.
The following is the code I used to write the excel file.
SXSSFWorkbook wb = new SXSSFWorkbook();
wb.setCompressTempFiles(true);
SXSSFSheet sh = (SXSSFSheet) wb.createSheet();
// sh.setRandomAccessWindowSize(100);// keep 100 rows in memory,
// exceeding rows will be flushed to disk
for (int rownum = 0; rownum < 100; rownum++) {
Row row = sh.createRow(rownum);
for (int cellnum = 0; cellnum < 10; cellnum++) {
Cell cell = row.createCell(cellnum);
String address = new CellReference(cell).formatAsString();
cell.setCellValue(address);
}
}
FileOutputStream out = new FileOutputStream("D:\\tempsxssf.xlsx");
wb.write(out);
out.flush();
out.close();
wb.dispose();
I am in a big trouble, can someone help me to figure out the issue?

I used another constructor according POI documentation
SXSSFWorkbook(workbook, rowAccessWindowSize, compressTmpFiles, useSharedStringsTable)
Like this:
SXSSFWorkbook workbook = new SXSSFWorkbook(null, 1000, true, true);
where you can enable shared strings table

Related

Not able to write data in xlsx file using java?

I Have a data stored in variables and then i want to write my data to excel file(.xlsx).
(i.e) I use automation testing tools like selenium to get data from webpage and i store it in variable which i want to wrie in xlsx file
After a lot of google search I found many of users uses list or objects to write into .xlsx file.
I created a list and add my variable to that list and using looping statements (for loop) i checked whether my data is stored in list by printing it.
Then I created XSSFWorkbook and XSSFSheet and XSSFRow and XSSFCell to write data.
I write a cell by using setCellValue method to my cell.
My code successfully creates a xlsx file and sheet in it
but after execution i could not able to find any data in it.
Source code:
ArrayList<String> head = new ArrayList<String>();
head.add("Register Number");
head.add(subject1);
head.add(subject2); //subject1 and subject2 are variable i created
System.out.println(head.get(1)); //To check if my list has value
XSSFWorkbook workbook = new XSSFWorkbook();
FileOutputStream fileOut = new FileOutputStream("/home/st.xlsx");
for (int i = 0; i < head.size(); i++)
{
XSSFRow Row = sheet1.createRow(1);
XSSFCell cell = Row.createCell(1);
cell.setCellValue(head.get(1));
sheet1.autoSizeColumn(1);
}
workbook.write(fileOut);
fileOut.close();
I expect my code add data to my file.
Main thing is During execution when i try to open my .xlsx file it has data in it.
But after the complete execution i get with the empty xlsx file.
I don't know why i'm getting this and What wrong in my code?
Thanks in advance!
ArrayList<String> head = new ArrayList<String>();
head.add("Register Number");
head.add(subject1);
head.add(subject2); // subject1 and subject2 are variable i created
System.out.println(head.get(0)); // To check if my list has value
System.out.println(head.get(1)); // To check if my list has value
System.out.println(head.get(2)); // To check if my list has value
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet1 = wb.createSheet("Sheet1");
for (int r = 0; r < head.size(); r++)
{
XSSFRow row = sheet1.createRow(r);
XSSFCell cell = row.createCell(0);
cell.setCellValue(head.get(r));
sheet1.autoSizeColumn(0);
}
// Write this workbook to a FileOutputStream.
FileOutputStream fileOut = new FileOutputStream("/home/st.xlsx");
workbook.write(fileOut);
fileOut.flush();
fileOut.close();
More info here:
https://gist.github.com/madan712/3912272

New Sheet is not getting created when i do Apache POI on a loop

I am facing an issue when i write huge set of data to a Excel file with multiple sheets. I am using apache POI for the excel export.
File file = new File("../path/file.xls");
FileOutputStream fout = new FileOutputStream(file);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
int limit = 100000,offset=0,count=0,sheetIndex=0;
XSSFWorkbook workbook = new XSSFWorkbook();
do{
XSSFSheet sheet = null;
if (file.exists() && sheetIndex > 0) {
try {
workbook = (XSSFWorkbook)WorkbookFactory.create(file);
} catch (InvalidFormatException e) {
e.printStackTrace();
}
sheet = workbook.createSheet("Sheet-"+sheetIndex);
}else{
workbook = new XSSFWorkbook();
sheet = workbook.createSheet("Sheet-"+sheetIndex);
}
Row header = sheet.createRow(0);
//...Header row creation...
List<DataType> result = query(criteria,offset,limit);
offset = offset + limit;
count = results.size();
sheetIndex++;
int rowCount = 1;
for(DataType rowData : results){
Row row = sheet.createRow(rowCount++);
//row creation....
}
try {
workbook.write(outputStream);
outputStream.writeTo(fout);
} finally {
outputStream.flush();
}
}while(count == limit);
workbook.write(outputStream);
outputStream.writeTo(fout);
outputStream.close();
fout.close();
In the loop i am fetching 100k records from DB and writing it to the excel, and each 100k i am creating a new Sheet until there are no more records from the DB.
This code have 2 issues
1. I am facing issues in opening the file, the excel file alert me that it has issues when i try to open, eventually when i say ok it loads the data.
I can see there are only 1 sheet with 100k data though my DB contains 240M records. I also can see the loop is looping for number of times.
How can i get these issues resolved? really stucked!
Thanks in advance.
The XSSFWorkbook workbook is created multiple times and it overwrites the one created on previous loop. The workbook needs to be created only once.
I suggest changing the loop entry to the following:
XSSFWorkbook workbook = new XSSFWorkbook();
do {
XSSFSheet sheet = workbook.createSheet("Sheet-"+sheetIndex);
Row header = sheet.createRow(0);
//...Header row creation...
// remaining code
I have changed WorkBook type to SXSSFWorkbook and set the flush limit to 100 and it worked.
The performance has increased 5 times better than the XSSFWorkbook.

Apache POI not "Saving" excel file

I am writing a small utility that creates a pivot table in an excel sheet using POI and I want to read the data from the pivot table back to the program which will save it as a PDF file using Itext. I am running into a problem where the program cannot read the data from the pivot table after it is created. The program only can "see" the information in the pivot table after I manually open the created file and hit the save button in excel. Does anyone know a way to read the data from the pivot table from the XSSFPivotTable object or otherwise force a way for the file to "save" so it can be accessed by the program again?
Here is a snippet of code so you can see what I'm talking about. I'm a student so any advice on best practices would be greatly appreciated as well.
public void returnPivotData() throws IOException {
FileInputStream fs = new FileInputStream(this.xlsxFile);
XSSFWorkbook book = new XSSFWorkbook(fs);
XSSFSheet dataSheet = book.getSheet("Sheet1");
AreaReference dataRef = new AreaReference("A1:E15",
SpreadsheetVersion.EXCEL2007);
XSSFPivotTable table = dataSheet.createPivotTable(dataRef,
new CellReference("A16"));
table.addRowLabel(0);
table.addColumnLabel(DataConsolidateFunction.SUM, 3);
// Save the data back to the file
FileOutputStream fsOut = new FileOutputStream(
"D:\\workspace\\test.xlsx");
book.write(fsOut);
fsOut.close();
book.close();
fs.close();
// This does not allow access
FileInputStream fsIn = new FileInputStream("D:\\workspace\\test.xlsx");
XSSFWorkbook bookNew = new XSSFWorkbook(fsIn);
XSSFSheet sheet = bookNew.getSheet("Sheet1");
for (int i = 0; i < 20; i++) {
XSSFRow rowNew = sheet.getRow(i);
XSSFCell cellNew = rowNew.getCell(0,
MissingCellPolicy.CREATE_NULL_AS_BLANK);
System.out.println(cellNew.toString());
}
fsIn.close();
bookNew.close();
}

How to read large xlsm files using apache POI

I am trying to read a large xlsm file for which i am getting heap space error,i am using XSSFWorkbook for the large file but still i am getting this .And also i have set the VM argumets -Xmx1024m to eclipse.Here is my code
public class TestSJXLSX {
public static void main(String[] args) throws Throwable {
OPCPackage pkg = OPCPackage.open(new File("D:\\resources\\1712_Reporting.xlsm"));
XSSFWorkbook wb_template;
wb_template = new XSSFWorkbook(
pkg
);
System.out.println("package loaded");
SXSSFWorkbook wb = new SXSSFWorkbook(wb_template); wb.dispose();
wb.setCompressTempFiles(true);
SXSSFSheet sh = (SXSSFSheet) wb.createSheet();
sh.setRandomAccessWindowSize(100);// keep 100 rows in memory, exceeding rows will be flushed to disk
for(int rownum = 4; rownum < 5000; rownum++){
Row row = sh.createRow(rownum);
for(int cellnum = 0; cellnum < 10; cellnum++){
Cell cell = row.createCell(cellnum);
String address = new CellReference(cell).formatAsString();
cell.setCellValue(address);
}
}
FileOutputStream out = new FileOutputStream(new File("D:\\new_file.xlsm"));
wb.write(out);
out.close(); }
}
SXSSFWorkbook is for streaming-writing, not reading. Did you try with XSSFWorkbook instead? This will still require quite some memory so might still go OOM with 1024m, depending on the size of the workbook.
Another approach is a streamed reading approach, see e.g. https://poi.apache.org/spreadsheet/how-to.html#xssf_sax_api for some description of this approach. There will be some features that are not supported there, though, so it might or might not be applicable for your use case.

Updating .XLSM file using Apache POI

I am trying to update an existing .XLSM file using Apache POI. Every time I run my code I receive an error as shown below.
Exception in thread "main" java.lang.IllegalArgumentException: Attempting to write a row[1] in the range [0,9] that is already written to disk.
at org.apache.poi.xssf.streaming.SXSSFSheet.createRow(SXSSFSheet.java:136)
at com.log.test.Test.main(Test.java:41)
Basically I wanted to use a macro enabled excel file as standard template , using java code i wanted to make a copy of template and update the some sheet's columns data and save the file.
I am trying with below sample code :
OPCPackage pkg = OPCPackage.open(new File("C:/LogTest/testme.xlsm"));
XSSFWorkbook wb_template;
wb_template = new XSSFWorkbook(pkg);
System.out.println("package loaded");
SXSSFWorkbook wb = new SXSSFWorkbook(wb_template);
wb.setCompressTempFiles(true);
SXSSFSheet sh = (SXSSFSheet) wb.getSheet("Asset Names");
sh.setRandomAccessWindowSize(100);
for (int rownum = 1; rownum < 10; rownum++) {
Row row = sh.createRow(rownum);
for (int cellnum = 0; cellnum < 2; cellnum++) {
Cell cell = row.createCell(cellnum);
String address = new CellReference(cell).formatAsString();
cell.setCellValue("hello");
}
}
FileOutputStream out = new FileOutputStream(new File("C:/output/new.xlsm"));
wb.write(out);
out.close();
wb.dispose();
System.out.println("Done !!!");
Can this be achieved using Apache POI ? or i need to use some other libraries ?
sample template

Categories