I am extracting Russian characters from db and generating one excel sheet. But unfortunately in extracted excel sheet, I have to change the character set manually to "UNICODE(UTF-8)" , otherwise I can't able to see Russian character. Is anybody aware how to update this character set through java(I am not asking to convert the value) ?
Let me know if anything needs to be provided from my end.
Is Apache POI an option ?
Apache POI manages the encoding for you. All the text returned is in Java Unicode format (which I believe is UTF-16, and not UTF-8)
Here is how you read Excel sheet in POI:
try {
FileInputStream file = new FileInputStream(new File("C:\\test.xls"));
//Get the workbook instance for XLS file
HSSFWorkbook workbook = new HSSFWorkbook(file);
//Get first sheet from the workbook
HSSFSheet sheet = workbook.getSheetAt(0);
//Iterate through each rows from first sheet
Iterator<Row> rowIterator = sheet.iterator();
while(rowIterator.hasNext()) {
Row row = rowIterator.next();
//For each row, iterate through each columns
Iterator<Cell> cellIterator = row.cellIterator();
while(cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch(cell.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN:
System.out.print(cell.getBooleanCellValue() + "\t\t");
break;
case Cell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue() + "\t\t");
break;
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getStringCellValue() + "\t\t");
break;
}
}
System.out.println("");
}
file.close();
FileOutputStream out =
new FileOutputStream(new File("C:\\test.xls"));
workbook.write(out);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Source: http://viralpatel.net/blogs/java-read-write-excel-file-apache-poi/
Related
I am new to java.I have been trying to automate a website using selenium using TestNG in POM model.I need to enter data for a web form,the data which is stored in a .xlsx file.There are multiple data in multiple columns having o data type string,integer,boolean.I am using Apache POI to extract data from the file using the following code:
ArrayList<Object> arrlist = new ArrayList<Object>(); try {
FileInputStream file = new FileInputStream( new File("C:\\Users\\dell i7\\Desktop\\imp docs\\TestData.xlsx"));
// Create Workbook instance holding reference to .xlsx file
XSSFWorkbook workbook = new XSSFWorkbook(file);
// Get first/desired sheet from the workbook XSSFSheet sheet =
workbook.getSheetAt(0);
// Iterate through each rows one by one
Iterator<Row> rowIterator =sheet.iterator();
while (rowIterator.hasNext())
{ Row row = rowIterator.next(); // For each row, iterate through all the columns
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) { Cell cell = cellIterator.next();
// Check the cell type and format accordingly switch (cell.getCellType()) {
case NUMERIC:
//System.out.println((int) cell.getNumericCellValue());
arrlist.add((int) cell.getNumericCellValue());
break;
case STRING:
System.out.println(cell.getStringCellValue());
arrlist.add(cell.getStringCellValue());
break;
default: break; } }
System.out.println("");
} file.close(); }
catch (Exception e
) {
e.printStackTrace();
}
Now a TestNG Data provider requires an Object[][] to get the data and send it to the Test method.What is the best way to do so?
#DataProvider(name ="Testlogin")
public Object[][] getData()
{
//your data from excel sheet
return data;
}
Initially i have used 4 rows of data and then i deleted the last two rows . The problem is, i am still getting 4 as the total no of rows . What should i do to get updated count .
FileInputStream inputStream = new FileInputStream(new File(excelFilePath));
Workbook workbook = new XSSFWorkbook(inputStream);
Sheet firstSheet = (Sheet) workbook.getSheetAt(0);
System.out.println("No of rows:"+firstSheet.getPhysicalNumberOfRows());
Iterator<Row> iterator = firstSheet.iterator();
try{
while (iterator.hasNext()) {
Row nextRow = iterator.next();
Iterator<Cell> cellIterator = nextRow.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
cell.setCellType(Cell.CELL_TYPE_STRING);
if(!cell.getStringCellValue().isEmpty()){
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
writer.append(cell.getStringCellValue());
break;
}
}
}
}
}finally{
inputStream.close();
workbook.close();
writer.flush();
writer.close();
}
The issue has been cleared by deleting Entire row in the Excel .if you want to delete some data in the excel , please don't just clear contents in the cell instead delete the entire row .
I am trying to read data from one sheet of excel file and write to other sheet of same excel file.I have tried this :
FileInputStream file = new FileInputStream(new File("E:\\excel\\input.xlsx"));
//Create Workbook instance holding reference to .xlsx file
XSSFWorkbook workbook = new XSSFWorkbook(file);
//Get first/desired sheet from the workbook
XSSFSheet sheet = workbook.getSheetAt(0);
//Iterate through each rows one by one
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext())
{
Row row = rowIterator.next();
//For each row, iterate through all the columns
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext())
{
Cell cell = cellIterator.next();
//Check the cell type and format accordingly
switch (cell.getCellType())
{
case Cell.CELL_TYPE_NUMERIC:
System.out.print((int)cell.getNumericCellValue()+ " ");
break;
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getStringCellValue());
break;
}
}
System.out.println("");
}
file.close();
CreationHelper createHelper = workbook.getCreationHelper();
XSSFSheet newSheet = workbook.createSheet("new sheet");
// Create a row and put some cells in it. Rows are 0 based.
Row row = newSheet.createRow((short)0);
// Create a cell and put a value in it.
Cell cell = row.createCell(0);
cell.setCellValue(1);
// Or do it on one line.
row.createCell(1).setCellValue(1.2);
row.createCell(2).setCellValue(
createHelper.createRichTextString("This is a string"));
row.createCell(3).setCellValue(true);
System.out.println("writing to file");
// Write the output to a file
FileOutputStream fileOut = new FileOutputStream(new File("E:\\excel\\input.xlsx"));
workbook.write(fileOut);
fileOut.close();
I have successfully read data from excel sheet But I am getting exception while writing in new sheet given below
java.io.FileNotFoundException: E:\excel\input.xlsx (The process cannot access the file because it is being used by another process)
This will happen when you are trying to execute this program while the "input.xlsx" file is already opened by another application.
Please close any instance of MS Excel and try to run it again
Just a guess but XSSFWorkbook should be implementing Closeable thus it has a .close() that should be called.
Maybe the file result still in use because of that?
You are probably going to need a middle step there: write to a new file, close the XSSFWorkbook and then copy the new file on the old one that you want to write on
My scenario is to get text from "Status" column and based on text comparison ,I want to highlight that particular cell.Below is my code-
private static void colorSheet(String xlsxFileAddress)
{
try
{
FileInputStream file = new FileInputStream(new File(xlsxFileAddress));
//Create Workbook instance holding reference to .xlsx file
XSSFWorkbook workbook = new XSSFWorkbook(file);
//Get first/desired sheet from the workbook
XSSFSheet sheet = workbook.getSheetAt(0);
XSSFFormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
XSSFSheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
//Iterate through each rows one by one
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext())
{
Row row = rowIterator.next();
//For each row, iterate through all the columns
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext())
{
Cell cell = cellIterator.next();
//Check the cell type after eveluating formulae
//If it is formula cell, it will be evaluated otherwise no change will happen
switch (evaluator.evaluateInCell(cell).getCellType())
{
case Cell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue() + "tt");
break;
case Cell.CELL_TYPE_STRING:
{
System.out.print(cell.getStringCellValue() + "tt");
ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(ComparisonOperator.EQUAL,"Extra Rows in new table");
org.apache.poi.ss.usermodel.PatternFormatting fill2 = rule2.createPatternFormatting();
fill2.setFillBackgroundColor(IndexedColors.BLUE.index);
fill2.setFillPattern(PatternFormatting.SOLID_FOREGROUND);
CellRangeAddress[] regions = {
CellRangeAddress.valueOf("A2:A7")
};
sheetCF.addConditionalFormatting(regions, rule2);
break;
}
}
}
System.out.println("");
}
file.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
I want that whichever cell has a text "Extra Rows in new table" should be highlighted in blue but my code is not working.please suggest needful.
Okay, the problem is that you're reading the file and changing its content in the process memory, but you never write the changes back into the file.
Try replacing:
file.close();
with:
file.close();
FileOutputStream writeFile = new FileOutputStream(new File(xlsxFileAddress));
workbook.write(writeFile);
writeFile.close();
It can be because of
ConditionalFormattingRule "Equal" will work only when it is given like ComparisonOperator.EQUAL, "\"" + "Extra Rows in new table" + "\"" instead of (ComparisonOperator.EQUAL,"Extra Rows in new table");
Add this after your file.close() in order to write back to the file.
FileOutputStream writeFile = new FileOutputStream(new
File(xlsxFileAddress));
workbook.write(writeFile);
writeFile.close();
I found plenty of solutions how to convert XLSX to CSV file using Java, all the solutions use: XSSFWorkbook. Problem I am facing is that probably the stream is having too much data. I just don't get why, the file is just 4mb.
CODE:
// For storing data into CSV files
StringBuffer data = new StringBuffer();
try {
FileOutputStream fos = new FileOutputStream(outputFile);
System.out.println("Getting input stream.");
// Get the workbook object for XLS file
XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(inputFile));
System.out.println(" - Done");
// Get first sheet from the workbook
XSSFSheet sheet = workbook.getSheetAt(0);
Cell cell;
Row row;
// Iterate through each rows from first sheet
Iterator<Row> rowIterator = sheet.iterator();
System.out.println(" - Reading xlsx rows.");
while (rowIterator.hasNext()) {
i++;
row = rowIterator.next();
// For each row, iterate through each columns
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
cell = cellIterator.next();
switch (cell.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN:
data.append(cell.getBooleanCellValue() + ";");
break;
case Cell.CELL_TYPE_NUMERIC:
data.append(cell.getNumericCellValue() + ";");
break;
case Cell.CELL_TYPE_STRING:
data.append(cell.getStringCellValue() + ";");
break;
case Cell.CELL_TYPE_BLANK:
data.append("" + ";");
break;
default:
data.append(cell + ";");
}
}
data.append('\n');
int limit = 10000;
if ((i % limit) == 0) {
System.out.println(" - Writing " + limit + " data.");
fos.write(data.toString().getBytes());
fos.flush();
data = null;
data = new StringBuffer();
System.out.println(" - Data written.");
}
}
fos.write(data.toString().getBytes());
fos.flush();
fos.close();
The error is pointing to line in switch statement where I am appending something to data (StringBuffer), but I am nulling it so it shouldn't be an issue.
Now you may not be able to use SXSSFWorkbook (as it's write-only), but you may be able to convert your program to streaming-style using the SAX-based API. Edit: Another thing you may want to try is to create the XSSFWorkbook from File instead of InputStream (I remember reading somewhere that the File-based code needs less memory).
(First try was:
Since you are reading data sequentially the SXSSFWorkbook class should be just the thing you need.)
The xlsx format is just a zip with content xml and shared-strings xml. Hence 4 MB compressed, may well be very large uncompressed.
Using a zip file system you could load the shared strings into memory, and then read content xml sequentially, immediately outputting.
As two inner files are concerned, you might use java's zip file system. Tedious but not difficult.
try this code this one is perfectly working for me i hope that also working for you.
package com.converting;
import java.io.FileInputStream;
import java.io.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import com.opencsv.CSVWriter;
import java.util.Iterator;
import java.io.FileWriter;
public class XlsxtoCSV {
public static void main(String[] args) throws Exception{
FileInputStream input_document = new FileInputStream(new File("/home/blackpearl/Downloads/aa.xlsx"));
XSSFWorkbook my_xls_workbook = new XSSFWorkbook(input_document);
XSSFSheet my_worksheet = my_xls_workbook.getSheetAt(0);
Iterator<Row> rowIterator = my_worksheet.iterator();
FileWriter my_csv=new FileWriter("/home/blackpearl/Downloads/Newaa.csv");
CSVWriter my_csv_output=new CSVWriter(my_csv);
while(rowIterator.hasNext()) {
Row row = rowIterator.next();
int i=0;//String array
String[] csvdata = new String[20];
Iterator<Cell> cellIterator = row.cellIterator();
while(cellIterator.hasNext()) {
Cell cell = cellIterator.next(); //Fetch CELL
switch(cell.getCellType()) { //Identify CELL type
case Cell.CELL_TYPE_STRING:
csvdata[i]= cell.getStringCellValue();
break;
}
i=i+1;
}
my_csv_output.writeNext(csvdata);
}
System.out.println("file imported");
my_csv_output.close(); //close the CSV file
input_document.close(); //close xlsx file
}
}