I am reading data from an arraylist and writing this to an excel sheet. The problem is my excel is getting overwritten each time. Here is my code. I can't figure out what is wrong here :( Can someone please help?
public static void main( String[] args ) throws Exception
{
List<String> fileData = new ArrayList<String>();
for(File file:files) {
fileData.add(readFileContents(file.getAbsolutePath()));
}
for(String fileContent:fileData) {
//do some stuff that in turn calls the writeDataToExcel method
}
}
private static void writeDataToExcel(String test,Map<String,String> dataMap,Object object) throws IOException {
File file = new File("input/data.xls");
Map<String,Object[]> data = new LinkedHashMap<String,Object[]>();
XSSFWorkbook workbook = null;
int count = 0;
XSSFSheet sheet = null;
if(file.exists()) {
workbook = new XSSFWorkbook(new FileInputStream(file));
sheet = workbook.getSheet("Data Sheet");
}
else {
workbook = new XSSFWorkbook();
sheet = workbook.createSheet("Data Sheet");
//count = sheet.getLastRowNum();
}
data.put("1", new Object[]{"Id","Name","Field","Description","Value"});
for(Map.Entry<String, String> dataMp:dataMap.entrySet()) {
data.put(Integer.toString(count+2), new Object[]{id,object.getClass().getSimpleName(),dataMp.getKey(),dataMp.getValue(),"null"});
count++;
}
Set<String> keyset = data.keySet();
int rownum = 0;
for (String key : keyset) {
Row row = sheet.createRow(rownum++);
Object [] objArr = data.get(key);
int cellnum = 0;
for (Object obj : objArr) {
Cell cell = row.createCell(cellnum++);
if(obj instanceof String)
cell.setCellValue((String)obj);
}
}
FileOutputStream fis = new FileOutputStream("input/data.xls");
workbook.write(fis);
if(fis!=null)
fis.close();
}
I think problem is at line
int rownum = 0;
this will set rowNUm to zero each time and sheet will be written from zero row
You need to persist this rowNum value if you want to append data in the sheet
Related
I have an Excel file which needs filtering on a specific column.
String fileName = "filepath";
String cellContent = "Automation";
int rownr = 0;
int colnr = 0; //column from which you need data to store in array list
InputStream input = new FileInputStream(fileName);
XSSFWorkbook wb = new XSSFWorkbook(input);
XSSFSheet sheet = wb.getSheetAt(0);
List filteredCol = new ArrayList();
filteredCol = findRow(sheet, cellContent);
if (filteredCol != null) {
for (Iterator iter = filteredCol.iterator(); iter.hasNext(); ) {
System.out.println(iter.next());
}
}
private static List findRow(HSSFSheet sheet, String cellContent) {
List filter=new ArrayList();
for (Row row : sheet) {
for (Cell cell : row) {
if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
if (cell.getRichStringCellValue().getString().trim().equals(cellContent)) {
//System.out.println("Row numbers are"+row.getRowNum());
int rownumber=row.getRowNum();
//return row.getRowNum();
XSSFRow row1 = sheet.getRow(rownumber);
XSSFCell cell1 = row1.getCell(0);
filter.add(cell1);
}
}
}
}
return filter;
}
I am getting number format exception on this codeline:
"cell.getRichStringCellValue().getString().trim().equals(cellContent)"
How about reading the row with multiple values using excel
for instance
reference
testcase1
testcase2
testcase3
Name
Sam
ram
cam
Age
20
25
30
sex
m
F
m
place
place1
place2
place 3
I have to read
testcase1.name=sam
testcase2.name=ram
testcase3.name=cam
and age
how can I do this... any help would be appreciated
Use apache poi library.
First you must read the Excel file in a java object
FileInputStream myFile = new FileInputStream(new File(FILE_NAME));
Workbook myWorkbook = new XSSFWorkbook(myFile);
Sheet datatypeSheet = myWorkbook.getSheetAt(0); //read the first sheet
Iterator<Row> iterator = datatypeSheet.iterator();
Then you can iterate over each row and in each row you can read each cell (aka column value)
List<TestCase> myList = new ArrayList();
int rowNum = 0;
while (iterator.hasNext()) {
Row row = iterator.next();
int columnsSize = row.getLastCellNum();
//create all objects
if(rowNum == 0) {
for (int i = 1; i <= columnsSize; i++) {
myList.add(new TestCase());
}
} else {
//initialize property in each row for all objects
for (int i = 1; i <= columnsSize; i++) {
TestCase testCase = myList.get(i-1);
int cellType = row.getCell(i).getCellType();
switch(cellType) {
case Cell.CELL_TYPE_NUMERIC:
testCase.properties.add(new Property(row.getCell(0).getStringCellValue(),
String.valueOf(row.getCell(i).getNumericCellValue()));
break;
case Cell.CELL_TYPE_STRING:
testCase.properties.add(new Property(row.getCell(0).getStringCellValue(),
row.getCell(i).getStringCellValue());
break;
}
}
}
rowNum++;
}
System.out.println(myList);
public class TestCase {
public List<Property> properties;
public TestCase(){
this.properties = new ArrayList();
}
}
public class Property {
String name;
String value;
public Property(String name, String value){
this.name = name;
this.value = value;
}
}
*Edit: For loop must have <= condition instead of <
This tutorial might be helpful to use: https://www.javatpoint.com/how-to-read-excel-file-in-java.
Basically, you are using the Apache POI Library to parse the file's values, generating iterators for each row, then for each cell in each row, and dealing with the data that way.
In your case, after importing the relevant Classes, the code snippet will be something like this:
//Input Data for Class
FileInputStream in = new FileInputStream(new File("<File Location>.xls(x)"));
// Create an Apache POI Workbook reading the file
HSSFWorkbook workbook = new HSSFWorkbook(in);
// Use the Workbook to make a sheet
HSSFSheet sheet = workbook.getSheetAt(0); // Replace 0 with your sheet number
List<Row> rowsList = new ArrayList<Row>();
sheet.iterator().forEachRemaining(actualList::add); // Gets a list of all the rows
int i = -1;
String[] names = new String[3];
for (Cell cell : rowsList[1]) { // Start at second row
if (i++ > 0) {
names[i] = cell.getStringCellValue();
}
}
testcase1.name = names[0];
testcase2.name = names[1];
testcase3.name = names[2];
i = -1;
int[] ages = new int[3];
for (Cell cell : rowsList[2]) { // Start at Third Row
if (i++ > 0) {
ages[i] = (int) cell.getNumericCellValue();
}
}
testcase1.name = ages[0];
testcase2.name = ages[1];
testcase3.name = ages[2];
I have written a code to pick data for certain area in the input excel and the transpose and paste it in the output excel. This read and write are 2 separate methods, which i call from main method. However, once the code runs and the file is generated, it only shows the data written for the last write method call. As per my understanding, it has to be because, my code is creating a new workbook object every time. Though i have tried to overcome this by using static keyword in my code. Please see below for the code.
public class DataExtractor {
static FileOutputStream output = null;
static XSSFWorkbook workbook = null;
static XSSFSheet sheet = null;
static XSSFWorkbook outputWorkbook = null;
static XSSFSheet outputSheet = null;
static XSSFRow row = null;
DataFormatter dataFormatter = null;
public DataExtractor(XSSFWorkbook workbook, XSSFSheet sheet, XSSFWorkbook outputWorkbook, XSSFSheet outputSheet) {
DataExtractor.workbook = workbook;
DataExtractor.sheet = sheet;
DataExtractor.outputWorkbook = outputWorkbook;
DataExtractor.outputSheet = outputSheet;
}
private ArrayList<ArrayList<String>> fetchDataFromInputExcel(){
//code for fetching data from excel/reading excel only for some grids.
}
private ArrayList<ArrayList<String>> pasteTransposedDataIntoOutputExcel(){
//code for transposing data and pasting it into output excel/writing to excel.
}
public static void main(String args[]){
File file = new File("path of xlsx file");
workbook = new XSSFWorkbook(new FileInputStream(file));
sheet = workbook.getSheet("SHEETNAME");
outputWorkbook = new XSSFWorkbook();
outputSheet = outputWorkbook.createSheet("OUTPUT");
DataExtractor obj = new DataExtractor(workbook, sheet, outputWorkbook, outputSheet);
ArrayList<ArrayList<String>> header = dataExtractor.fetchDataFromInputExcel(//args for mentioning grid area row and col are passed here);
ArrayList<ArrayList<String>> data = dataExtractor.fetchDataFromInputExcel(//args for mentioning grid area row and col are passed here);
dataExtractor.pasteTransposedDataIntoOutputExcel(dataExtractor, data, 1, 8);
dataExtractor.pasteTransposedDataIntoOutputExcel(dataExtractor, header, 1, 1);
output = new FileOutputStream(new File("path of output.xlsx file"));
outputWorkbook.write(output);
}
}
Only dataExtractor.pasteTransposedDataIntoOutputExcel(dataExtractor, header, 1, 1) operation is performed and i do not see the data for the previous one. Please suggest.
Method for transposeAndPaste:
private boolean transposeAndPasteData(DataExtractor dataExtractor, ArrayList<ArrayList<String>> data, int startRowNum, int startColNum){
XSSFCell cell = null;
XSSFRow row = null;
outputWorkbook = dataExtractor.getOutputWorkbook();
outputSheet = dataExtractor.getOutputSheet();
try {
int startRowIndex = startRowNum - 1;
int startColIndex = startColNum - 1;
//paste data row wise
//for(int rowNum = startColNum-1; rowNum<startColNum+data.size(); rowNum++) {}
Iterator<ArrayList<String>> colItr = data.iterator();
while(colItr.hasNext()) {
row = outputSheet.createRow(startRowIndex++);
ArrayList<String> colData = colItr.next();
Iterator<String> rowItr = colData.iterator();
while(rowItr.hasNext()) {
cell = row.createCell(startColIndex++);
cell.setCellValue(rowItr.next());
}
startColIndex = startColNum - 1;
}
dataExtractor.setOutputSheet(outputSheet);
return true;
}catch(Exception e) {
e.printStackTrace();
return false;
}
Thanks,
Aman
I have this code and now what I want to do is I want to do checking if this looping has found the ABC01 then it will continue to loop to look for the '2018'. I tried to do checking and increment like in the code, but it wont work. Please help me.
public static void ReadFile() throws Exception {
FileInputStream file = new FileInputStream(new File("C:xx"));
XSSFWorkbook wb = new XSSFWorkbook(file);
XSSFSheet sheet = wb.getSheetAt(0);
for (Iterator<Row> iterator = sheet.rowIterator(); iterator.hasNext();) {
XSSFRow row = (XSSFRow) iterator.next();
for (int i = 0; i < row.getPhysicalNumberOfCells(); i++) {
XSSFCell cell = row.getCell(i);
DataFormatter formatter = new DataFormatter();
String val = formatter.formatCellValue(cell);
/* System.out.println(val); */
if (val.equals("ABC01")) {
i++;
}
if (val.equals("2018")) {
System.out.print("XX");
}
}
}
}
Based on the discussion in comments, the following code should work for you
public static void ReadFile() throws Exception {
FileInputStream file = new FileInputStream(new File("C:xx"));
XSSFWorkbook wb = new XSSFWorkbook(file);
XSSFSheet sheet = wb.getSheetAt(0);
XSSFRow row = null;
XSSFCell cell = null;
DataFormatter formatter = new DataFormatter();
String val;
for (Iterator<Row> iterator = sheet.rowIterator(); iterator.hasNext();) {
row = (XSSFRow) iterator.next();
for (int i = 0; i < row.getPhysicalNumberOfCells(); i++) {
cell = row.getCell(i);
val = formatter.formatCellValue(cell);
/* System.out.println(val); */
if (val.equals("ABC01")) {
i++;
cell = row.getCell(i);
val = formatter.formatCellValue(cell);
if (val.equals("2018")) {
System.out.print("XX");
}
}
}
}
}
I have the solution to copy .xls workbook in java but not able to copy .xlsx workbook.
Anybody have solution.
I have searched google, stackoverflow and found solution only to copy xls files.
If anyone wants a simpler procedure just use Files.copy:
File originalWb = new File("orginalWb.xlsx");
File clonedWb = new File("clonedWb.xlsx");
Files.copy(originalWb.toPath(), clonedW.toPath());
No need for any bloated code
I didn't test my code. Just wrote it to give you a basic idea of what to do.
public class CopyXSSFWorkbook {
public static void main(String[] args) {
// Read xlsx file
XSSFWorkbook oldWorkbook = null;
try {
oldWorkbook = (XSSFWorkbook) WorkbookFactory.create(new File("old.xlsx"));
} catch (Exception e) {
e.printStackTrace();
return;
}
final XSSFWorkbook newWorkbook = new XSSFWorkbook();
// Copy style source
final StylesTable oldStylesSource = oldWorkbook.getStylesSource();
final StylesTable newStylesSource = newWorkbook.getStylesSource();
oldStylesSource.getFonts().forEach(font -> newStylesSource.putFont(font, true));
oldStylesSource.getFills().forEach(fill -> newStylesSource.putFill(new XSSFCellFill(fill.getCTFill())));
oldStylesSource.getBorders()
.forEach(border -> newStylesSource.putBorder(new XSSFCellBorder(border.getCTBorder())));
// Copy sheets
for (int sheetNumber = 0; sheetNumber < oldWorkbook.getNumberOfSheets(); sheetNumber++) {
final XSSFSheet oldSheet = oldWorkbook.getSheetAt(sheetNumber);
final XSSFSheet newSheet = newWorkbook.createSheet(oldSheet.getSheetName());
newSheet.setDefaultRowHeight(oldSheet.getDefaultRowHeight());
newSheet.setDefaultColumnWidth(oldSheet.getDefaultColumnWidth());
// Copy content
for (int rowNumber = oldSheet.getFirstRowNum(); rowNumber < oldSheet.getLastRowNum(); rowNumber++) {
final XSSFRow oldRow = oldSheet.getRow(rowNumber);
if (oldRow != null) {
final XSSFRow newRow = newSheet.createRow(rowNumber);
newRow.setHeight(oldRow.getHeight());
for (int columnNumber = oldRow.getFirstCellNum(); columnNumber < oldRow
.getLastCellNum(); columnNumber++) {
newSheet.setColumnWidth(columnNumber, oldSheet.getColumnWidth(columnNumber));
final XSSFCell oldCell = oldRow.getCell(columnNumber);
if (oldCell != null) {
final XSSFCell newCell = newRow.createCell(columnNumber);
// Copy value
setCellValue(newCell, getCellValue(oldCell));
// Copy style
XSSFCellStyle newCellStyle = newWorkbook.createCellStyle();
newCellStyle.cloneStyleFrom(oldCell.getCellStyle());
newCell.setCellStyle(newCellStyle);
}
}
}
}
}
try {
oldWorkbook.close();
newWorkbook.write(new FileOutputStream("new.xlsx"));
newWorkbook.close();
} catch (Exception e) {
e.printStackTrace();
return;
}
}
private static void setCellValue(final XSSFCell cell, final Object value) {
if (value instanceof Boolean) {
cell.setCellValue((boolean) value);
} else if (value instanceof Byte) {
cell.setCellValue((byte) value);
} else if (value instanceof Double) {
cell.setCellValue((double) value);
} else if (value instanceof String) {
if (value.startsWith("=")) {
// Formula String
cell.setCellFormula(value.substring(1));
} else {
cell.setCellValue(cstr);
}
} else {
throw new IllegalArgumentException();
}
}
private static Object getCellValue(final XSSFCell cell) {
switch (cell.getCellTypeEnum()) {
case BOOLEAN:
return cell.getBooleanCellValue(); // boolean
case ERROR:
return cell.getErrorCellValue(); // byte
case NUMERIC:
return cell.getNumericCellValue(); // double
case STRING:
case BLANK:
return cell.getStringCellValue(); // String
case FORMULA:
return "=" + cell.getCellFormula(); // String for formula
default:
throw new IllegalArgumentException();
}
}
}
Using Apache POI XSSF library:
public void copyFile(String sourcePath, String destinationPath) throws IOException {
FileInputStream excelFile = new FileInputStream(new File(sourcePath));
Workbook workbook = new XSSFWorkbook(excelFile);
FileOutputStream outputStream = new FileOutputStream(destinationPath);
workbook.write(outputStream);
workbook.close();
}
Clone a workbook in memory (if you can efford it):
public static Workbook cloneWorkbook(final Workbook workbook) {
try {
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(4096);
workbook.write(outputStream);
return WorkbookFactory.create(new ByteArrayInputStream(outputStream.toByteArray()));
} catch (final IOException ex) {
log.warn("Error cloning workbook", ex);
return null; // or throw exception
}
}
Apache POI Busy Developers' Guide to HSSF and XSSF Features
POI performs these steps on XLS/XLSX File. XLS: HSSFWorkbook, XLSX: XSSFWorkbook
Read the File as Stream (FileStream): SystemFile to JavaFileObject
Create a WorkBook form Stream. Stream to XSSFWorkbook-JavaObject
Using POI functions you can perform CURD operations on Java Workbook Object.
Convert Java Workbook Object to file/stream.
NOTE: Index Starts form 0 for Row/Column/Sheet.
Following operations are performed on Sheets:
XLSX File with Sheet1, Sheet2
getSheet_RemoveOthers(Sheet1). XLSX File:Sheet1
public static XSSFSheet getSheet_RemoveOthers(String sourceFileSheetName) {
XSSFSheet srcSheet = workBook.getSheet(sourceFileSheetName);
//Sheet srcSheet = oldWorkbook.getSheetAt(0);
int srcSheetIndex = workBook.getSheetIndex(srcSheet);
System.out.println("srcSheetIndex:"+srcSheetIndex);
int numberOfSheets = workBook.getNumberOfSheets();
for (int indexAt = 0; indexAt < numberOfSheets; indexAt++) {
if (srcSheetIndex == indexAt) {
System.out.println("sourceFileSheetName:"+indexAt);
} else {
String sheetName = workBook.getSheetName(indexAt);
System.out.println("Removing sheetName:"+sheetName);
workBook.removeSheetAt(indexAt);
}
}
System.out.println("getSheetName : "+ srcSheet.getSheetName() );
int totalRows = srcSheet.getPhysicalNumberOfRows();
System.out.println("Total Number of Rows : "+ totalRows );
return srcSheet;
}
XSSFSheet.cloneSheet(Sheet1). XLSX File:Sheet1, Sheet1 (2)
public static XSSFSheet cloneSheet(String sourceFileSheetName) {
Sheet srcSheet = workBook.getSheet(sourceFileSheetName);
int srcSheetIndex = workBook.getSheetIndex(srcSheet);
System.out.println("srcSheetIndex:"+srcSheetIndex);
XSSFSheet cloneSheet = workBook.cloneSheet(srcSheetIndex);
return cloneSheet;
}
Full-Length Example:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
public class POI_XLSX_Report {
static String filePath = "C:/Yash/",
sourceFile = filePath+"POIExcel.xlsx", sourceFileSheetName = "Sheet1",
destinationFile = filePath+"POIExcelCopy.xlsx";
static XSSFWorkbook workBook;
public static void main(String[] args) throws Exception {
File mySrcFile = new File(sourceFile);
FileInputStream stream = new FileInputStream(mySrcFile);
workBook = (XSSFWorkbook) WorkbookFactory.create( stream );
XSSFSheet sheet_RemoveOthers = getSheet_RemoveOthers(sourceFileSheetName);
setSheetValue(sheet_RemoveOthers, 4, 6, "Val2");
// New Sheet with exact copy of Source-Sheet
XSSFSheet cloneSheet = cloneSheet(sourceFileSheetName);
setSheetValue(cloneSheet, 4, 6, "Val2");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
workBook.write( byteArrayOutputStream );
byteArrayOutputStream.close();
File clonedWb = new File(destinationFile);
//Files.copy(mySrcFile.toPath(), clonedWb.toPath()); If a file is already available then throws exception
// Write the output to a file
FileOutputStream fileOutputStream = new FileOutputStream( clonedWb );
byteArrayOutputStream.writeTo(fileOutputStream);
}
public static XSSFSheet getSheet_RemoveOthers(String sourceFileSheetName) {
// ...
}
public static XSSFSheet cloneSheet(String sourceFileSheetName) {
// ...
}
public static void setSheetValue(Sheet sheet, int colIndex, int rowIndex, String value) {
// Row and Column index starts form 0
rowIndex = rowIndex - 1;
colIndex = colIndex - 1;
Row row = sheet.getRow(rowIndex);
if (row == null) {
System.out.println("createRow:");
Row createRow = sheet.createRow(rowIndex);
row= createRow;
}
short lastCellNum = row.getLastCellNum();
System.out.println("Col:"+lastCellNum);
Cell createCell = row.createCell(colIndex, CellType.STRING);
System.out.println("New cell:"+createCell.getStringCellValue());
createCell.setCellValue(value);
}
}