How to update excel metadata using java - excel

I am trying to update excel metadata in java using apache POI. Input file is large containing 8K columns and 600 rows. I am using below code
OPCPackage pkg = OPCPackage.open(new File("path for input"));
POIXMLProperties props = new POIXMLProperties(pkg);
props.getCoreProperties().setTitle("Test Title");
XSSFWorkbook wb = new XSSFWorkbook(pkg);
FileOutputStream fos = new FileOutputStream("path for output");
BufferedOutputStream bos = new BufferedOutputStream(fos);
wb.write(bos);
fos.close();
Above code is throwing me Out Of memory exception as below.
java.lang.OutOfMemoryError: Java heap space
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at org.apache.xmlbeans.impl.store.Locale$SaxLoader.load(Locale.java:3414)
at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1272)
at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1259)
at org.apache.xmlbeans.impl.schema.SchemaTypeLoaderBase.parse(SchemaTypeLoaderBase.java:345)
at org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument$Factory.parse(Unknown Source)
at org.apache.poi.xssf.usermodel.XSSFSheet.read(XSSFSheet.java:227)
at org.apache.poi.xssf.usermodel.XSSFSheet.onDocumentRead(XSSFSheet.java:219)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.parseSheet(XSSFWorkbook.java:452)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.onDocumentRead(XSSFWorkbook.java:417)
at org.apache.poi.ooxml.POIXMLDocument.load(POIXMLDocument.java:184)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:286)
Could you please help to overcome this issue for updating excel properties ?

Promoting a comment to an answer....
If you're just changing the OPC level metadata, there's no need to load the file up in the XSSF layer at any point. You'd only need to do that if you also wanted to change the spreadsheet contents eg cells
Your code can be as simple as
OPCPackage pkg = OPCPackage.open(new File("path for input"));
POIXMLProperties props = new POIXMLProperties(pkg);
props.getCoreProperties().setTitle("Test Title");
props.commit();
pkg.close();

Related

Apach poi Excel write() takes too much time

I am building excel (xlsx) using POI 4.0. Below is the final code to flush and close excel workbook which takes around 4 sec on my macbook pro for aprox 900Kb on disc (actual .xlsx file). Is there any way to improve it?
Also, I am not writing huge data. Actually opening existing excel which has functions and some static content, adding a header row with cell style (around 60 columns) and then closing it.
Tried using SXSSFWorkbook but no improvement.
Tried to replace FileOutputStream with ByteArrayOutputStream (just to test performance) but its pretty much same.
public void generateFinalExcelFile(XSSFWorkbook workbook) throws IOException {
String filePath = "somepath.xlsx"
File outFile = new File(filePath);
FileOutputStream outputStream = new FileOutputStream(outFile);
BufferedOutputStream out = new BufferedOutputStream(outputStream);
workbook.write(out); // this one takes long time.
out.close();
workbook.close();
}

How to create a new sheet and write some data in the existing excel using selenium java

I tried the below code.
But it overwrite the existing sheet.
File f= new File(System.getProperty("user.dir")+"\\src\\test\\resources\\Exceldata.xls");
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet worksheet= workbook.createSheet("Sheet4");
HSSFRow row = worksheet.createRow(1);
HSSFCell cell= row.createCell(1);
cell.setCellValue("admin");
enter code here
workbook.write(f);
workbook.close();
Use FileInputStream instead of File and and object of XSSFWorkbook
I hope this function may help you,
public static void write(){
try
{
FileInputStream myxls = new FileInputStream(System.getProperty("user.dir")+"\\src\\test\\resources\\Exceldata.xls" );
HSSFWorkbook studentsSheet = new HSSFWorkbook(myxls);
workbook = new XSSFWorkbook(myxls );
workbook.createSheet(sheetname);
HSSFSheet worksheet = studentsSheet.getSheetAt(0);
a=worksheet.getLastRowNum();
System.out.println(a);
Row row = worksheet.createRow(++a);
row.createCell(1).setCellValue("");
myxls.close();
FileOutputStream output_file =new FileOutputStream(new File(System.getProperty("user.dir")+"\\src\\test\\resources\\Exceldata.xls"));
//write changes
workbook.write(output_file );
studentsSheet.write(output_file);
output_file.close();
System.out.println(" is successfully written");
}
Try calling this function from main maethod,
public static void main(String args[])
{
write();
}
Possible duplicate of Append Data in existing Excel file using apache poi in java and
How to add new sheets to existing excel workbook using apache POI?
I finally found out the solution. i had used poi jar 4.0 in which i could not succeed in writing data. I then downgraded the jar version to 3.14 and i works perfectly

Apache POI header error

I am trying to read an xlsx file using Apache POI. Here is my code -
public static void convertFromXlsx(File inputFile, File outputFile) {
StringBuffer bf = new StringBuffer();
FileOutputStream fos = null;
String strGetValue = "";
try {
fos = new FileOutputStream(outputFile);
// XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(inputFile));
org.apache.poi.ss.usermodel.Workbook wb = WorkbookFactory.create(inputFile);
java.io.IOException: Invalid header signature; read 0x0000000000000000, expected 0xE11AB1A1E011CFD0
Please help me understand why this is happening and how it can be fixed.
There were intially 2 sheets in the xlsx file. I have tried with copies of the file - first removing the 2nd sheet and also by copying and pasting the content into a new sheet as text only but both lead to the same error.

to read a big excel file in java

I am trying to read a excel file through java apache poi in netbeans containing about 8000 columns and 1200 rows for which I am getting the following exception. I have also tried to increase the heap size in netbeans with –Xmx2048m but it doesn’t help me out.
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at org.apache.xmlbeans.impl.store.Cur$CurLoadContext.attr(Cur.java:3039)
at org.apache.xmlbeans.impl.store.Cur$CurLoadContext.attr(Cur.java:3060)
at org.apache.xmlbeans.impl.store.Locale$SaxHandler.startElement(Locale.java:3250)
at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.reportStartTag(Piccolo.java:1082)
at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseAttributesNS(PiccoloLexer.java:1802)
at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseOpenTagNS(PiccoloLexer.java:1521)
at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseTagNS(PiccoloLexer.java:1362)
at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseXMLNS(PiccoloLexer.java:1293)
at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseXML(PiccoloLexer.java:1261)
at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.yylex(PiccoloLexer.java:4808)
at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.yylex(Piccolo.java:1290)
at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.yyparse(Piccolo.java:1400)
at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.parse(Piccolo.java:714)
at org.apache.xmlbeans.impl.store.Locale$SaxLoader.load(Locale.java:3439)
at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1270)
at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1257)
at org.apache.xmlbeans.impl.schema.SchemaTypeLoaderBase.parse(SchemaTypeLoaderBase.java:345)
at org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument$Factory.parse(Unknown Source)
at org.apache.poi.xssf.usermodel.XSSFSheet.read(XSSFSheet.java:188)
at org.apache.poi.xssf.usermodel.XSSFSheet.onDocumentRead(XSSFSheet.java:180)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.onDocumentRead(XSSFWorkbook.java:300)
at org.apache.poi.POIXMLDocument.load(POIXMLDocument.java:159)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:221)
at testdoc.Testdoc.main(Testdoc.java:26)
Java Result: 1
BUILD SUCCESSFUL (total time: 49 seconds)
The line no 26 is
File excel = new File ("E:\\Project\\Rapid out\\"+filename+""+type+".xlsx");
FileInputStream fis = new FileInputStream(excel);
Line 26:: XSSFWorkbook wb = new XSSFWorkbook(fis);
XSSFSheet ws = wb.getSheet("Sheet2");
Instead of using InputStream, can you try with File:
XSSFWorkbook wb = new XSSFWorkbook(excel);
From POI Guide
When opening a workbook, either a .xls HSSFWorkbook, or a .xlsx XSSFWorkbook, the Workbook can be loaded from either a File or an InputStream. Using a File object allows for lower memory consumption, while an InputStream requires more memory as it has to buffer the whole file.

Protect a sheet results in a corrupt workbook

I want to copy an Excel Workbook with apache poi. The copy must be protected but the user should be able to resize the columns. I prepared a template and picked "columns format" on the first sheet in the template. When I use the following snippet
InputStream is = new FileInputStream(
new File(DIR, "template.xlsx"));
XSSFWorkbook wb = (XSSFWorkbook) WorkbookFactory.create(is);
XSSFSheet s = wb.getSheetAt(0);
s.protectSheet("");
FileOutputStream os = new FileOutputStream(new File(DIR, "test.xlsx"));
wb.write(os);
os.close();
I get a corrupt Excelsheet. I use apache poi 3.8 and Excel 2007.
Is there a workaround for protecting the sheets but allow to resize the columns?
Any help would be greatly appreciated
stephan
I know this is an old post, but I just solved this problem. You can use the following code:
//just initialize these
XSSFWorkbook xwb;
XSSFSheet xsheet;
xsheet.protectSheet("1234");
xsheet.getCTWorksheet().getSheetProtection().setFormatColumns(false);
xsheet.enableLocking();
xwb.lockStructure();
Hope this helps somebody in the future! :D

Resources