I am using Apache POI to create an excel file with the help of database. I tried searching a lot with different codes and all I got was corrupted excel sheet over and over again. As of now, here is the code which I am using:
public void generateExcel(ResultSet rs, String excelFilename, String newDesc){
try {
Workbook wb = new XSSFWorkbook();
Cell c = null;
//Cell style for header row
CellStyle cs = wb.createCellStyle();
cs.setFillForegroundColor(IndexedColors.LIME.getIndex());
cs.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
Font f = wb.createFont();
f.setBoldweight(Font.BOLDWEIGHT_BOLD);
f.setFontHeightInPoints((short) 12);
cs.setFont(f);
//New Sheet
Sheet sheet1 = null;
sheet1 = wb.createSheet(newDesc);
ResultSetMetaData metaData = rs.getMetaData();
int colCount = metaData.getColumnCount();
//Create Hash Map of Field Definitions
LinkedHashMap<Integer, MyTableInfo> hashMap = new LinkedHashMap<Integer, MyTableInfo>(colCount);
for (int i = 0; i < colCount; i++) {
MyTableInfo db2TableInfo = new MyTableInfo();
db2TableInfo.setFieldName(metaData.getColumnName(i + 1).trim());
db2TableInfo.setFieldText(metaData.getColumnLabel(i + 1));
db2TableInfo.setFieldSize(metaData.getPrecision(i + 1));
db2TableInfo.setFieldDecimal(metaData.getScale(i + 1));
db2TableInfo.setFieldType(metaData.getColumnType(i + 1));
db2TableInfo.setCellStyle(getCellAttributes(wb, c, db2TableInfo));
hashMap.put(i, db2TableInfo);
}
// Row and column indexes
int idx = 0;
int idy = 0;
// Generate column headings
Row row = sheet1.createRow(idx);
MyTableInfo db2TableInfo = new MyTableInfo();
Iterator<Integer> iterator = hashMap.keySet().iterator();
while (iterator.hasNext()) {
Integer key = (Integer) iterator.next();
db2TableInfo = hashMap.get(key);
c = row.createCell(idy);
c.setCellValue(db2TableInfo.getFieldText());
c.setCellStyle(cs);
if(db2TableInfo.getFieldSize() > db2TableInfo.getFieldText().trim().length()){
sheet1.setColumnWidth(idy, (db2TableInfo.getFieldSize()* 500));
}
else {
sheet1.setColumnWidth(idy, (db2TableInfo.getFieldText().trim().length() * 500));
}
idy++;
}
while (rs.next()) {
idx++;
row = sheet1.createRow(idx);
System.out.println(idx);
for (int i = 0; i < colCount; i++) {
c = row.createCell(i);
db2TableInfo = hashMap.get(i);
switch (db2TableInfo.getFieldType()) {
case 1:
c.setCellValue(rs.getString(i+1));
break;
case 2:
c.setCellValue(rs.getDouble(i+1));
break;
case 3:
c.setCellValue(rs.getDouble(i+1));
break;
default:
c.setCellValue(rs.getString(i+1));
break;
}
c.setCellStyle(db2TableInfo.getCellStyle());
}
}
rs.close();
FileOutputStream fileOut = new FileOutputStream(excelFilename);
wb.write(fileOut);
fileOut.close();
}
catch (Exception e) {
System.out.println(e);
}
}
private static CellStyle getCellAttributes (Workbook wb, Cell c, MyTableInfo db2TableInfo){
CellStyle cs= wb.createCellStyle();
DataFormat df = wb.createDataFormat();
Font f = wb.createFont();
switch (db2TableInfo.getFieldDecimal()) {
case 1:
cs.setDataFormat(df.getFormat("#,##0.0"));
break;
case 2:
cs.setDataFormat(df.getFormat("#,##0.00"));
break;
case 3:
cs.setDataFormat(df.getFormat("#,##0.000"));
break;
case 4:
cs.setDataFormat(df.getFormat("#,##0.0000"));
break;
case 5:
cs.setDataFormat(df.getFormat("#,##0.00000"));
break;
default:
break;
}
cs.setFont(f);
return cs;
}
I get the following message:
"Excel cannot open the file "filename" because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file."
I used to generate excel files using JXL earlier but recently it started giving me the same thing too hence i opted to switch to Apache POI.
Thanks in advance.
Your HttpServletResponse has been setted correctly?
What file extension are you using?
Try with this:
ServletOutputStream os = response.getOutputStream();
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=\"example.xls\"");
workbook = getWorkbook(....)
workbook.write(os);
workbook.close();
os.flush();
response.flushBuffer();
Where 'response' is a HttpServletResponse from the controller method
Related
I am having 100 excel files and I want to merge all of them into one excel file. Here in my example I am having 2 excel files and I want to merge them into one. I can't do it. I am using Apache POI API.
In one excel workbook there can be more than one sheets also so I want to iterate through sheets of each workbook also.
I tried and researched but I got this link and it's not working for me
https://dev.to/eiceblue/merge-excel-files-in-java-2lo2#:~:text=A%20quick%20way%20to%20merge,data%20table%20into%20another%20worksheet.
Please help me out here.
package com.cas.ExcelTest;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class Combine {
public static void main(String args[]) {
String[] files = new String[] {"Test2.xlsx","Test3.xlsx"};
XSSFWorkbook workbook = new XSSFWorkbook();
try {
for (int f = 0; f < files.length; f++) {
String file = files[f];
FileInputStream inputStream = new FileInputStream(file);
XSSFWorkbook tempWorkbook = new XSSFWorkbook(inputStream);
int numOfSheets = tempWorkbook.getNumberOfSheets();
for (int i = 0; i < numOfSheets; i++) {
XSSFSheet tempSheet = tempWorkbook.getSheetAt(i);
String newSheetName = ""+f+""+tempSheet.getSheetName();
XSSFSheet sheet = workbook.createSheet(newSheetName);
Iterator<Row> itRow = tempSheet.rowIterator();
while(itRow.hasNext()) {
Row tempRow = itRow.next();
XSSFRow row = sheet.createRow(tempRow.getRowNum());
Iterator<Cell> itCell = tempRow.cellIterator();
while(itCell.hasNext()) {
Cell tempCell = itCell.next();
XSSFCell cell = row.createCell(tempCell.getColumnIndex());
switch (tempCell.getCellType()) {
case NUMERIC:
cell.setCellValue(tempCell.getNumericCellValue());
break;
case STRING:
cell.setCellValue(tempCell.getStringCellValue());
break;
case BLANK:
break;
case BOOLEAN:
break;
case ERROR:
break;
case FORMULA:
cell.setCellValue(tempCell.getNumericCellValue());
break;
case _NONE:
break;
default:
break;
}
}
}
}
}
} catch (IOException ex1) {
System.out.println("Error reading file");
ex1.printStackTrace();
}
try (FileOutputStream outputStream = new FileOutputStream("result.xlsx")) {
workbook.write(outputStream);
}
catch(Exception ex) {
System.out.println("Something went wrong");
}
}
}
My Excel files:
Test2.xlsx
Test3.xlsx
Here some columns are extra in Test3.xlsx and in both files as you can see in the heading row its all string but after that it has numeric values.
Here you have an approximation of the code you need, format it, extract functionalities to methods and check the naming of sheets.
String[] files = new String[] {"Test2.xlsx","Test3.xlsx"};
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = createSheetWithHeader(workbook);
try {
for (int f = 0; f < files.length; f++) {
String file = files[f];
FileInputStream inputStream = new FileInputStream(file);
XSSFWorkbook tempWorkbook = new XSSFWorkbook(inputStream);
int numOfSheets = tempWorkbook.getNumberOfSheets();
for (int i = 0; i < numOfSheets; i++) {
XSSFSheet tempSheet = tempWorkbook.getSheetAt(i);
int indexLastDataInserted = sheet.getLastRowNum();
int firstDataRow = getFirstDataRow(tempSheet);
Iterator<Row> itRow = tempSheet.rowIterator();
while(itRow.hasNext()) {
Row tempRow = itRow.next();
if (tempRow.getRowNum() >= firstDataRow) {
XSSFRow row = sheet.createRow(indexLastDataInserted + 1);
Iterator<Cell> itCell = tempRow.cellIterator();
while(itCell.hasNext()) {
Cell tempCell = itCell.next();
XSSFCell cell = row.createCell(tempCell.getColumnIndex());
//At this point you will have to set the value of the cell depending on the type of data it is
switch (tempCell.getCellType()) {
case NUMERIC:
cell.setCellValue(tempCell.getNumericCellValue());
break;
case STRING:
cell.setCellValue(tempCell.getStringCellValue());
break;
/**
* Add your other types, here is your problem!!!!!
*/
}
}
}
}
}
}
}catch (IOException ex1) {
System.out.println("Error reading file");
ex1.printStackTrace();
}
try (FileOutputStream outputStream = new FileOutputStream("result.xlsx")) {
workbook.write(outputStream);
}
Function to get the first data row (necessary to avoid having to enter by hand where the header of each excel ends):
/**
* If the tab has a filter, it returns the row index of the filter + 1, otherwise it returns 0
* #param tempSheet
* #return index of first data row
*/
public static Integer getFirstDataRow(XSSFSheet tempSheet) {
Integer result = 0;
Boolean isAutoFilter = tempSheet.getCTWorksheet().isSetAutoFilter();
if (isAutoFilter) {
String autoFilterRef = tempSheet.getCTWorksheet().getAutoFilter().getRef();
result = new CellReference(autoFilterRef.substring(0, autoFilterRef.indexOf(":"))).getRow() + 1;
}
return result;
}
Create the sheet with header in the method:
public static XSSFSheet createSheetWithHeader(XSSFWorkbook workbook){
XSSFSheet sheet = workbook.createSheet("NEW_SHEET_NAME");
//Implement the header
[...]
return sheet;
}
Hi there i was following a tutorial regarding the data driven testing in selenium and i want to read data from the excel file .xlsx but its giving me null pointer.
Below is the code:
package com.usman;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;public class ReadDataFromExcelSheet {
public String[][] getExcelData(String excellocation, String sheetName) {
try {
String dataSets[][] = null;
FileInputStream file = new FileInputStream(new File(excellocation));
// Create Workbook instance holding reference to .xlsx file
XSSFWorkbook workbook = new XSSFWorkbook(file);
// Get first/desired sheet from the workbook
XSSFSheet sheet = workbook.getSheet(sheetName);
// count number of active rows
int totalRow = sheet.getLastRowNum();
// count number of active columns in row
int totalColumn = sheet.getRow(0).getLastCellNum();
// Create array of rows and column
dataSets = new String[totalRow][totalColumn];
// Iterate through each rows one by one
Iterator<Row> rowIterator = sheet.iterator();
int i = 0;
while (rowIterator.hasNext()) {
System.out.println(i);
Row row = rowIterator.next();
// For each row, iterate through all the columns
Iterator<Cell> cellIterator = row.cellIterator();
int j = 0;
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
if (cell.getStringCellValue().contains("User Name")) {
break;
}
// Check the cell type and format accordingly
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
dataSets[i - 1][j++] = cell.getStringCellValue();
System.out.println(cell.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING:
dataSets[i - 1][j++] = cell.getStringCellValue();
System.out.println(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_BOOLEAN:
dataSets[i - 1][j++] = cell.getStringCellValue();
System.out.println(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
dataSets[i - 1][j++] = cell.getStringCellValue();
System.out.println(cell.getStringCellValue());
break;
}
}
System.out.println("");
i++;
}
file.close();
return dataSets;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void updateResult(String excellocation, String sheetName, String testCaseName, String testStatus) throws IOException {
try {
FileInputStream file = new FileInputStream(new File(excellocation));
// Create Workbook instance holding reference to .xlsx file
XSSFWorkbook workbook = new XSSFWorkbook(file);
// Get first/desired sheet from the workbook
XSSFSheet sheet = workbook.getSheet(sheetName);
// count number of active tows
int totalRow = sheet.getLastRowNum() + 1;
// count number of active columns in row
for (int i = 1; i < totalRow; i++) {
XSSFRow r = sheet.getRow(i);
String ce = r.getCell(1).getStringCellValue();
if (ce.contains(testCaseName)) {
r.createCell(2).setCellValue(testStatus);
file.close();
System.out.println("resule updated");
FileOutputStream outFile = new FileOutputStream(new File(excellocation));
workbook.write(outFile);
outFile.close();
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public Object[][] getExcelDataBasedOnStartingPoint(String excellocation, String sheetName, String testName) {
try {
String dataSets[][] = null;
FileInputStream file = new FileInputStream(new File(excellocation));
// Create Workbook instance holding reference to .xlsx file
XSSFWorkbook workbook = new XSSFWorkbook(file);
// Get first/desired sheet from the workbook
XSSFSheet sheet = workbook.getSheet(sheetName);
// count number of active rows
int totalRow = sheet.getLastRowNum();
int totalColumn = 0;
// Iterate through each rows one by one
Iterator<Row> rowIterator = sheet.iterator();
int i = 0;
int count = 1;
while (rowIterator.hasNext() && count == 1 || count == 2) {
// System.out.println(i);
Row row = rowIterator.next();
// For each row, iterate through all the columns
Iterator<Cell> cellIterator = row.cellIterator();
int j = 0;
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
if (cell.getStringCellValue().contains(testName + "end")) {
count = 0;
break;
}
// System.out.println(sheetName+"Start");
if (cell.getStringCellValue().contains(testName + "start")) {
// count number of active columns in row
totalColumn = row.getPhysicalNumberOfCells() - 1;
// Create array of rows and column
dataSets = new String[totalRow][totalColumn];
}
// System.out.println(sheetName+"Start");
if (cell.getStringCellValue().contains(testName + "start") || count == 2) {
System.out.println(sheetName + "start");
count = 2;
// Check the cell type and format accordingly
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
dataSets[i - 1][j++] = cell.getStringCellValue();
System.out.println(cell.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING:
if (!cell.getStringCellValue().contains(testName + "start")) {
dataSets[i - 1][j++] = cell.getStringCellValue();
System.out.println(cell.getStringCellValue());
}
break;
case Cell.CELL_TYPE_BOOLEAN:
dataSets[i - 1][j++] = cell.getStringCellValue();
System.out.println(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
dataSets[i - 1][j++] = cell.getStringCellValue();
System.out.println(cell.getStringCellValue());
break;
}
}
}
System.out.println("");
i++;
}
file.close();
return parseData(dataSets, totalColumn);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* This method is used to remove unwanted null data from array
*
* #param data
* #return
*/
public Object[][] parseData(Object[][] data, int colSize) {
// Creating array list to store data;
ArrayList<ArrayList<String>> list = new ArrayList<ArrayList<String>>();
// This array list will store one Array index data, every array index
// has three sets of data
ArrayList<String> list1;
System.out.println(data.length);
// running for loop on array size
for (int i = 0; i < data.length; i++) {
// creates a list to store the elements != null
System.out.println(data[i].length);
list1 = new ArrayList<String>();
// this for loop will run on array index, since each array index has
// three sets of data
for (int j = 0; j < data[i].length; j++) {
// this if will check null
if (data[i][j] != null) {
list1.add((String) data[i][j]);
}
}
// once all one array index data is entered in arrayList , then
// putting this object in parent arrayList
if (list1.size() > 0) {
list.add(list1);
}
}
// convert array List Data into 2D Array
Object[][] arr2d = new Object[list.size()][colSize];
// run loop on array list data
for (int i = 0; i < list.size(); i++) {
// every array list index has arryList inside
ArrayList<String> t = list.get(i);
// run loop on inner array List
for (int j = 0; j < t.size(); j++) {
arr2d[i][j] = t.get(j);
}
}
System.out.println(list);
System.out.println(arr2d);
return arr2d;
}
public static void main(String[] args) throws IOException {
String excellocation = "D:\\usman data\\excel-tutorial-with-dataDrivenFramework-master\\excel-tutorial-with-dataDrivenFramework-master\\src\\main\\resources\\testData\\demo.xlsx";
String sheetName = "login";
ReadDataFromExcelSheet excel = new ReadDataFromExcelSheet();
Object[][] data = excel.getExcelDataBasedOnStartingPoint(excellocation, sheetName, "login");
System.out.println(data);
// excel.updateResult(excellocation, sheetName, "Login Test", "FAIL");
// excel.updateResult(excellocation, sheetName, "Registartion Test",
// "PASS");
// excel.updateResult(excellocation, sheetName, "Dashboard Test",
// "PASS");
}
}
I am getting the following error:
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.dom4j.io.SAXContentHandler (file:/C:/Users/True%20Meridian/.m2/repository/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar) to method com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser$LocatorProxy.getEncoding()
WARNING: Please consider reporting this to the maintainers of org.dom4j.io.SAXContentHandler
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
java.lang.NullPointerException
null
at com.usman.ReadDataFromExcelSheet.getExcelDataBasedOnStartingPoint(ReadDataFromExcelSheet.java:130)
at com.usman.ReadDataFromExcelSheet.main(ReadDataFromExcelSheet.java:258)
On XSSFSheet sheet = workbook.getSheet(sheetName); in method getExcelDataBasedOnStartingPoint it probably returns null. If it does, the name provided is not the sheet name of any sheet in the workbook. You should check for null. Like this:
XSSFSheet sheet = workbook.getSheet(sheetName);
if (sheet == null) throw new IllegalArgumentException("Sheet with sheet name " + sheetName + " does not exist");
This being said, this does not exactly resolve your issue. Your main issue is, that sheet "login" does not exist in the workbook "D:\usman data\excel-tutorial-with-dataDrivenFramework-master\excel-tutorial-with-dataDrivenFramework-master\src\main\resources\testData\demo.xlsx".
I have nearly 1500 rows in web table, I want to write all the rows data to excel.
I'm using Selenium-Webdriver,Java. problem is program stopped without any error after writing nearly 300 rows.
Please help me on this, How to write all the data to excel. if i give thraed.sleep(5000); its taking more time.
I have used below mentioned code:
List<WebElement> irows = a2.findElements(By.xpath("//*[#id='filter_result']/table/tbody/tr/td[2]/a[1]"));
int iRowsCount = irows.size();
System.out.println(iRowsCount);
FileOutputStream fos = new FileOutputStream("E:\\jega\\testw3.xlsx");
XSSFWorkbook wkb = new XSSFWorkbook();
XSSFSheet sheet1 = wkb.createSheet("DataStorage");
String a3=null;
for (int i=500,Row=0;i<=iRowsCount;i++) {
try
{
WebElement val= a2.findElement(By.xpath("//*[#id='filter_result']/table/tbody/tr["+i+"]/td[2]"));
// WebElement val= a2.findElement(By.xpath("//*[#id='filter_result']/table/tbody/tr["+i+"]/td["+j+"]"));
String a = val.getText();
if( a.length() != 0 )
{
a3=a;
//int length = val.length();
System.out.print(a3 + '\n');
XSSFRow excelRow = sheet1.createRow(Row++);
XSSFCell excelCell = excelRow.createCell(0);
excelCell.setCellType(XSSFCell.CELL_TYPE_STRING);
excelCell.setCellValue(a3);
for ( int j=5;j<12;j++)
{ switch (j)
{
case 5:val= a2.findElement(By.xpath("//*[#id='filter_result']/table/tbody/tr["+i+"]/td[5]"));excelCell = excelRow.createCell(1);
excelCell.setCellValue(val.getText()); break;
case 8:val= a2.findElement(By.xpath("//*[#id='filter_result']/table/tbody/tr["+i+"]/td[8]"));excelCell = excelRow.createCell(2);
excelCell.setCellValue(val.getText());break;
case 9:val= a2.findElement(By.xpath("//*[#id='filter_result']/table/tbody/tr["+i+"]/td[9]"));excelCell = excelRow.createCell(3);
excelCell.setCellValue(val.getText());break;
case 11:val= a2.findElement(By.xpath("//*[#id='filter_result']/table/tbody/tr["+i+"]/td[11]"));excelCell = excelRow.createCell(4);
excelCell.setCellValue(val.getText());break;
}
}
Thread.sleep(5000);
}
else
{
System.out.print(a3 + '\n');
XSSFRow excelRow = sheet1.createRow(Row++);
XSSFCell excelCell = excelRow.createCell(0);
excelCell.setCellType(XSSFCell.CELL_TYPE_STRING);
excelCell.setCellValue(a3);
for ( int j=5;j<12;j++)
{ switch (j)
{
case 5:val= a2.findElement(By.xpath("//*[#id='filter_result']/table/tbody/tr["+i+"]/td[5]"));excelCell = excelRow.createCell(1);
excelCell.setCellValue(val.getText()); break;
case 8:val= a2.findElement(By.xpath("//*[#id='filter_result']/table/tbody/tr["+i+"]/td[8]"));excelCell = excelRow.createCell(2);
excelCell.setCellValue(val.getText());break;
case 9:val= a2.findElement(By.xpath("//*[#id='filter_result']/table/tbody/tr["+i+"]/td[9]"));excelCell = excelRow.createCell(3);
excelCell.setCellValue(val.getText());break;
case 11:val= a2.findElement(By.xpath("//*[#id='filter_result']/table/tbody/tr["+i+"]/td[11]"));excelCell = excelRow.createCell(4);
excelCell.setCellValue(val.getText());break;
}
}
Thread.sleep(5000);
}
}//tryc
catch (NoSuchElementException e) {
}//cath
}//for
// System.out.println();
// Thread.sleep(6000);
fos.flush();
wkb.write(fos);
fos.close();
Can anyone help me on this issue?
Your help is much appreciated.
Best Regards.
I have also exported web table data to an excel sheet like this,
This works fine for me. Hope this will help you.
WebElement element = driver.findElement(By.xpath("//*[#id='entireBody']/div[3]/div/table"));
List<WebElement> tbdy = element.findElements(By.tagName("tbody"));
List<WebElement> thed = element.findElements(By.tagName("thead"));
Thread.sleep(1000);
List<WebElement> tr = tbdy.get(0).findElements(By.tagName("tr"));
List<WebElement> trh = thed.get(0).findElements(By.tagName("tr"));
Thread.sleep(1000);
try {
String filename = Path;
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("FirstSheet");
CellStyle style = workbook.createCellStyle();//Create style
Font font = workbook.createFont();//Create font
font.setBoldweight(Font.BOLDWEIGHT_BOLD);//Make font bold
style.setFont(font);//set it to bold
HSSFRow row = sheet.createRow(0);
for(int i = 0; i < trh.size(); i++){
List<WebElement> tdh =trh.get(i).findElements(By.tagName("td"));
System.out.println("loop1");
for (int j = 0; j < tdh.size(); j++) {
row.createCell(j).setCellValue(tdh.get(j).getText());
row.getCell(j).setCellStyle(style);
}
}
for (int i = 0; i < tr.size(); i++) {
HSSFRow row2 = sheet.createRow(i+1);
List<WebElement> td = tr.get(i).findElements(By.tagName("td"));
for (int j = 0; j < td.size(); j++) {
td.get(j).getText();
row2.createCell(j).setCellValue(td.get(j).getText());
}
}
FileOutputStream fileOut = new FileOutputStream(filename);
workbook.write(fileOut);
fileOut.close();
System.out.println("Your excel file has been generated!");
i m trying to merge two .xlsx files to each other in java. But i m somehow getting a NullPointerException on the line
if (cell.getSheet().getWorkbook() == mcell.getSheet()
.getWorkbook()) {
}
Any ides what could cause this error ? when i tried before merging other two files, my code worked perfectly, but now i changed the files and now getting NullPointerException. The new Files which i try to merge have 2 sheets. I just need to merge the first pages of them.
Here is my code :
public static void main(String[] args) {
try {
FileInputStream excellFile1 = new FileInputStream(new File(
"/Users/TLQ/Desktop/a.xlsx"));
FileInputStream excellFile2 = new FileInputStream(new File(
"/Users/TLQ/Desktop/b.xlsx"));
// Create Workbook instance holding reference to .xlsx file
XSSFWorkbook workbook1 = new XSSFWorkbook(excellFile1);
XSSFWorkbook workbook2 = new XSSFWorkbook(excellFile2);
// Get first/desired sheet from the workbook
XSSFSheet sheet1 = workbook1.getSheetAt(0);
XSSFSheet sheet2 = workbook2.getSheetAt(0);
// add sheet2 to sheet1
addSheet(sheet1, sheet2);
excellFile1.close();
// save merged file
File mergedFile = new File(
"/Users/TLQ/Desktop/Albert.xlsx");
if (!mergedFile.exists()) {
mergedFile.createNewFile();
}
FileOutputStream out = new FileOutputStream(mergedFile);
workbook1.write(out);
out.close();
// mergeThemAll(mergedFile);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void addSheet(XSSFSheet mergedSheet, XSSFSheet sheet) {
// map for cell styles
Map<Integer, XSSFCellStyle> styleMap = new HashMap<Integer, XSSFCellStyle>();
// This parameter is for appending sheet rows to mergedSheet in the end
int len = mergedSheet.getLastRowNum();
for (int j = sheet.getFirstRowNum(); j <= sheet.getLastRowNum(); j++) {
XSSFRow row = sheet.getRow(j);
XSSFRow mrow = mergedSheet.createRow(len + j + 1);
for (int k = row.getFirstCellNum(); k < row.getLastCellNum(); k++) {
XSSFCell cell = row.getCell(k);
XSSFCell mcell = mrow.createCell(k);
if (cell.getSheet().getWorkbook() == mcell.getSheet()
.getWorkbook()) {
mcell.setCellStyle(cell.getCellStyle());
} else {
int stHashCode = cell.getCellStyle().hashCode();
XSSFCellStyle newCellStyle = styleMap.get(stHashCode);
if (newCellStyle == null) {
newCellStyle = mcell.getSheet().getWorkbook()
.createCellStyle();
newCellStyle.cloneStyleFrom(cell.getCellStyle());
styleMap.put(stHashCode, newCellStyle);
}
mcell.setCellStyle(newCellStyle);
}
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_FORMULA:
mcell.setCellFormula(cell.getCellFormula());
break;
case HSSFCell.CELL_TYPE_NUMERIC:
mcell.setCellValue(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_STRING:
mcell.setCellValue(cell.getStringCellValue());
break;
case HSSFCell.CELL_TYPE_BLANK:
mcell.setCellType(HSSFCell.CELL_TYPE_BLANK);
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
mcell.setCellValue(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_ERROR:
mcell.setCellErrorValue(cell.getErrorCellValue());
break;
default:
mcell.setCellValue(cell.getStringCellValue());
break;
}
}
}
}
row.getCell(k) can return null if there is no Cell at that position. There are a few ways to work around the problem (e.g. asking the workbook to create cells on the fly), but for this case, checking against null Cells is the easiest and least resource-consuming option.
Does anyone know of a means to copy a worksheet from one workbook to another using POI? The Workbook class has a cloneSheet method, but there doesn't seem to be able to insert a cloned sheet into a new workbook?
If there isn't an API to do this easily, does anyone have the code to copy all of the data (styles, column widths, data, etc) from one sheet to another?
The jxls has methods to copy sheets, but they don't work when copying between workbooks.
i have implemented some functionality with poi. please see the code for your reference.
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public class ExcelReadAndWrite {
public static void main(String[] args) throws IOException {
ExcelReadAndWrite excel = new ExcelReadAndWrite();
excel.process("D:/LNN/My Workspace/POI/src/tables.xls");
}
public void process(String fileName) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fileName));
HSSFWorkbook workbook = new HSSFWorkbook(bis);
HSSFWorkbook myWorkBook = new HSSFWorkbook();
HSSFSheet sheet = null;
HSSFRow row = null;
HSSFCell cell = null;
HSSFSheet mySheet = null;
HSSFRow myRow = null;
HSSFCell myCell = null;
int sheets = workbook.getNumberOfSheets();
int fCell = 0;
int lCell = 0;
int fRow = 0;
int lRow = 0;
for (int iSheet = 0; iSheet < sheets; iSheet++) {
sheet = workbook.getSheetAt(iSheet);
if (sheet != null) {
mySheet = myWorkBook.createSheet(sheet.getSheetName());
fRow = sheet.getFirstRowNum();
lRow = sheet.getLastRowNum();
for (int iRow = fRow; iRow <= lRow; iRow++) {
row = sheet.getRow(iRow);
myRow = mySheet.createRow(iRow);
if (row != null) {
fCell = row.getFirstCellNum();
lCell = row.getLastCellNum();
for (int iCell = fCell; iCell < lCell; iCell++) {
cell = row.getCell(iCell);
myCell = myRow.createCell(iCell);
if (cell != null) {
myCell.setCellType(cell.getCellType());
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_BLANK:
myCell.setCellValue("");
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
myCell.setCellValue(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_ERROR:
myCell.setCellErrorValue(cell.getErrorCellValue());
break;
case HSSFCell.CELL_TYPE_FORMULA:
myCell.setCellFormula(cell.getCellFormula());
break;
case HSSFCell.CELL_TYPE_NUMERIC:
myCell.setCellValue(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_STRING:
myCell.setCellValue(cell.getStringCellValue());
break;
default:
myCell.setCellFormula(cell.getCellFormula());
}
}
}
}
}
}
}
bis.close();
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("workbook.xls", true));
myWorkBook.write(bos);
bos.close();
}
}
I created a workitem for NPOI: http://npoi.codeplex.com/WorkItem/View.aspx?WorkItemId=6057.
Update: The workitem is implemented in NPOI 2.0. You can download NPOI 2.0 from https://npoi.codeplex.com/releases/view/112932
This is my implementation of copying sheets from one workbook to another. This solution works for me. This code will work if the sheets don't have tables, etc. If the sheets contain simple text (String, boolean, int etc), formulas, this solution will work.
Workbook oldWB = new XSSFWorkbook(new FileInputStream("C:\\input.xlsx"));
Workbook newWB = new XSSFWorkbook();
CellStyle newStyle = newWB.createCellStyle(); // Need this to copy over styles from old sheet to new sheet. Next step will be processed below
Row row;
Cell cell;
for (int i = 0; i < oldWB.getNumberOfSheets(); i++) {
XSSFSheet sheetFromOldWB = (XSSFSheet) oldWB.getSheetAt(i);
XSSFSheet sheetForNewWB = (XSSFSheet) newWB.createSheet(sheetFromOldWB.getSheetName());
for (int rowIndex = 0; rowIndex < sheetFromOldWB.getPhysicalNumberOfRows(); rowIndex++) {
row = sheetForNewWB.createRow(rowIndex); //create row in this new sheet
for (int colIndex = 0; colIndex < sheetFromOldWB.getRow(rowIndex).getPhysicalNumberOfCells(); colIndex++) {
cell = row.createCell(colIndex); //create cell in this row of this new sheet
Cell c = sheetFromOldWB.getRow(rowIndex).getCell(colIndex, Row.CREATE_NULL_AS_BLANK ); //get cell from old/original WB's sheet and when cell is null, return it as blank cells. And Blank cell will be returned as Blank cells. That will not change.
if (c.getCellType() == Cell.CELL_TYPE_BLANK){
System.out.println("This is BLANK " + ((XSSFCell) c).getReference());
}
else { //Below is where all the copying is happening. First It copies the styles of each cell and then it copies the content.
CellStyle origStyle = c.getCellStyle();
newStyle.cloneStyleFrom(origStyle);
cell.setCellStyle(newStyle);
switch (c.getCellTypeEnum()) {
case STRING:
cell.setCellValue(c.getRichStringCellValue().getString());
break;
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
cell.setCellValue(c.getDateCellValue());
} else {
cell.setCellValue(c.getNumericCellValue());
}
break;
case BOOLEAN:
cell.setCellValue(c.getBooleanCellValue());
break;
case FORMULA:
cell.setCellValue(c.getCellFormula());
break;
case BLANK:
cell.setCellValue("who");
break;
default:
System.out.println();
}
}
}
}
}
//Write over to the new file
FileOutputStream fileOut = new FileOutputStream("C:\\output.xlsx");
newWB.write(fileOut);
oldWB.close();
newWB.close();
fileOut.close();
If your requirement is to copy full sheets as is without leaving anything, the process of elimination works better in this case and faster than the above code and you don't have to worry about losing formulas, drawings, tables, styles, fonts, etc.
XSSFWorkbook wb = new XSSFWorkbook("C:\\abc.xlsx");
for (int i = wb.getNumberOfSheets() - 1; i >= 0; i--) {
if (!wb.getSheetName(i).contentEquals("January")) //This is a place holder. You will insert your logic here to get the sheets that you want.
wb.removeSheetAt(i); //Just remove the sheets that don't match your criteria in the if statement above
}
FileOutputStream out = new FileOutputStream(new File("C:\\xyz.xlsx"));
wb.write(out);
out.close();
If you are using the Java POI library the best would be to load the Spreadsheet into memory,,, then create a new one and write each one of the records you want to copy... not the best way but acomplishes the copy function...
I put about a week of effort into doing this with POI (using the latest code on coderanch) - be warned that the code is flawed (there's an issue with using TreeSet where you need to replace that with a HashMap), but even after fixing that it crashes on formulas.
While it may be possible to do it's a scary proposition to have to rely on hacked up code.
Depending on your needs/budget you may want to consider biting the bullet and paying for aspose - http://www.aspose.com/doctest/java-components/aspose.cells-for-java/copy-move-worksheets-within-and-between-workbooks.html
It successfully copied sheets including formatting, formulas, & protection rules. I did 300 sheets in 130 seconds. (300 x 90kb workbooks, compiled into one 15mb workbook). The demo is free, it just puts an additional sheet into the workbook reminding you to buy a license.
The best way is to open the file and load it.
If you want any of the specific sheets from the source Excel file, then you just need to remove the sheet that does not match the intended Sheet.
try this:
FileInputStream fis=new FileInputStream("D:\\SourceExcel.xls");
Workbook wb=WorkbookFactory.create(fis);
for (int i = wb.getNumberOfSheets() - 1; i >= 0; i--) {
if (!wb.getSheetName(i).contentEquals("SheetNameWhichwantToRetain")) //This is a place holder. You will insert your logic here to get the sheets that you want.
wb.removeSheetAt(i); //Just remove the sheets that don't match your criteria in the if statement above
}
FileOutputStream fos = new FileOutputStream(new File("D:\\DestinationFileName.xls"));
wb.write(fos);
fos.close();
System.out.println("file is copied in a new file at destination :"+"D:\\DestinationFileName.xls");
}
catch(Exception e){
e.printStackTrace();
}
This should help clarify