I want to display some text with superscript into Excel cell. I tried to pass the HTML string to XSSFRichTextString but it displays the HTML string as it is in the output file.
I'm using Apache POI 3.16
Screenshot to explain the requirement
You are thinking, RichTextString should be able to interpret HTML? It is not. It is only able to apply Font from startIndex to endIndex. And Font can be marked using TypeOffset SS_SUPER.
Example:
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import java.io.FileOutputStream;
class RichTextSuperscript {
public static void main(String[] args) {
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet("Sheet1");
Font fontRed = wb.createFont();
fontRed.setColor(Font.COLOR_RED);
Font fontRedSuperscript = wb.createFont();
fontRedSuperscript.setColor(Font.COLOR_RED);
fontRedSuperscript.setTypeOffset(Font.SS_SUPER);
String string = "Level 3";
RichTextString richString = new XSSFRichTextString( "Level 13" );
//^0 ^7
richString.applyFont(7, 8, fontRedSuperscript);
for (int r = 0; r < 10; r++) {
Row row = sheet.createRow(r);
Cell cell = row.createCell(0);
if ((r%2) == 0) {
cell.setCellValue(string);
} else {
CellUtil.setFont(cell, fontRed);
cell.setCellValue(richString);
}
}
try {
wb.write(new FileOutputStream("RichTextSuperscript.xlsx"));
wb.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Related
I've a simple method to read csv and convert it to Excel:
public static void main(String[] args) throws Exception {
CSVReader csvReader = new CSVReader(new FileReader("P:\\employees.csv"));
SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook();
SXSSFSheet sxssfSheet = sxssfWorkbook.createSheet("Sheet");
String[] dataRow = null;
int rowNum = 0;
while ((dataRow = csvReader.readNext()) != null) {
Row currentRow = sxssfSheet.createRow(rowNum);
for (int i = 0; i < dataRow.length; i++) {
String cellValue = dataRow[i];
currentRow.createCell(i).setCellValue(cellValue);
}
rowNum++;
}
sxssfWorkbook.write(new FileOutputStream("P:\\employees.xlsx"));
}
But there's a problem with cell data type. All my data now represents as text. I want to find columns by their name (for example age, paid_total), not by index, and set numeric (float) data type for these columns. Something like this (sorry for sql-like style, for me it's a simplier to describe): WHEN columnName IN ('age', 'paid_total') SET allColumnType AS NUMERIC. How can I do this? Or it's only possible with indexes?
CSV files always are plain text files without data types. But if you exactly know which column should be which data type, then a type safe Excel sheet can be created. This can be achieved by column indes as well as by column header. To detect types by column header, those headers wolud must be into a separate data structure. But this will always be benefical.
Let's take the example employees.csv from here: https://gist.github.com/kevin336/acbb2271e66c10a5b73aacf82ca82784.
Then following should work:
import java.io.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.xssf.streaming.*;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import com.opencsv.CSVReader;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeFormatter;
import java.time.LocalDate;
class CreateExcelFromCSVDifferentDataTypes {
public static void main(String[] args) throws Exception {
try (
SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(); FileOutputStream fileout = new FileOutputStream("./employees.xlsx");
CSVReader csvReader = new CSVReader(new FileReader("./employees.csv"));
) {
sxssfWorkbook.setCompressTempFiles(true);
CellStyle dateStyle = sxssfWorkbook.createCellStyle();
dateStyle.setDataFormat(sxssfWorkbook.getCreationHelper().createDataFormat().getFormat("dd-MMM-yy"));
SXSSFSheet sxssfSheet = sxssfWorkbook.createSheet("Sheet");
sxssfSheet.setRandomAccessWindowSize(100);
String[] strHeaders = null;
String[] dataRow = null;
int rowNum = 0;
while ((dataRow = csvReader.readNext()) != null) {
if (rowNum == 0) strHeaders = dataRow;
Row currentRow = sxssfSheet.createRow(rowNum);
for (int i = 0; i < dataRow.length; i++) {
String cellValue = dataRow[i];
if (rowNum > 0 && "HIRE_DATE".equals(strHeaders[i])) {
DateTimeFormatter formatter= new DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern("dd-MMM-yy").toFormatter(java.util.Locale.ENGLISH);
LocalDate localDate = LocalDate.parse(cellValue, formatter);
currentRow.createCell(i).setCellValue(localDate);
currentRow.getCell(i).setCellStyle(dateStyle);
} else if (rowNum > 0 && "SALARY".equals(strHeaders[i])) {
double d = Double.valueOf(cellValue);
currentRow.createCell(i).setCellValue(d);
} else {
currentRow.createCell(i).setCellValue(cellValue);
}
}
rowNum++;
}
sxssfWorkbook.write(fileout);
sxssfWorkbook.dispose();
}
}
}
EDIT1: I have an ExcelUtility.java class to get cell data from it and pass it on to the tests methods in my test class.
I am reading from 1 excel file.
The excel file has 3 worksheets.
Every worksheet has 1 unique working table inside.
I have 1 Test class.
The test class has 3 test methods.
The test class contains 3 dataProviders.
All dataProviders differ in the worksheet name and working table name.
The tests in the test class are written in the following manner:
#Test(priority = 0, dataProvider = "dp1")
public void test01(String...strings){
}
#Test(priority = 1, dataProvider = "dp2")
public void test02(String...strings){
}
#Test(priority = 2, dataProvider = "dp3")
public void test03(String...strings){
}
I have the following java class to read from XLSX file using apache poi jars:
public class ExcelUtility {
private static XSSFWorkbook ExcelWBook;
private static XSSFSheet ExcelWSheet;
/*
* Set the File path, open Excel file
* #params - Excel Path and Sheet Name
*/
public static void setExcelFile(String path, String sheetName) throws Exception {
try {
// Open the Excel file
FileInputStream ExcelFile = new FileInputStream(path);
// Access the excel data sheet
ExcelWBook = new XSSFWorkbook(ExcelFile);
ExcelWSheet = ExcelWBook.getSheet(sheetName);
} catch (Exception e) {
throw (e);
}
}
public static String[][] getTestData(String tableName) {
String[][] testData = null;
try {
// Handle numbers and strings
DataFormatter formatter = new DataFormatter();
XSSFCell[] boundaryCells = findCells(tableName);
XSSFCell startCell = boundaryCells[0];
XSSFCell endCell = boundaryCells[1];
int startRow = startCell.getRowIndex() + 1;
int endRow = endCell.getRowIndex() - 1;
int startCol = startCell.getColumnIndex() + 1;
int endCol = endCell.getColumnIndex() - 1;
testData = new String[endRow - startRow + 1][endCol - startCol + 1];
for (int i=startRow; i<endRow+1; i++) {
for (int j=startCol; j<endCol+1; j++) {
// testData[i-startRow][j-startCol] = ExcelWSheet.getRow(i).getCell(j).getStringCellValue();
Cell cell = ExcelWSheet.getRow(i).getCell(j);
testData[i - startRow][j - startCol] = formatter.formatCellValue(cell);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return testData;
}
public static XSSFCell[] findCells(String tableName) {
DataFormatter formatter = new DataFormatter();
String pos = "begin";
XSSFCell[] cells = new XSSFCell[2];
for (Row row : ExcelWSheet) {
for (Cell cell : row) {
// if (tableName.equals(cell.getStringCellValue())) {
if (tableName.equals(formatter.formatCellValue(cell))) {
if (pos.equalsIgnoreCase("begin")) {
cells[0] = (XSSFCell) cell;
pos = "end";
} else {
cells[1] = (XSSFCell) cell;
}
}
}
}
return cells;
}
}
In order to read from the excel file I have organized the test methods in the following manner:
#DataProvider(name = "dp1")
public Object[][] dp1() throws IOException {
Object[][] testData = new Object[0][];
try {
ExcelUtility.setExcelFile(Constants.File_Path+Constants.File_Name, "Page1");
testData = ExcelUtility.getTestData("P1");
} catch (Exception e) {
e.printStackTrace();
}
return testData;
}
#DataProvider(name = "dp2")
public Object[][] dp2() throws IOException {
Object[][] testData = new Object[0][];
try {
ExcelUtility.setExcelFile(Constants.File_Path+Constants.File_Name, "Page2");
testData = ExcelUtility.getTestData("P2");
} catch (Exception e) {
e.printStackTrace();
}
return testData;
}
#DataProvider(name = "dp3")
public Object[][] dp3() throws IOException {
Object[][] testData = new Object[0][];
try {
ExcelUtility.setExcelFile(Constants.File_Path+Constants.File_Name, "Page3");
testData = ExcelUtility.getTestData("P3");
} catch (Exception e) {
e.printStackTrace();
}
return testData;
}
#Test(priority = 0, dataProvider = "dp1")
public void test01(String...strings){
//read data from excel and pass the value to the strings added as arguments in the method above
}
#Test(priority = 1, dataProvider = "dp2")
public void test02(String...strings){
}
#Test(priority = 2, dataProvider = "dp3")
public void test03(String...strings){
}
What I would like to do is the following:
Read first row data from sheet1, pass it to test1, continue to test2
Read first row data from sheet2, pass it to test2, continue to test3
Read first row data from sheet3, pass it to test3, continue to test1
Read second row data from sheet 1, pass it to test1, continue to test2
And so on, depending of number of rows in the excel sheets.
What happens is:
The first test is executed, reads worksheet 1, row 1.
The first test is executed, reads worksheet 1, row 2.
The second test is executed, reads worksheet 2, row 1.
The second test is executed, reads worksheet 2, row 2.
All tests fail because they are dependable from each other, that is why I set execution priority.
Should I change something in the Test class, or something in the ExcelUtility.java class should be changed?
Thank you in advance!
See files related to the commit
It creates testng.xml based on xlsx with test data.
This is actually not a question but solution proposal: I found workaround to read set of data from excel. in this case there is no need for multiple users or data variation but read parameters to create a validation environment.
ok, solution is to save excel file to html format and then let the Selenium IDE to read parameters from that. Users needs only to agree the same filename to be used.
1) you should add "Apache POI" jar files in order to read your excel through java.
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
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 ExcelReadExample {
#SuppressWarnings({ "unchecked", "rawtypes" })
public static void main(String[] args) throws Exception {
String filename = "E:\\data.xls";
List sheetData = new ArrayList();
FileInputStream fis = null;
try {
fis = new FileInputStream(filename);
XSSFWorkbook workbook = new XSSFWorkbook(fis);
XSSFSheet sheet = workbook.getSheetAt(0);
Iterator rows = sheet.rowIterator();
while (rows.hasNext()) {
XSSFRow row = (XSSFRow) rows.next();
Iterator cells = row.cellIterator();
List data = new ArrayList();
while (cells.hasNext()) {
XSSFCell cell = (XSSFCell) cells.next();
data.add(cell);
}
sheetData.add(data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
fis.close();
}
}
showExelData(sheetData);
}
private static void showExelData(List sheetData) {
int sum = 0;
for (int i = 0; i < sheetData.size(); i++) {
List<XSSFCell> list = (List) sheetData.get(i);
for (int j = 0; j < list.size(); j++) {
XSSFCell cell = (XSSFCell) list.get(j);
if(cell.getCellType()==0)
{
sum += cell.getNumericCellValue();
}
}
System.out.println("");
System.out.println("Sum Value is:" +sum);
}
}
}
Change the file path.
i hve mentioned my sheet name as "input" change it as per yours
Happy excelling :D
Today This is the demo to show data from CSV for DAT file without make custom class on tableView in JavaFX 2.0. I call this TableView as Dynamic TableView because the tableview automatically manages the columns and rows.
On my research about the editable on tableView we must have a custom class and implement it to tableView to show as this demo ==> http://docs.oracle.com/javafx/2/ui_controls/table-view.htm
But in this case I can not do it because we don't know how many column example with csv file or .dat file.... I want to do editable on this tableView in this case by add TextField into TableCell. How does it do without make custom class (because you do not how many column ...), and if it must make custom class then how about the design of custom class for this case?
Could you please help me?
private void getDataDetailWithDynamic() {
tblView.getItems().clear();
tblView.getColumns().clear();
tblView.setPlaceholder(new Label("Loading..."));
// #Override
try {
File aFile = new File(txtFilePath.getText());
InputStream is = new BufferedInputStream(new FileInputStream(aFile));
Reader reader = new InputStreamReader(is, "UTF-8");
BufferedReader in = new BufferedReader(reader);
final String headerLine = in.readLine();
final String[] headerValues = headerLine.split("\t");
for (int column = 0; column < headerValues.length; column++) {
tblView.getColumns().add(
createColumn(column, headerValues[column]));
}
// Data:
String dataLine;
while ((dataLine = in.readLine()) != null) {
final String[] dataValues = dataLine.split("\t");
// Add additional columns if necessary:
for (int columnIndex = tblView.getColumns().size(); columnIndex < dataValues.length; columnIndex++) {
tblView.getColumns().add(createColumn(columnIndex, ""));
}
// Add data to table:
ObservableList<StringProperty> data = FXCollections
.observableArrayList();
for (String value : dataValues) {
data.add(new SimpleStringProperty(value));
}
tblView.getItems().add(data);
}
} catch (Exception ex) {
System.out.println("ex: " + ex.toString());
}
for(int i=0; i<tblView.getColumns().size(); i++) {
TableColumn col = (TableColumn)tblView.getColumns().get(i);
col.setPrefWidth(70);
}
}
private TableColumn createColumn(
final int columnIndex, String columnTitle) {
TableColumn column = new TableColumn(DefaultVars.BLANK_CHARACTER);
String title;
if (columnTitle == null || columnTitle.trim().length() == 0) {
title = "Column " + (columnIndex + 1);
} else {
title = columnTitle;
}
Callback<TableColumn, TableCell> cellFactory = new Callback<TableColumn, TableCell>() {
#Override
public TableCell call(TableColumn p) {
System.out.println("event cell");
EditingCellData cellExtend = new EditingCellData();
return cellExtend;
}
};
column.setText(title);
column.setCellValueFactory(cellFactory);
return column;
}
Thanks for your reading.
This is the best way to resolve it ==> https://forums.oracle.com/message/11216643#11216643
I'm really thank for your reading about that.
Thanks
I have an excel file of 111 rows. I need to omit first two rows of the sheet and then read the file using java and POI.
You have to skip first two rows using rownum().Here is the sample code
HSSFWorkbook workBook = new HSSFWorkbook (fileSystem);
HSSFSheet sheet = workBook.getSheetAt (0);
Iterator<HSSFRow> rows = sheet.rowIterator ();
while (rows.hasNext ())
{
HSSFRow row = rows.next ();
// display row number in the console.
System.out.println ("Row No.: " + row.getRowNum ());
if(row.getRowNum()==0 || row.getRowNum()==1){
continue; //just skip the rows if row number is 0 or 1
}
}
Here is the complete example
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
public class POIExcelReader
{
/** Creates a new instance of POIExcelReader */
public POIExcelReader ()
{}
#SuppressWarnings ("unchecked")
public void displayFromExcel (String xlsPath)
{
InputStream inputStream = null;
try
{
inputStream = new FileInputStream (xlsPath);
}
catch (FileNotFoundException e)
{
System.out.println ("File not found in the specified path.");
e.printStackTrace ();
}
POIFSFileSystem fileSystem = null;
try
{
fileSystem = new POIFSFileSystem (inputStream);
HSSFWorkbook workBook = new HSSFWorkbook (fileSystem);
HSSFSheet sheet = workBook.getSheetAt (0);
Iterator<HSSFRow> rows = sheet.rowIterator ();
while (rows.hasNext ())
{
HSSFRow row = rows.next ();
if(row.getRowNum()==0 || row.getRowNum()==1){
continue; //just skip the rows if row number is 0 or 1
}
// once get a row its time to iterate through cells.
Iterator<HSSFCell> cells = row.cellIterator ();
while (cells.hasNext ())
{
HSSFCell cell = cells.next ();
System.out.println ("Cell No.: " + cell.getCellNum ());
/*
* Now we will get the cell type and display the values
* accordingly.
*/
switch (cell.getCellType ())
{
case HSSFCell.CELL_TYPE_NUMERIC :
{
// cell type numeric.
System.out.println ("Numeric value: " + cell.getNumericCellValue ());
break;
}
case HSSFCell.CELL_TYPE_STRING :
{
// cell type string.
HSSFRichTextString richTextString = cell.getRichStringCellValue ();
System.out.println ("String value: " + richTextString.getString ());
break;
}
default :
{
// types other than String and Numeric.
System.out.println ("Type not supported.");
break;
}
}
}
}
}
catch (IOException e)
{
e.printStackTrace ();
}
}
public static void main (String[] args)
{
POIExcelReader poiExample = new POIExcelReader ();
String xlsPath = "c://test//test.xls";
poiExample.displayFromExcel (xlsPath);
}
}
Apache POI provides two ways to access the rows and cells in an Excel file. One is an iterator that gives you all the entries, the other is to loop up by index. (POI will also tell you the start/end rows/columns). The iterator is often simpler to use, but both are equally as fast.
If you have specific requirements on rows to fetch, I'd suggest you use the latter. Your code would want to be something like:
int FIRST_ROW_TO_GET = 2; // 0 based
Sheet s = wb.getSheetAt(0);
for (int i = FIRST_ROW_TO_GET; i < s.getLastRowNum(); i++) {
Row row = s.getRow(i);
if (row == null) {
// The whole row is blank
}
else {
for (int cn=row.getFirstCellNum(); cn<row.getLastCellNum(); cn++) {
Cell c = row.getCell(cn, Row.RETURN_BLANK_AS_NULL);
if (c == null) {
// The cell is empty
} else {
// Process the cell
}
}
}
}
you can improve Murali N s answer. If you want to skip 40 rows for example, use:
if (currentRow.getRowNum() <= 40) {
continue;
}