Question
In a SXSSF Workbook:
How can I set font?
How can I set celltype to date?
Context
I need to write an excel .xlsx file with a huge amount of rows and columns (400.000 rows, 50 fields each) so I'm using apache poi, SXSSF workbook. I created a test file with this amount of dummy text and it works but I want cells to have a custom font: so if text is somehow representing time cell type should be set to "date" (allowing me to filter rows by date easily).
I wrote a function which allows me to create a cell, check and modify its text type (currency, string, data) based on textType value that I pass to the function. Text type is correctly recognized as I examine data. Currency and text are correctly modified but when I tried to set Font and Data type it doesn't work at all.
(I already have a working function (XSSF) which creates an excel with custom font and different data types included "date", it just can't generate large excel files due to GC overhead, that's why I had to switch to SXSSF)
Error
I get this kind of compile error.
Errors incompatible types;found :
org.apache.poi.ss.usermodel.Font,required:
org.apache.poi.xssf.usermodel.XSSFFont at line 235 (235:40)
incompatible types;found :
org.apache.poi.ss.usermodel.DataFormat,required:
org.apache.poi.xssf.usermodel.XSSFDataFormat at line 271 (271:54)
incompatible types;found :
org.apache.poi.ss.usermodel.DataFormat,required:
org.apache.poi.xssf.usermodel.XSSFDataFormat at line 308 (308:54)
incompatible types;found :
org.apache.poi.ss.usermodel.DataFormat,required:
org.apache.poi.xssf.usermodel.XSSFDataFormat at line 335 (335:54)
incompatible types;found :
org.apache.poi.ss.usermodel.DataFormat,required:
org.apache.poi.xssf.usermodel.XSSFDataFormat at line 375 (375:66)
Since SXSSFFont doesn't exists, I tried to fix it by creating a Font object and then using it instead of XSSFFont.
Same for DataFormat.
But I still find types issues here and there in code.
XSSFFont font = (XSSFFont) workbook.createFont();
XSSFDataFormat df = (XSSFFont) workbook.createDataFormat();
Also tried code above but it doesnt work, I get
ClassCastException error
Code
//[...]
SXSSFWorkbook workbook = new SXSSFWorkbook(100);
Sheet sheet;
Row row;
Cell cell;
//[...]
XSSFFont font = workbook.createFont();
font.setBold(fontBold);
font.setItalic(fontItalic);
font.setFontHeightInPoints( (short) fontSize);
if (!fontUnderline) {
font.setUnderline(FontUnderline.NONE);
}
else {
font.setUnderline(FontUnderline.SINGLE);
}
font.setColor(fontColor);
CellStyle style = workbook.createCellStyle();
style.setFont(font);
//[...]
if (textType == 'T') {
XSSFDataFormat df = workbook.createDataFormat();
style.setDataFormat(df.getFormat("d-mmm-yyyy hh:mi:ss"));
Calendar c = Calendar.getInstance();
c.set(year, month, day, hour, minute,second);
cell.setCellValue(c.getTime());
}
//in the end I set cell value and style
cell.setCellStyle(style);
cell.setCellValue(text);
Here I created a short example using a SXSSFWorkbook and filling 1 cell with a date and applying the proper format as well as a font.
SXSSFWorkbook s = new SXSSFWorkbook();
Font font = s.createFont();
font.setBold(true);
font.setItalic(true);
short dateStyle = s.createDataFormat().getFormat("mm/dd/yy;#");
CellStyle dateCellFormat = s.createCellStyle();
dateCellFormat.setDataFormat(dateStyle);
dateCellFormat.setFont(font);
SXSSFSheet sheet = s.createSheet("Test");
Row r = sheet.createRow(0);
Cell c = r.createCell(0);
c.setCellValue(new Date());
c.setCellStyle(dateCellFormat);
s.write(Files.newOutputStream(Paths.get("D:/test.xlsx"), StandardOpenOption.CREATE_NEW));
s.close();
You will have to make some adjustments, but I hope you get the idea (use the appropriate Interface's)
Related
Need to fill data in Excel template , whcih has Date format style applied to cells. Somehow Date format is not reflecting after filling data in excel cell.
if (cellVal instanceof Date || cellVal instanceof Timestamp) {
cell.setCellValue("20-08-2019"));
CellStyle style = cell.getCellStyle();
cell.setCellStyle(style);
}
Here cell.getCellStyle() to get existing cell style from excel template which should convert date in this format: "20-AUG-19"
issue is even after appying this style cell.setCellStyle(style), Date values style remained same i.e. "20-08-2019"
CellStyle style = cell.getCellStyle();
cell.setCellStyle(style);
you are getting the style of cell variable and setting it again to cell so you're not changing anything at all.
your code should be like that:
CellStyle style = cellVal.getCellStyle(); //cellVal instead of cell
cell.setCellStyle(style);
In my excel sheet many cells contain formulas, i don't want to recalculate these formulas when i read the excel with Apache POI.
The way i do that:
if(cell.getCellType() == XSSFCell.CELL_TYPE_FORMULA) {
//System.out.println("Formula is " + cell.getCellFormula());
switch(cell.getCachedFormulaResultType()) {
case XSSFCell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue() +" ");
break;
case XSSFCell.CELL_TYPE_STRING:
System.out.print(cell.getRichStringCellValue()+" ");
break;
}
}
This helps me in getting the raw value in the cell.
For example if the cell has value 19.5%, this will give me 0.195456 .
I want to get the formatted value.
One way to get the formatted value is:
DataFormatter formatter = new DataFormatter();
System.out.print(formatter.formatCellValue(cell));
This works well for regular cells, but for cells with formulas, this actually gets the formula string and displays it, i.e., it does not get the cached value and formats it, rather it just returns the formula string.
Is there a way to format a value after retrieving it from CELL_TYPE_FORMULA
It's possible to directly format the cached value of a cell without using an evaluator. It's useful in case of values that cannot be recalculated because of third party plugin or unavailable external Data in the cell formula.
This code can be used to do that:
final DataFormatter dataFormatter = new DataFormatter();
final CellStyle cellStyle = cell.getCellStyle();
final String formtatedValue = dataFormatter.formatRawCellContents(cell.getNumericCellValue(), cellStyle.getDataFormat(), cellStyle.getDataFormatString());
System.out.println(formattedValue);
A formatter is still used but the method formatRawCellContents is called to manually format the cell cached value with its style.
It should work if you pass in a FormulaEvaluator in the call to formatCellValue, i.e.
DataFormatter formatter = new DataFormatter();
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
System.out.print(formatter.formatCellValue(cell, evaluator));
We have one existing application where we read one text file and write into excel using java. Text file will have first row as header and subsequent rows as records which is fetched from database.
Currently while writing into excel, all the columns are getting converted into text format. We want to convert one column(consider column Z) as number.
String [] column = line.split("\\|~");
for (int i = 0; i < column.length; i++) {
Cell tmpCell = row.createCell(i);
tmpCell.setCellValue(new HSSFRichTextString(column[i].trim()));
}
I am new to java, need your help in resolving this issue.
Thanks
Santhosh
You can write to cell like this
cell.setCellValue(12345.00000)
But this alone will not be enough in case where you don't want to truncate. Using style and dataformats, you can avoid truncation. E.g.
CellStyle cellStyle = wb.createCellStyle();
DataFormat df = wb.createDataFormat();
cellStyle.setDataFormat(df.getFormat("0.0")); //you can adjust it as per your requirments
cell.setCellStyle(cellStyle);
I need to apply specific data format to cell.
XSSFCellStyle cellStyle = workBook.createCellStyle();
XSSFDataFormat format = workBook.createDataFormat();
cellStyle.setDataFormat(format.getFormat("m/d/yy h:mm"));
dataCell.setCellType(1); //String
dataCell.setCellStyle(cellStyle);
The data is being written but the problem is that the format is applied only when I open excel sheet (in Excel application), click inside the cell with my data.
And then pressing Enter key.
Only then the format is applied.
How can I apply the format without clicking on every cell?
Your problem is that you're setting the cell to be a string. For the most part, cell formatting rules only apply to numeric cells. They don't apply to string cells, those don't get formatted (as they're already formatted to a string!)
XSSFCellStyle cellStyle = workBook.createCellStyle();
XSSFDataFormat format = workBook.createDataFormat();
cellStyle.setDataFormat(format.getFormat("m/d/yy h:mm"));
dataCell.setCellStyle(cellStyle);
// Set Cell Type not really needed, the setCellValue does it
dataCell.setCellType(Cell.CELL_TYPE_NUMERIC);
// Set a date value (2012-06-05 08:50)
dataCell.setCellValue(new Date(1338878999635));
When you open that in Excel, it ought to be have as expected
This is how you change the cell format to Date.
var workBook = new XSSFWorkbook();
var sheet = workBook.CreateSheet("Sheet1");
var dateStyle = workBook.CreateCellStyle();
var dataFormat = workBook.CreateDataFormat();
dateStyle.DataFormat = dataFormat.GetFormat("M/D/YYYY");
row.CreateCell(0).SetCellValue(item.ModifiedDate.HasValue ?
item.ModifiedDate.Value.ToShortDateString(): "");
row.Cells[0].CellStyle = dateStyle; // This will change your cell to date
format.
I'm able to get cells to format as Dates, but I've been unable to get cells to format as currency... Anyone have an example of how to create a style to get this to work? My code below show the styles I'm creating... the styleDateFormat works like a champ while styleCurrencyFormat has no affect on the cell.
private HSSFWorkbook wb;
private HSSFCellStyle styleDateFormat = null;
private HSSFCellStyle styleCurrencyFormat = null;
......
public CouponicsReportBean(){
wb = new HSSFWorkbook();
InitializeFonts();
}
public void InitializeFonts()
{
styleDateFormat = wb.createCellStyle();
styleDateFormat.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy"));
styleCurrencyFormat = wb.createCellStyle();
styleCurrencyFormat.setDataFormat(HSSFDataFormat.getBuiltinFormat("$#,##0.00"));
}
After digging through the documentation a bit more, I found the answer:
http://poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/HSSFDataFormat.html
Just need to find an appropriate pre-set format and supply the code.
styleCurrencyFormat.setDataFormat((short)8); //8 = "($#,##0.00_);[Red]($#,##0.00)"
Here are more examples:
http://www.roseindia.net/java/poi/setDataFormat.shtml
For at least Excel 2010:
Go into Excel. Format a cell they way you want it.
Then go back into the format dialogue. Select custom.
Copy paste the text it has on the top row under Type: into
createHelper.createDataFormat().getFormat("<here>");
Example:
createHelper.createDataFormat().getFormat("_($* #,##0.00_);_($* (#,##0.00);_($* \"-\"??_);_(#_)"); //is the "Accounting" format.
Make sure you set your populate your cells by using a double.
Using the index may cause problems with different versions of Excel. Note that the new format you create above ends up in the custom dialogue from step two.
Just an update to above reply. short '8' doesn't work for me but the '7' does.
cell.setCellValue(416.17);
cellStyle.setDataFormat((short)7);
cell.setCellStyle(cellStyle);
O/P is $416.00
You can try this code to format your cell with currency mode (with thowsand separator like used in Brazil or Germany. Eg. 12.345,67):
HSSFCellStyle cell = yourWorkBook.createCellStyle();
CreationHelper ch = yourWorkBook.getCreationHelper();
cell.setDataFormat(ch.createDataFormat().getFormat("#,##0.00;\\-#,##0.00"));