Error while creating read only .xlsx file using Apache POI - java

I am trying to create one read only Excel-sheet using Apache POI 3.10.
private void lockAll(Sheet s, String password) throws Exception{
XSSFSheet sheet = ((XSSFSheet)s);
sheet.protectSheet(password);
sheet.enableLocking();
sheet.lockSelectLockedCells();
sheet.lockSelectUnlockedCells();
}
Now I am calling this method after creating my excel sheet using following.
private String generateExcel(List<Model> DataList) {
Workbook wwbook = null;
File ff = null;
try {
String filePath = // getting this path using ServletContext.
wwbook = new XSSFWorkbook();
Sheet wsheet = wwbook.createSheet("MyReport");
ApachePoiExcelFormat xlsxExcelFormat = new ApachePoiExcelFormat();
CellStyle sheetHeading = xlsxExcelFormat.SheetHeading(wwbook);
//My personal org.apache.poi.ss.usermodel.CellStyle here.
short col = 0, row = 0;
XSSFRow hrow = (XSSFRow) (XSSFRow) wsheet.createRow(row);
XSSFCell cell = hrow.createCell(col);
//My code here to iterate List and add data to cell.
FileOutputStream fileOut = new FileOutputStream(filePath.toString());
wwbook.write(fileOut);
lockAll(wsheet, "password"); //******calling the method to lock my sheet.
fileOut.close();
System.out.println("Excel Created");
} catch (Exception e) {
e.printStackTrace();
} finally {
}
return filePath;
}
Now while I am running this code to download the excel file. Then I am getting error on the webpage but not on my eclipse console.
Next I was trying to run the same code after commenting the following line in lockAll method. And then the excel downloading happens as required, but every cells in the sheet are editable.
sheet.protectSheet(password);

Related

Writing list of data in excel file using JAVA is entering the data only in the last column

I am iterating through a list of data which I am sending from the runner file(FunctionVerifier.java).
When I am calling the function writeExcel() in excelHandler.java it is entering only the last data from the list that I am iterating through.
Can someone please let me know the reason and how to fix this
public void writeExcel(String sheetName, int r, int c, String data) throws IOException {
file = new FileInputStream(new File(inFilePath));
wb = new XSSFWorkbook(file);
Sheet sh;
sh = wb.getSheet(sheetName);
Row row = sh.createRow(r);
row.createCell(c).setCellValue(data);
closeExcelInstance();
FileOutputStream outputStream = new FileOutputStream(inFilePath);
wb.write(outputStream);
wb.close();
outputStream.close();
}
public void closeExcelInstance() {
try {
file.close();
} catch (Exception e) {
System.out.println(e);
}
}
FunctionVerifier.java
package Sterling.oms;
import Sterling.oms.Process.CouponValidationProcess;
import Sterling.oms.Utilities.ExcelHandler;
import java.util.ArrayList;
public class FuncVerify {
public static void main(String args[]) throws Exception {
String filePath = System.getProperty("user.dir") + "/src/test/resources/TestData/test.xlsx";
ExcelHandler excelHandler = new ExcelHandler(filePath);
excelHandler.readExcelData("Validation");
CouponValidationProcess couponValidationProcess = new CouponValidationProcess("OMS-T781");
excelHandler.createSheet();
// couponValidationProcess.enterValidationHeaderRowInExcel(filePath);
String sheet = "ValidationData";
if (excelHandler.getRowCountWhenNull(sheet) < 1) {
ArrayList<String> header = new ArrayList<>();
header.add("Test Case");
header.add("Coupon ID");
header.add("Grand Total");
header.add("Manual Grand Total");
for (int i = 0; i < header.size(); i++) {
// excelHandler = new ExcelHandler(filePath);
excelHandler.writeExcel(sheet, 0, i, header.get(i));
// excelHandler.closeExcelInstance();
}
}
}
}
The reason for only storing the last item is that Sheet.createRow as well as Row.createCell are doing exactly what their method names tell. They create a new empty row or cell each time they get called. So every times Row row = sh.createRow(r) gets called, it creates a new empty row at row index r and looses all former created cells in that row.
The correct way to use rows would be first trying to get the row from the sheet. And only if it is not present (null), then create a new row. The same is for cells in rows. First try to get them. And only if not present, then create them.
...
Sheet sh;
sh = wb.getSheet(sheetName);
Row row = sh.getRow(r); if (row == null) row = sh.createRow(r);
Cell cell = row.getCell(c); if (cell == null) cell = row.createCell(c);
cell.setCellValue(data);
...
That's the answer to your current question.
But the whole approach, to open the Excel file to create a Workbook, then set data of only one cell in and then write the whole workbook out to the file, and doing this for each cell, is very sub optimal. Instead the workbook should be opened, then all known new cell values should be set into the sheet and then the workbook should be written out.
Your approach is wrong, you open your files again for each line you want to write to Excel, then save again. You just have to create one FileInputStream and send it to your Workbook where you do all your Excel work. After you have finished writing all your lines, you can create only one FileOutputStream and export your changes in your Workbook to a file of your choice.
writeExcel()
public void writeExcel(String sheetName, int r, int c, ArrayList<String> data) throws IOException {
file = new FileInputStream(new File(inFilePath));
wb = new XSSFWorkbook(file);
Sheet sh;
sh = wb.getSheet(sheetName);
Row row = sh.createRow(r);
//Adding data column wise
for (String h : data) {
row.createCell(c++).setCellValue(h);
}
closeExcelInstance();
FileOutputStream outputStream = new FileOutputStream(inFilePath);
wb.write(outputStream);
wb.close();
outputStream.close();
}

How do i create a multiple sheets in same workbook on base of dropdown selection using Apache POI?

I have to select the option one after another from dropdown say (AAA,BBB... GGG) and after selection whatever the data populate have to be written on excel. Here method clickOnPerfomanceDetails() contains the code to write it down onto Excel. My following code is writing successfully onto excel with different sheets but manually i comment other options. In all 7 times i am executing the script to get data into 7 different worksheet.
public void clickOnPerformanceDetails() throws Exception {
File file = new File("C:\\Users\\dp\\Desktop\\Performance.xlsx");
XSSFWorkbook wb = (XSSFWorkbook) WorkbookFactory.create(new FileInputStream(file));
XSSFSheet sheet = wb.createSheet("AAA");
//XSSFSheet sheet = wb.createSheet("BBB");
//XSSFSheet sheet = wb.createSheet("CCC");
// XSSFSheet sheet = wb.createSheet("DDD");
//CODE
FileOutputStream fos = new FileOutputStream("C:\\Users\\dp\\Desktop\\Performance.xlsx");
wb.write(fos);
fos.close();
}
#Test()
public void providerTest1() throws Exception {
performance_PlusTWO.hoverTest();
performance_PlusTWO.clickOnHieararchyDropDown();
performance_PlusTWO.selectOptionNais();
//AAA
performance_PlusTWO.selectAAAOption();
performancePlus_TWO.clickOnPerformanceDetails();
//BBB
//performance_PlusTWO.selectBBBOption();
//performanceP_TWO.clickOnPerformanceDetails();
//CCC
performance_PlusTWO.selectAAAOption();
performance_TWO.clickOnPerformanceDets();
}
Creating 'AAA' worksheet and running Test for performance_PlusTWO.selectAAAOption();
performancePlus_TWO.clickOnPerformanceDetails(); Then manually i comment 'AAA' option, uncomment 'BBB' option and again execute the script. How do on a single click i execute the data for all the options.
Any help will be appreciated.
Try the below approach.
public void WriteToExcelSheet(String SheetName) throws Exception {
File file = new File("C:\\Users\\dp\\Desktop\\Performance.xlsx");
XSSFWorkbook wb = (XSSFWorkbook) WorkbookFactory.create(new FileInputStream(file));
XSSFSheet sheet = wb.createSheet(SheetName);
//CODE
FileOutputStream fos = new FileOutputStream("C:\\Users\\dp\\Desktop\\Performance.xlsx");
wb.write(fos);
fos.close();
}
#Test()
public void providerTest1() throws Exception {
Select dropdown = new Select(driver.findElement(By.id("id")));
//Get all options
List<WebElement> dropdown_items = dropdown.getOptions();
//print the number of dropdown items
System.out.println(dropdown_items.size());
// Loop through all items one by one
for (int itemIndex = 0; j < dd.size(); j++) {
String option = dropdown_items.get(itemIndex).getText();
//print the sheet name
System.out.println(option);
// write the logic to select the option <=== don't forget to implement this
// logic to call function with sheet name
performance_TWO.WriteToExcelSheet(option);
}
}

Is there a way to copy/duplicate excel files with java?

I am trying to write a program where I have to either
create an exel file and insert a table (and eventually data) into it, OR
duplicate a template exel file that I have made, and copy that over to a new directory to use.
I have gotten the 'duplicate' part working, but I cannot open the duplicated file (It says the file format/extension is not valid).
This is the code:
try {
var template = new RandomAccessFile(App.NAME+".xlsx", "rw");
var copy = new RandomAccessFile(App.data.getFilePath()+App.NAME+".xlsx", "rw");
var sourceChannel = template.getChannel();
var destinationChannel = copy.getChannel();
destinationChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
System.out.println("Successfully created exel file");
} catch (IOException e) {
System.err.println("Error creating exel file: " + e.getMessage());
}
Does anyone know what I should do to fix this?
Thanks in advance.
The following example creates an Excel File named example.xls. The file has a table with two columns ( name, job ) and one row (bayrem, developer).
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Persons");
sheet.setColumnWidth(0, 6000); //style
sheet.setColumnWidth(1, 4000);//style
Row header = sheet.createRow(0);
CellStyle headerStyle = workbook.createCellStyle();//style
headerStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());//style
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);//style
XSSFFont font = ((XSSFWorkbook) workbook).createFont();//style
font.setFontName("Arial");//style
font.setFontHeightInPoints((short) 16);//style
font.setBold(true);//style
headerStyle.setFont(font);//style
Cell headerCell = header.createCell(0);
headerCell.setCellValue("Name");
headerCell.setCellStyle(headerStyle);//style
headerCell = header.createCell(1);
headerCell.setCellValue("Job");
headerCell.setCellStyle(headerStyle);//style
CellStyle style = workbook.createCellStyle();//style
style.setWrapText(true);//style
Row row = sheet.createRow(2);
Cell cell = row.createCell(0);
cell.setCellValue("Bayrem");
cell.setCellStyle(style);//style
cell = row.createCell(1);
cell.setCellValue("Developer");
cell.setCellStyle(style);//style
File currDir = new File(".");
String path = currDir.getAbsolutePath();
String fileLocation = path.substring(0, path.length() - 1) + "example.xlsx";
FileOutputStream outputStream = new FileOutputStream(fileLocation);
workbook.write(outputStream);
workbook.close();
This is all you need for a copy, the language level has to be 7 or higher
import java.io.IOException;
import java.nio.file.*;
public class ExcelCopy {
public static void main(String[] args) {
FileSystem system = FileSystems.getDefault();
Path original = system.getPath("C:\\etc\\etc\\Desktop\\ExcelTestOne.xlsx");
Path target = system.getPath("C:\\etc\\etc\\Desktop\\ExcelCopy.xlsx");
try {
// Throws an exception if the original file is not found.
Files.copy(original, target, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
System.out.println("ERROR");
}
}
}
original post is here,I check that it worked for you.
How to copy excel file?

Create .csv file with Apache POI doesn't work

I need to create a file .csv with apache-poi but this file is empty. For this example I want to create only header about this file so I do:
public byte[]...(File save_file) {
Workbook workbook = null;
Sheet sheet = null;
FileOutputStream outputStream=null;
try {
workbook = new HSSFWorkbook();
sheet = workbook.createSheet();
createHeader(0,sheet);
outputStream = new FileOutputStream(save_file);
workbook.write(outputStream);
} catch (Exception exception) {
log.error("ERROR", exception);
} finally {
}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byteArrayOutputStream.writeTo(outputStream);
log.info("SOTTO BYTE "+byteArrayOutputStream.toByteArray().length);
return byteArrayOutputStream.toByteArray();
}
and after the method "create_header":
private static void createHeader(int rowPosition,Sheet sheet) {
Row row = sheet.createRow(rowPosition);
Cell cell = row.createCell(1);
cell.setCellValue("DATE");
cell = row.createCell(2);
cell.setCellValue("EMAIL");
}
The problem is the file is empty. In the first method I need to return the byte[] that represents the csv file. Anyone can help me?

Editing a Excel template with POI in Netbeans

I have a Excel template wich I want to open, modify and save it like a normal book of excel when I click in a button in a Jframe.
This is the code:
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
InputStream inp;
try {
inp = new FileInputStream("plantilla.xlt");
XSSFWorkbook wb = new XSSFWorkbook(inp);
XSSFSheet sheet = (XSSFSheet) wb.getSheetAt(1);
XSSFRow row = sheet.getRow(3);
XSSFCell cell1 = row.getCell(1);
XSSFCell cell2 = row.getCell(2);
cell1.setCellValue(0);
cell2.setCellValue(10000);
//FileOutputStream fileOut = new FileOutputStream("plantilla.xlt");
//wb.write(fileOut);
//fileOut.close();
} catch (IOException ioe) {
Logger.getLogger(DonnéesFE.class.getName()).log(Level.SEVERE, null,ioe);
}
}
This is new for me so I have a couple questions:
I have to put the whole file path to get the FileInputStream? Is the extension .xlt correct? Right now it doesn't find the file. I have tried with the normal .xlsx extension and it finds it (I don't think it found the good file either) but I get this error on the definition of the workbook that I don't understand:
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/apache/xmlbeans/XmlException.`
When I finish editing the excel template how I save it as a new excel book? Everybody uses a new file to save the output but I think that won't work here.

Categories