Appending sheet to existing excel file using Java and Apache POI - java

I have a Java method writeToExcel(String sheetName, Map), which creates a new sheet with name 'sheetName' in a new excel file and write the map data into it . When I call the method with different sheetName arguments more than once, existing sheet gets replaced by the last called one. I want to create new sheets in the same excel file each time whenever the method is called with different sheetName argument, without losing existing sheets. Here is my code.
public static void writeToExcel(String fileName,Map<Integer,String[]> excelData){
String filePath="/Data/excel.xlsx";
XSSFWorkbook workbook=new XSSFWorkbook();
XSSFSheet sheet=workbook.createSheet(fileName);
Set<Integer> keySet=excelData.keySet();
int passedCount=0;
int failedCount=0;
int rowNo=0;
int cellNo=0;
Row row;
Cell cell;
try{
File file=new File(filePath);
FileOutputStream output=new FileOutputStream(file);
for(Integer key:keySet){
row=sheet.createRow(rowNo++);
String[] dataToWrite=excelData.get(key);
cellNo=0;
for(String str:dataToWrite){
cell=row.createCell(cellNo++);
cell.setCellValue(str);
}
}
workbook.write(output);
output.close();
workbook.close();
}
catch(FileNotFoundException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
}

Seems like you're always creating a new workbook in the second line of the method. So it is not the sheet that is replaced but the entire workbook. Better use
XSSFWorkbook workbook=new XSSFWorkbook(new File(filePath));
That should do the trick.

XSSFWorkbook workbook=new XSSFWorkbook(new File(filePath)); => XSSFWorkbook workbook=new XSSFWorkbook(filePath); as no suit constructor for XSSFWorkbook workbook=new XSSFWorkbook(new File(filePath))

Related

How to write on another sheet in excel Java use POI

I would like to write to a cell on sheet 2, but the operation errors and I get this message :
Exception in thread "main" java.lang.NullPointerException
at Testnextsheet.Testnextsheet.main(Testnextsheet.java:43)
public static void main(String[] args) throws IOException{
try{
FileInputStream files = new FileInputStream(new File("d:\\Materi\\Selenium\\Projects\\Excel\\Book1.xlsx"));
XSSFWorkbook workbook = new XSSFWorkbook(files);
//----Sheet 1-------------------------------------//
XSSFSheet sheet1 = workbook.getSheet("Sheet1");
//---sheet 2--------------------------------------//
XSSFSheet sheet2 = workbook.getSheet("Sheet2");
//-----------write text to sheet 2------------------------//
sheet2.getRow(3).getCell(2).setCellValue("Test");
FileOutputStream fout= new FileOutputStream(new File("d:\\Materi\\Selenium\\Projects\\Excel\\Book1.xlsx"));
workbook.write(fout);
workbook.close();
files.close();
}
catch(FileNotFoundException fnfe){
fnfe.printStackTrace();
}catch(IOException ioe){
ioe.printStackTrace();
}
}
The sheet2 object,which is a TreeMap is empty in the beginning.You need to create a row, then cell and then set the value, something like below-
sheet2.createRow(2).createCell(1).setCellValue("Test");
In your case,sheet2.getRow(3) will throw NullPointerException.
The suggested way would be to iterate the XSSFWorkbook object to access the XSSFSheet and then create as many row and cell as you want and keep on setting the values.

Creating new sheet using Apache POI removes all the existing sheets

I trying to add new sheet to an existing excel file using Apache poi library as in the below code.
FileOutputStream fileOut = new FileOutputStream(new File(BASE_PATH+outputFile));
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet("Splitted Rules");
Set<String> tags = outputRules.keySet();
int i = 0;
for (String tag : tags) {
List<String> rules = outputRules.get(tag);
for (String rule : rules) {
Row row = sheet.createRow(i++);
row.createCell(0).setCellValue(tag);
row.createCell(1).setCellValue(rule);
}
}
wb.write(fileOut);
fileOut.close();
wb.close();`
The problem is that all the sheets in the file is deleted and only the new sheets exist.
What is this problem ?
The comments already hint at the solution.
The code above creates a new workbook and overwrites any existing file.
If you want to append a sheet to an existing workbook use the WorkbookFactory.create method (or the XSSFWorkbook constructors with the appropriate argument) to create the workbook based on the existing excel file.

Generic Way of Creating workbook Apache POI

I have a method that reads an excel sheet using Apache POI library. To make that method generic, I need to to write some code in a catch block. Here's the method:
private List<String[]> readFile(String filePath) throws IOException{
List<String[]> sheetValues = new ArrayList<String[]>();
//Two types of fileInputStreams for both the types of workbook i am about to use
//
FileInputStream fileInputStream = new FileInputStream(new File(filePath));
FileInputStream fileInputStream2 = new FileInputStream(new File(filePath));
LineItemFileReader fileReader = new LineItemFileReaderImpl();
//If the file is in xls format i should use HSSFWorkbook
//If the file is in xlsx format i should use XSSFWorkbook
try {
//If the file is in xlsx format then the below line will throw the
//Exception and catch block code will be executed
HSSFWorkbook workbook = new HSSFWorkbook(fileInputStream);
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
sheetValues = fileReader.ParseSheet(workbook.getSheetAt(1),evaluator);
} catch (OfficeXmlFileException exception){
XSSFWorkbook workbook = new XSSFWorkbook(fileInputStream2);
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
sheetValues = fileReader.ParseSheet(workbook.getSheetAt(1),evaluator);
} finally{
fileInputStream.close();
fileInputStream2.close();
}
return sheetValues;
}
So what's happening here is that I dont know what type of file I am being supplied. I am deciding that on the basis of the try/catch block given above. So is there any generic way of deciding which workbook to use? Since the above code has flow control logic written in a catch block, it's a bad practice.
Use WorkbookFactory.create(...) for opening the Workbook. It will create the appropriate subclass internally:
Workbook workbook = WorkbookFactory.create(new File(filePath));
// ...
workbook.close();

Delete an excel sheet using Apache POI

I have to delete a sheet from the Excel file.
Here's my code snippet :
FileInputStream fileStream = new FileInputStream(destFile);
POIFSFileSystem fsPoi = new POIFSFileSystem(fileStream);
HSSFWorkbook workbook = new HSSFWorkbook(fsPoi);
int index = 0;
HSSFSheet sheet = workbook.getSheet("Setup");
if(sheet != null) {
index = workbook.getSheetIndex(sheet);
workbook.removeSheetAt(index);
}
return destFile;
After this I'm getting exactly the same workbook which I passed, without the removal of the sheet "Setup"
Help me resolve this. Any help would be appreciated
After editing your workbook, you need to write it again. Try this:-
FileOutputStream output = new FileOutputStream(destFile);
workbook.write(output);
output.close();
Edit:- After writing it back, you can return your destFile.
private void removeOtherSheets(String sheetName, XSSFWorkbook book) {
for(int i=book.getNumberOfSheets()-1;i>=0;i--){
XSSFSheet tmpSheet =book.getSheetAt(i);
if(!tmpSheet.getSheetName().equals(sheetName)){
book.removeSheetAt(i);
}
}
}
Delete a sheet using Apache POI
//Open file
FileInputStream inputStream = new FileInputStream(new File(filePath));
XSSFWorkbook workBook = new XSSFWorkbook(inputStream);
//Delete Sheet
workBook.removeSheetAt(resultWorkbook.getSheetIndex("SheetToBeDeleted"));
//Save the file
FileOutputStream outFile =new FileOutputStream(new File(filePath));
workBook.write(filePath);
outFile.close();

Java POI Create new Workbook with SS model?

I'm a little confused, I used to do this:
HSSFWorkbook wb = new HFFSWorkbook();
But with the new POI, I dont have to do that.
I can't do this:
Workbook wb = new Workbook();
I understand WorkbookFactory.create, but that is for opening a file.
How do I set up a new workbook with this ss model?
You can still use the SS model but need to decide on the file format at the time of creation.
For xls -> Workbook wb = new HSSFWorkbook();
For xlsx -> Workbook wb = new XSSFWorkbook();
In "New POI", you can write/read both XLS files and XLSX files. In any case, for XLS file-format you were using:
HSSFWorkbook wb = new HSSFWorkbook();
So for XLSX file-format, you have to use:
XSSFWorkbook wb = new XSSFWorkbook();
// you could also do below
// Workbook wb = new XSSFWorkbook();
Also it would be helpful for you if you refer below links for starting with XLS to XLSX migration.
1. http://poi.apache.org/apidocs/org/apache/poi/xssf/usermodel/XSSFWorkbook.html
2. http://poi.apache.org/spreadsheet/converting.html
Make sure you download and add the POI JAR file to your project’s class path before running the code. The Apache POI JAR file can be found here.
public void main(String[] args) throws IOException {
// Directory path where the xls file will be created
String destinationFilePath = "C:/Users/devesh_/Documents/HelloWorld.xls";
// Create object of FileOutputStream
FileOutputStream fout = new FileOutputStream(destinationFilePath);
// Build the Excel File
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
HSSFWorkbook workBook = new HSSFWorkbook();
// Create the spreadsheet
HSSFSheet spreadSheet = workBook.createSheet("Hello_World");
// Create the first row
HSSFRow row = spreadSheet.createRow((short) 0);
// Create the cells and write to the file
HSSFCell cell;
// Write Hello
cell = row.createCell(0);
cell.setCellValue(new HSSFRichTextString("Hello"));
// Write World
cell = row.createCell(1);
cell.setCellValue(new HSSFRichTextString("World"));
workBook.write(outputStream);
outputStream.writeTo(fout);
outputStream.close();
fout.close();
}
When creating a file, you need to decide up front what format it'll be - you can't just wait until write-out time to do that. You code would be something like:
Workbook wb = null;
if (shouldBeXLS) {
wb = new HSSFWorkbook();
} else {
wb = new XSSFWorkbook();
}
// work on the file in a generic way
// save, with a suitable name
String filename = "test.xls";
if (!shouldBeXLS) { filename = filename + "x"; }
FileOutputStream fout = new FileOutputStream(filename);
wb.write(fout);
fout.close();
At the start, decide what format you want for this particular instance, and create that. Treat it as a general workbook, and write to it in the common way. At the end, remember what it is so you can give the file the right extension!
(When reading a file in, WorkbookFactory will let you load the appropriate instance for the file type. When creating a new file, you have to pick yourself as there's nothing there yet!)

Categories