not able to update the excel data - it overwrites the actual data - java

I have a code which writes to the excel file using apache poi api. The problem is it everytime writes the new data to the file and not append the data. can you please help me here. Here is my code.
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class ExcelWrite {
public static void write(AddExcel addExcel){
try {
XSSFWorkbook workbook = new XSSFWorkbook("NG.xlsx");
XSSFSheet worksheet = workbook.createSheet("Scrap Data");
int lastRow = worksheet.getLastRowNum();
System.out.println(lastRow);
Row row = worksheet.createRow(++lastRow);
row.createCell(2).setCellValue(addExcel.getArtistName());
row.createCell(3).setCellValue(addExcel.getItemName());
row.createCell(6).setCellValue(addExcel.getOriginalPrimaryMarket());
row.createCell(7).setCellValue(addExcel.getAvgResalePrice());
row.createCell(8).setCellValue(addExcel.getPriceChangedFromPrimaryMarket());
row.createCell(9).setCellValue(addExcel.getHighestAvgBid());
row.createCell(10).setCellValue(addExcel.getLastSoldPrice());
row.createCell(11).setCellValue(addExcel.getSecondayMarketVolume());
row.createCell(12).setCellValue(addExcel.getSecondarySales());
row.createCell(13).setCellValue(addExcel.getPrimarySales());
row.createCell(14).setCellValue(addExcel.getDateCreated());
row.createCell(16).setCellValue(addExcel.getInstagramURl());
row.createCell(17).setCellValue(addExcel.getTwitterURL());
FileOutputStream out = new FileOutputStream(new File("NG.xlsx"));
workbook.write(out);
out.close();
System.out.println("Write Successfully.");
}
catch(IOException io){
System.out.println(io.getMessage());
System.out.println(io.getStackTrace());
}
}
}

The problem is that each time you run your code, you always create a brand new XSSFWorkbook and so a brand new excel file, deleting and overriding the existing one.
It doesn't matters you're calling worksheet.getLastRowNum(); it will always return -1 because your XSSFWorkbook will always be empty.
If you want to update an existing excel file (appending new rows to it), you MUST create your XSSFWorkbook by loading that existing excel file. You're code is broken because with the line
workbook = new XSSFWorkbook();
you're creating a brand new XSSFWorkbook which is totally unrelated to the excel file you want to update. You HAVE TO use instead:
Workbook workbook = WorkbookFactory.create(new FileInputStream(toUpdateExcelFilePath));
You might want to have a look at this post for more details: how to update an existing excel file in Java.

According to my test (I used 4.1.2 version from maven repository) when you use createSheet it produce an exception:
java.lang.IllegalArgumentException: The workbook already contains a sheet named 'Scrap Data'
With the getSheet() method you can grab the existing sheet. If it does not exist you will be get a null then you can create a new sheet with the required name.
XSSFWorkbook workbook;
try {
File file = new File("NG.xlsx");
workbook = new XSSFWorkbook();
if(file.exists()) {
FileInputStream fs = new FileInputStream(file);
workbook = new XSSFWorkbook(fs);
}
String sheetName = "Scrap Data";
XSSFSheet worksheet = workbook.getSheet(sheetName);
if(worksheet == null) {
worksheet = workbook.createSheet(sheetName);
}
... //other code unchanged
} catch(Exception io){
io.printStackTrace();
}
NOTE: I changed the file reading code a little bit because I got errors and the documentation says the following:
* Note - if the Document was opened from a {#link File} rather
* than an {#link InputStream}, you <b>must</b> write out to
* a different file, overwriting via an OutputStream isn't possible.

Related

Java Writing Data to Excel - WorkbookFactory

I am trying to add some data to, already existing file which I created with; copyFileNIO(fromFile, toFile) method. To add data to already existing file I am using this code block:
try {
copyFileNIO(fromFile, toFile);
System.out.println("Copy file is done.");
// Creating file object of existing excel file
File xlsxFile = new File(toFile);
System.out.println("ok");
// Creating input stream
InputStream inputStream = new FileInputStream(xlsxFile);
System.out.println("okkk");
// Creating workbook from input stream
Workbook wb = WorkbookFactory.create(inputStream);
System.out.println("okkkk");
// Reading first sheet of excel file
Sheet sheet = wb.getSheetAt(0);
// Getting age cell of first row from the sheet
Cell cell = sheet.getRow(1).getCell(3);
// Updating the cell value with new data
cell.setCellValue(30);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Copy file is done.");
}
However, Workbook is giving error, I tried also XSSF its not working. I do not know what causes this. You can see ambda$7 exception:
at application.Sbt.lambda$7(Sbt.java:492) -> which leads Workbook wb = WorkbookFactory.create(inputStream);
I added some System.out.println as can seen on code: output of these methods are
Copy file is done.
ok
okkk
Exception ...
How can i solve this problem ? Thank you
I confirmed my file exists and patch is correct. Changed inputstream and workbook to -> Workbook wb = WorkbookFactory.create(new File(toFile)); Still same error
full error message and stack trace
at org.apache.poi.poifs.filesystem.FileMagic.valueOf(FileMagic.java:177)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:309)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:277)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:255)
at application.Sbt.lambda$7(Sbt.java:491)
Apache POI -> 5.2.3

getPivotCacheDefinition return null value when Refresh Pivot Table with Apache POI

I want to refresh pivot table after enter data to data sheet
I read two previous questions [this][1] and [this][2]. there two way to do this
one way is
Right click your pivot table -> pivotTable Options -> Data -> Check Refresh Data when opening File
this is working I want a automated way so I tried in this way
FileInputStream inputStream = new FileInputStream(new File(excelFilePath));
workbook = new XSSFWorkbook(inputStream);
XSSFSheet sheet = workbook.getSheet("Summary");
XSSFPivotTable pivotTable = sheet.getPivotTables().get(0);
pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().setRefreshOnLoad(true);
I have two pivot tables in this sheet so sheet.getPrivotTable return this
[Name: /xl/pivotTables/pivotTable1.xml - Content Type: application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml, Name: /xl/pivotTables/pivotTable2.xml - Content Type: application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml]
but sheet.getPivotTables().get(0).getPivotCacheDefinition() return null value.
Is there any way to refresh Pivot table automatically?
You are correct, the XSSFPivotTable.getPivotCacheDefinition() does not work properly when XSSFPivotTable was read from an existing *.xlsx file. This is because of the kind how the XSSFPivotTable is got form the file. See XSSFSheet.read: The XSSFPivotTable is read from the related document parts of the sheet. But the XSSFPivotTable has relations of it's own. But those are not read at all.
You could file a bug report to apache poi about this.
Workaround: The XSSFPivotTable extends POIXMLDocumentPart and so it knows about it's own related document parts where the XSSFPivotCacheDefinition is one of.
Example:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import java.io.FileInputStream;
class ExcelReadPivotTables {
public static void main(String[] args) throws Exception{
XSSFWorkbook workbook = (XSSFWorkbook)WorkbookFactory.create(new FileInputStream("ExcelWorkbook.xlsx"));
XSSFSheet sheet = workbook.getSheet("Summary");
System.out.println(sheet.getPivotTables());
if (sheet.getPivotTables().size() > 0) {
XSSFPivotTable pivotTable = sheet.getPivotTables().get(0);
System.out.println(pivotTable);
XSSFPivotCache pivotCache = pivotTable.getPivotCache();
System.out.println(pivotCache); // null!
XSSFPivotCacheDefinition pivotCacheDefinition = pivotTable.getPivotCacheDefinition();
System.out.println(pivotCacheDefinition); //null!
for (org.apache.poi.ooxml.POIXMLDocumentPart documentPart : pivotTable.getRelations()) {
if (documentPart instanceof XSSFPivotCacheDefinition) {
pivotCacheDefinition = (XSSFPivotCacheDefinition)documentPart;
System.out.println(pivotCacheDefinition); //not null!
}
}
}
workbook.close();
}
}

Java POI the supplied data appears to be in the Office 2007+ XML

I am getting this error:
org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (e.g. XSSF instead of HSSF)
I read throw Google and I found out that I need to use XSSF instead of HSSF because my Excel file is xlsx, but as you see in my maven, I am already using xlsx. Where have I gone wrong please?
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.13-beta1</version>
</dependency>
The code the makes the exception is:
POIFSFileSystem fs;
fs = new POIFSFileSystem(new FileInputStream(getFilePath()));
My new code
public void getBColum() {
try {
OPCPackage fs;
fs = new OPCPackage.open(new File(getFilePath()));
XSSFWorkbook wb = new XSSFWorkbook(fs);
XSSFSheet sheet = wb.getSheet("Master column name - Used Car");
XSSFRow row;
CellReference cr = new CellReference("A1");
row = sheet.getRow(cr.getCol());
System.out.println(row.getCell(3));
} catch (FileNotFoundException e) {
if (logger.isDebugEnabled()) {
logger.debug("How can this error be possible? we should have already thrown an exception in the construction");
}
} catch (IOException e) {
logger.error(String.format("Exception in reading the file: %s",
e.getMessage()));
}
}
I have a compile error in new oPCPackage.open which is:
OPCPackage.open cannot be resolved to a type
According to the Apache POI Quick Guide, the POIFSFileSystem (or similarly, NPOIFSFileSystem) is only used with .xls (Excel versions through 2003) documents.
The equivalent for .xlsx documents (Excel 2007+) is OPCPackage.
OPCPackage pkg = OPCPackage.open(new File("file.xlsx"));
You can create an XSSFWorkbook from the OPCPackage:
XSSFWorkbook wb = new XSSFWorkbook(pkg);
Or you can just create it directly:
XSSFWorkbook wb = new XSSFWorkbook(new File("file.xlsx"));
Generally it's better to create the workbook using a File instead of an InputStream, to save memory.
Also, if you want code that doesn't care whether it's an .xls or an .xlsx:
// or "file.xlsx"
Workbook wb = WorkbookFactory.create(new File("MyExcel.xls"));
I was using XSSF with a xlsx file, but got this error when I tried to process a file that was encrypted/protected with a password.
Once I removed the password, everything worked as expected.
well actually there is no OPCPackage,
I am using https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml/3.5-beta5
so you have to:
import org.apache.poi.openxml4j.opc.Package;
....
Package fs = Package.open(new ByteArrayInputStream(container.getContent()));
XSSFWorkbook wb = new XSSFWorkbook(fs);
XSSFSheet sheet = wb.getSheetAt(0);
XSSFRow row;
XSSFCell cell;

Null pointer exception while using Apache POI

I am trying to write a excel file using Apache POI package. Here is the code snippet:
String basePath = "/home/aman/Desktop";
String fileName = "result.xls";
File file = new File(basePath, fileName); //File not null. checked.
OPCPackage pkg = OPCPackage.openOrCreate(file); //pkg not null. checked.
Workbook wb = new XSSFWorkbook(pkg); //GenerateReport.java:63
I get the following error:
Exception in thread "main" java.lang.NullPointerException
at org.apache.poi.POIXMLDocumentPart.read(POIXMLDocumentPart.java:382)
at org.apache.poi.POIXMLDocument.load(POIXMLDocument.java:155)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:186)
at amazon.category.database.GenerateReport.generateExcel(GenerateReport.java:63)
at amazon.category.database.MerchantAdoptionStats.processAdoptionStats(MerchantAdoptionStats.java:197)
at amazon.category.database.MerchantAdoptionStats.main(MerchantAdoptionStats.java:386)
Any help appreciated.
I found this example at the tutorial site:
here
You could try this approach.
Workbook wb = new HSSFWorkbook();
//Workbook wb = new XSSFWorkbook();
CreationHelper createHelper = wb.getCreationHelper();
Sheet sheet = wb.createSheet("new sheet");
// Create a row and put some cells in it. Rows are 0 based.
Row row = sheet.createRow((short)0);
// Create a cell and put a value in it.
Cell cell = row.createCell(0);
cell.setCellValue(1);
// Or do it on one line.
row.createCell(1).setCellValue(1.2);
row.createCell(2).setCellValue(createHelper.createRichTextString("This is a string"));
row.createCell(3).setCellValue(true);
// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();
I hit my head against this one for a while myself. The trick is whether or not the file exists prior.
//if file is .xls
Workbook workbook;
if(file.exists) {
NPOIFSFileSystem fs = new NPOIFSFileSystem(file);
workbook = new HSSFWorkbook(fs.getRoot(), false);
}
else {
workbook = new HSSFWorkbook();
}
//if file is .xlsx
Workbook workbook;
if(file.exists) {
OPCPackage pkg = OPCPackage.open(file);
workbook = new XSSFWorkbook(pkg);
}
else {
workbook = new XSSFWorkbook();
}
The trick appears to be (and this doesn't look like it is documented well), that you create the workbooks off of the file system or package objects only if the file exists prior. If you want a new file, then don't use the file system or package objects to create your workbooks.
If everything is what it looks like, you should not be able to build an XSSFWorkbook on an .xls file, since it is a class to model .xlsx files. You should use WorkbookFactory.create() instead of that, which is a factory method that will return the appropiate Workbook implementation for each case

append data into xlsx file through java

I am using Apache POI for writing into .xlsx file. I can write into .xlsx file but I am unable to append new content. How can I append new content in the .xlsx file?
My Code is:
public static void write(){
try {
Workbook[] wbs = new Workbook[]{new XSSFWorkbook()};
Workbook workbook=wbs[0];
org.apache.poi.ss.usermodel.Sheet sheet = workbook.createSheet();
System.out.println(sheet.getSheetName());
Row row = sheet.createRow(2);
for(int i=0;i<10;i++){
Cell cell=row.createCell(i);
cell.setCellValue("Sun System");
}
FileOutputStream fout=new FileOutputStream("D:/Test.Xlsx");
workbook.write(fout);
fout.close();
} catch (Exception e) {
}
}
The first thing U've to do :
When you're working with Excel 2007 format, its more wise to use XSSF-Implementations, because you've used abstract implementations. Always remember this when using any implementation.
To append to an existing file you need to reach the end of the rows in that particular workbook sheet. This can be achieved by:
int rows = sheet.getPhysicalNumberOfRows(); // or sheet.getLastRowNum();
After that you can create new cells with the XSSF- Implementation classes. For more information refer to this page
You should open the existing file instead of creating a new one if you want to append, see also this stackoverflow question:
Edit existing excel files using jxl api / Apache POI
You are creating a new workbook each time this is run youd want to create a FileInputStream with a file path to the excel file and then use that input stream to get the XSSF workbook you want to edit
FileInputStream fis = new FileInputStream(filePath);
XSSFWorkbook workBook = new XSSFWorkbook(fis);
then in order to get a specific sheet you simply just use the .getSheet or getSheetAt methods that are apart of workBook. then create and set cells

Categories

Resources