I have to convert CSV to XLS format through Java POI since I am doing some manipulations with XLS sheets through POI. Below is my code:
File file = new File("C:\\abc.csv");
FileInputStream fin = null;
fin = new FileInputStream(file);
HSSFWorkbook workbook = new HSSFWorkbook(fin);
HSSFSheet firstSheet1 = workbook.getSheetAt(0);
Now I want to write a fuctions, lets say method name is convertcsvtoexcel which will accept the file obj and in return it will be give me converted XLS file that file will be stored in my C: drive with the name abcout.xls and later on I will be passing it to workbook as shown. I have tried the following code. Please advise how I can custoise it to make it fittable for my piece of code.
ArrayList arList = null;
ArrayList al = null;
String fName = "test.csv";
String thisLine;
int count = 0;
FileInputStream file = null;
file = new FileInputStream(new File("C:\\abc.csv"));
//FileInputStream fis = new FileInputStream(file);
DataInputStream myInput = new DataInputStream(file);
int i = 0;
arList = new ArrayList();
while ((thisLine = myInput.readLine()) != null) {
al = new ArrayList();
String strar[] = thisLine.split(",");
for (int j = 0; j < strar.length; j++) {
al.add(strar[j]);
}
arList.add(al);
System.out.println();
i++;
}
try {
HSSFWorkbook hwb = new HSSFWorkbook();
HSSFSheet sheet = hwb.createSheet("new sheet");
for (int k = 0; k < arList.size(); k++) {
ArrayList ardata = (ArrayList) arList.get(k);
HSSFRow row = sheet.createRow((short) 0 + k);
for (int p = 0; p < ardata.size(); p++) {
HSSFCell cell = row.createCell((short) p);
String data = ardata.get(p).toString();
if (data.startsWith("=")) {
cell.setCellType(Cell.CELL_TYPE_STRING);
data = data.replaceAll("\"", "");
data = data.replaceAll("=", "");
cell.setCellValue(data);
} else if (data.startsWith("\"")) {
data = data.replaceAll("\"", "");
cell.setCellType(Cell.CELL_TYPE_STRING);
cell.setCellValue(data);
} else {
data = data.replaceAll("\"", "");
cell.setCellType(Cell.CELL_TYPE_NUMERIC);
cell.setCellValue(data);
}
//*/
// cell.setCellValue(ardata.get(p).toString());
}
System.out.println();
}
FileOutputStream fileOut = new FileOutputStream("C:\\abcout.xls");
hwb.write(fileOut);
fileOut.close();
System.out.println("Your excel file has been generated");
} catch (Exception ex) {
ex.printStackTrace();
} //main method end
public static void csvToXLSX() {
try {
String csvFileAddress = "test.csv"; //csv file address
String xlsxFileAddress = "test.xlsx"; //xlsx file address
XSSFWorkbook workBook = new XSSFWorkbook();
XSSFSheet sheet = workBook.createSheet("sheet1");
String currentLine=null;
int RowNum=0;
BufferedReader br = new BufferedReader(new FileReader(csvFileAddress));
while ((currentLine = br.readLine()) != null) {
String str[] = currentLine.split(",");
RowNum++;
XSSFRow currentRow=sheet.createRow(RowNum);
for(int i=0;i<str.length;i++){
currentRow.createCell(i).setCellValue(str[i]);
}
}
FileOutputStream fileOutputStream = new FileOutputStream(xlsxFileAddress);
workBook.write(fileOutputStream);
fileOutputStream.close();
System.out.println("Done");
} catch (Exception ex) {
System.out.println(ex.getMessage()+"Exception in try");
}
}
Related
I'm trying to write some data inside an existing formatted excel file (.xls).
Inside this file I have 3 sheets and I have to put the data inside the table of the second sheet.
I tried this:
String filename = "Report.xls";
HSSFWorkbook workbook = new HSSFWorkbook();
FileOutputStream fileOut = null;
try {
fileOut = new FileOutputStream(filename);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
int numberOfSheets = workbook.getNumberOfSheets();
System.out.println("Sheets found: " + numberOfSheets);
for(int i=0; i<numberOfSheets; i++) {
HSSFSheet sheet = workbook.getSheetAt(i);
String sheetName= workbook.getSheetName(i);
System.out.println("\n\nSheet with index: " + i
+ "/nHas name: " + sheetName);
}
try {
workbook.write(fileOut);
//closing the Stream
fileOut.close();
//closing the workbook
workbook.close();
} catch (IOException e1) {
e1.printStackTrace();
}
The Excel file has 3 sheets but I get this output:
Sheets found: 0
So I tried this:
String filename = "Report.xls";
InputStream inputStream = null;
Workbook workbook = null;
OutputStream outputStream = null;
try {
inputStream = new FileInputStream(filename);
workbook = WorkbookFactory.create(inputStream);
int Num = workbook.getNumberOfSheets();
System.out.println("Sheets found: " + Num);
for (int i = 0; i < Num; i++) {
Sheet sheet = workbook.getSheetAt(i);
Sheet s = workbook.getSheetAt(i);
String sheetName= s.getSheetName();
System.out.println("The sheet found has name: " + sheetName);
}
} catch (Exception error) {
error.getMessage();
}
But I get the same output..
I can read an Excel sheet vertically and the pass the values to TestNG dataprovide.
This makes TestNG executes each row.
public Object[][] getData(ITestContext context) throws IOException {
Object[][] obj = null;
try {
File file = new File(context.getCurrentXmlTest().getParameter("resource"));
FileInputStream fis = new FileInputStream(file);
XSSFWorkbook wb = new XSSFWorkbook(fis);
XSSFSheet sheet = wb.getSheetAt(0);
wb.close();
int rowCount= sheet.getLastRowNum();
int colCount = sheet.getRow(0).getLastCellNum();
obj = new Object[rowCount][1];
DataFormatter df = new DataFormatter();
for (int i = 0; i < rowCount; i++) {
Map<String, String> datamap= new HashMap<String, String>();
for (int j = 0; j < colCount; j++) {
String a = df.formatCellValue(sheet.getRow(0).getCell(j));
String b = df.formatCellValue(sheet.getRow(i+1).getCell(j));
if(!b.equals(""))
datamap.put(a, b);
if(b.equals("[PWD]")) {
b=PropertiesFile.getProperty("psw");
byte[] byteArray = Base64.decodeBase64(b.getBytes());
String decodedString = new String(byteArray);
b=decodedString;
datamap.put(a, b);
}
}
obj[i][0] =datamap;
}
}catch(Exception e){
e.printStackTrace();
}
return obj;
}
I'd like to read it horizontally, so that TestNG executes each column (the first column would be the keys column), how can i do?
Thanks
You can transpose your sheet and work with former columns which are now the rows: How to transpose sheet with POI SS/XSSF?
Or just change your loop nesting so that you go by columns in the outer loops. Not by rows.
I think i solved it
public Object[][] getData(ITestContext context) throws IOException {
Object[][] obj = null;
try {
File file = new File(context.getCurrentXmlTest().getParameter("resource"));
FileInputStream fis = new FileInputStream(file);
XSSFWorkbook wb = new XSSFWorkbook(fis);
XSSFSheet sheet = wb.getSheetAt(0);
wb.close();
int rowCount= sheet.getLastRowNum();
int colCount = sheet.getRow(0).getLastCellNum();
obj = new Object[colCount-1][1];
DataFormatter df = new DataFormatter();
for (int i = 0; i < colCount-1; i++) {
Map<String, String> datamap= new HashMap<String, String>();
for (int j = 0; j < rowCount+1; j++) {
String a = df.formatCellValue(sheet.getRow(j).getCell(0));
String b = df.formatCellValue(sheet.getRow(j).getCell(i+1));
System.out.println(a+ " "+b);
if(!b.equals(""))
datamap.put(a, b);
if(b.equals("[PWD]")) {
b=PropertiesFile.getProperty("psw");
byte[] byteArray = Base64.decodeBase64(b.getBytes());
String decodedString = new String(byteArray);
b=decodedString;
datamap.put(a, b);
}
}
obj[i][0] =datamap;
}
}catch(Exception e){
e.printStackTrace();
}
return obj;
}
I'm converting CSV file to XLS file.
When I do the conversion, everything works perfect; however, when there's a comma inside the cell, it separates a column into two columns.
EX:
| Hello, World! | CSV FILE |
after conversion
| Hello | World! | CSV FILE | X --- What I get currently
| Hello, World! | CSV FILE | O --- What I want
String ab = thisLine.replaceAll(", ", " ");
Assuming everyone uses space after using a comma, replaceAll would work but this is not an ideal solution.
public void csv2excel(String csv) throws Exception
{
String inputCSVFile = csv + ".csv";
ArrayList arList=null;
ArrayList al=null;
String fName = inputCSVFile;
String thisLine;
int count=0;
FileInputStream fis = new FileInputStream(fName);
DataInputStream myInput = new DataInputStream(fis);
int i=0;
arList = new ArrayList();
while ((thisLine = myInput.readLine()) != null)
{
al = new ArrayList();
//String ab = thisLine.replaceAll(", ", " ");
//String strar[] ab.split(",");
String strar[] = thisLine.split(",");
//Here is where I split the columns.
for(int j=0;j<strar.length;j++)
{
al.add(strar[j]);
}
arList.add(al);
i++;
}
try
{
HSSFWorkbook hwb = new HSSFWorkbook();
HSSFSheet sheet = hwb.createSheet("new sheet");
for(int k=0;k<arList.size();k++)
{
ArrayList ardata = (ArrayList)arList.get(k);
HSSFRow row = sheet.createRow((short) 0+k);
for(int p=0;p<ardata.size();p++)
{
HSSFCell cell = row.createCell((short) p);
String data = ardata.get(p).toString();
if(data.startsWith("=")){
cell.setCellType(CellType.STRING);
data=data.replaceAll("\"", "");
data=data.replaceAll("=", "");
cell.setCellValue(data);
}else if(data.startsWith("\"")){
data=data.replaceAll("\"", "");
cell.setCellType(CellType.STRING);
cell.setCellValue(data);
}else{
data=data.replaceAll("\"", "");
cell.setCellType(CellType.NUMERIC);
cell.setCellValue(data);
}
//*/
// cell.setCellValue(ardata.get(p).toString());
}
}
FileOutputStream fileOut = new FileOutputStream(csv + ".xls");
hwb.write(fileOut);
fileOut.close();
} catch ( Exception ex ) {
ex.printStackTrace();
}
myInput.close();
fis.close();
}
I wonder if there's just a way to split column by column.
public void csv2excel(String csv) throws Exception
{
String inputCSVFile = csv + ".csv";
ArrayList arList=null;
ArrayList al=null;
String fName = inputCSVFile;
String thisLine;
int count=0;
FileInputStream fis = new FileInputStream(fName);
DataInputStream myInput = new DataInputStream(fis);
int i=0;
arList = new ArrayList();
while ((thisLine = myInput.readLine()) != null)
{
al = new ArrayList();
StringBuilder myLine = new StringBuilder(thisLine);
int lineLength = thisLine.length();
int bool = 0;
for (int k = 0; k < lineLength; k++)
{
if (thisLine.charAt(k) == '"')
{
bool++;
}
else if (thisLine.charAt(k) == ',' && bool % 2 != 0)
{
myLine.setCharAt(k, ' ');
}
}
//System.out.println(myLine);
//String ab = thisLine.replaceAll(", ", " ");
String strar[] = myLine.toString().split(",");
for(int j=0;j<strar.length;j++)
{
al.add(strar[j]);
}
arList.add(al);
i++;
}
try
{
HSSFWorkbook hwb = new HSSFWorkbook();
HSSFSheet sheet = hwb.createSheet("new sheet");
for(int k=0;k<arList.size();k++)
{
ArrayList ardata = (ArrayList)arList.get(k);
HSSFRow row = sheet.createRow((short) 0+k);
for(int p=0;p<ardata.size();p++)
{
HSSFCell cell = row.createCell((short) p);
String data = ardata.get(p).toString();
if(data.startsWith("=")){
cell.setCellType(CellType.STRING);
data=data.replaceAll("\"", "");
data=data.replaceAll("=", "");
cell.setCellValue(data);
}else if(data.startsWith("\"")){
data=data.replaceAll("\"", "");
cell.setCellType(CellType.STRING);
cell.setCellValue(data);
}else{
data=data.replaceAll("\"", "");
cell.setCellType(CellType.NUMERIC);
cell.setCellValue(data);
}
//*/
// cell.setCellValue(ardata.get(p).toString());
}
}
FileOutputStream fileOut = new FileOutputStream(csv + ".xls");
hwb.write(fileOut);
fileOut.close();
} catch ( Exception ex ) {
ex.printStackTrace();
}
myInput.close();
fis.close();
}
I coded to work around it...
Looks ugly, but works...
Would like to know if anyone has better answer.
I am making a program where I would read data from multiple excel files and store the data in tables. I have managed to make this program and works fine when the user give the full path of the file. What I am trying to do now is the user would give the directory of where all the excel files are, automatically find all the .xls files and do the rest program for each of them (read the data, create the table and insert the data in it).
The code for the user to give the path and print all the .xls files is:
String dirpath = "";
Scanner scanner1 = new Scanner(System.in);
while (true) {
System.out.println("Please give the directory:");
dirpath = scanner1.nextLine();
File fl = new File(dirpath);
if (fl.canRead()) break;
System.out.println("Error:Directory does not exists");
}
try{
String files;
File folder = new File(dirpath);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
files = listOfFiles[i].getName();
if (files.endsWith(".xls") || files.endsWith(".XLS")) {
System.out.println(files);
}
}
}
}catch (Exception e){
System.out.println();
}
How I would get each one of these file to continue in the rest program?
What I am doing next is described in the code below:
List sheetData = new ArrayList();
FileInputStream fis = null;
try {
fis = new FileInputStream(strfullPath);
HSSFWorkbook workbook = new HSSFWorkbook(fis);
HSSFSheet sheet = workbook.getSheetAt(0);
Iterator rows = sheet.rowIterator();
while (rows.hasNext()) {
HSSFRow row = (HSSFRow) rows.next();
Iterator cells = row.cellIterator();
List data = new ArrayList();
while (cells.hasNext()) {
HSSFCell cell = (HSSFCell) cells.next();
data.add(cell);
}
sheetData.add(data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
fis.close();
}
}
After this code I am creating the table and after that I am filling it with the data.
Wrap the code into a method and instead of
System.out.println(files);
call this method and pass listOfFiles[i].
You can add the the XLS files to a list of files then iterate it for the xls file processing code.
//Delcare
List<File> xlsFiles = new ArrayList<File>();
//Add the below code in the if loop
xlsFiles.add(listOfFiles[i])
for(File xlsFile : xlsFiles){
List sheetData = new ArrayList();
FileInputStream fis = null;
try {
fis = new FileInputStream(xlsFile);
}
Regards,
Dinesh.R
You can read data from excel file and it will usable for further execution process.
Please find following example for the same.
private void getSpecificExcelWSheetDataList(String absolutePath) {
LogLoader.serverLog.trace("In getSpecificExcelWSheetDataList() [File Location : " + absolutePath + "]");
try {
File file = new File(absolutePath);
if (!file.isAbsolute()) {
LogLoader.serverLog.error("Source file does not exist");
} else if (!file.canRead()) {
LogLoader.serverLog.error("Source file doesn't have permission for read operation");
} else {
FileInputStream ExcelFile = new FileInputStream(absolutePath);
excelWBook = new XSSFWorkbook(ExcelFile);
Iterator<Sheet> sheetIterator = excelWBook.sheetIterator();
while (sheetIterator.hasNext()) {
XSSFSheet excelWSheet = (XSSFSheet) sheetIterator.next();
Iterator<Row> rowIterator = excelWSheet.rowIterator();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
if (row.getRowNum() != 0) {
this.serviceProcessData = new ServiceProcessData();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
int columnIndex = cell.getColumnIndex();
String cellValue = dataFormatter.formatCellValue(cell).trim();
System.out.println("Row Number :"+row.getRowNum()
+"Column Number :"+columnIndex
+"Value : "+cellValue);
}
}
}
}
}
} catch (Exception e) {
LogLoader.errorLog.error(e.getMessage(), e);
LogLoader.serverLog.error(e.getMessage());
}
LogLoader.serverLog.trace("Out getSpecificExcelWSheetDataList()");
}
This part of my code was creating xls file successfuly
FileOutputStream fileOut = new FileOutputStream("c:\\Decrypted.xls");
wb.write(fileOut);
fileOut.close();
when other part of the code had this statement ( which was before the above code )
in = new ByteArrayInputStream(theCell_00.getBytes(""));
But when I changed it to
in = new ByteArrayInputStream(theCell_00.getBytes("UTF-8"));
this part
FileOutputStream fileOut = new FileOutputStream("c:\\Decrypted.xls");
wb.write(fileOut);
fileOut.close();
is not generating any xls file anymore.
I need to change the encoding to UTF-8 as I have done in ByteArrayInputStream line, so what should I do that the code still generates xls file.
In case you need it, the two parts are taken from this function.
public void getExcel() throws Exception {
try {
ByteArrayInputStream in = null;
FileOutputStream out = null;
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
/*
* KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128); SecretKey key =
* kgen.generateKey(); byte[] encoded = key.getEncoded();
*
* IOUtils.write(encoded, new FileOutputStream(new
* File("C:\\Users\\abc\\Desktop\\key.txt")));
*/
FileInputStream fin = new FileInputStream("C:\\key.txt");
DataInputStream din = new DataInputStream(fin);
byte b[] = new byte[16];
din.read(b);
InputStream excelResource = new FileInputStream(path);
Workbook rwb = Workbook.getWorkbook(excelResource);
int sheetCount = rwb.getNumberOfSheets();
Sheet rs = rwb.getSheet(0);
int rows = rs.getRows();
int cols = rs.getColumns();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < Col.length; j++) {
String theCell_00 = rs.getCell(j, i).getContents();
System.out.println("the Cell Content : " + theCell_00);
in = new ByteArrayInputStream(theCell_00.getBytes(""));
out = new FileOutputStream("c:\\Decrypted.txt");
try {
// System.out.println(b);
SecretKey key1 = new SecretKeySpec(b, "AES");
// Create encrypter/decrypter class
AESDecrypter encrypter = new AESDecrypter(key1);
encrypter.encrypt(new ByteArrayInputStream(theCell_00.getBytes()),
new FileOutputStream("temp.txt"));
// Decrypt
// encrypter.encrypt(,new FileOutputStream("Encrypted.txt"));
encrypter.decrypt(in, out);
try {
if (out != null)
out.close();
} finally {
if (in != null)
in.close();
}
// encrypter.decrypt(new
// ByteArrayInputStream(theCell_00.getBytes(Latin_1)),new
// FileOutputStream("c:\\Decrypted.txt"));
String filename = "c:\\Decrypted.txt";
BufferedReader bufferedReader = null;
try {
// Construct the BufferedReader object
bufferedReader = new BufferedReader(new FileReader(filename));
// System.out.println(bufferedReader.readLine());
String line = null;
while ((line = bufferedReader.readLine()) != null) {
// Process the data, here we just print it out
/*
* HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet =
* wb.createSheet("new sheet"); HSSFRow row = sheet.createRow(2);
*/
// System.out.println(i);
HSSFRow row = sheet.createRow(i);
int s_col = 0;
row.createCell(s_col).setCellValue(line);
// s_col++;
// row.createCell(1).setCellValue(new Date());
FileOutputStream fileOut = new FileOutputStream("c:\\Decrypted.xls");
wb.write(fileOut);
fileOut.close();
// System.out.println(line);
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
// Close the BufferedReader
try {
if (bufferedReader != null)
bufferedReader.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
rwb.close();
} catch (Exception ex) {
ex.printStackTrace();
ex.getMessage();
}
}
What data types are expected by the call to AESDecrypter.decrypt? Does it have to take in a FileOutputStream object? Or can you pass in a Writer or other OutputStream?
I normally do something like this to write UTF-8 output:
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("c:\\Decrypted.txt"), "UTF-8"));