I am pretty new to Apache POI, I wonder how to do that Format Painter operation to format a cell into Date format, each time when I try to copy the date format of cell, in POI, it can only give me Numeric, I wonder how can I keep the date format?
// Get source cell type and style
CellType type_from = cell_from.getCellTypeEnum();
CellStyle style_from = cell_from.getCellStyle();
// Get source cell data format
short df = style_from.getDataFormat();
// Change dest cell cell type, set format on it
cell_to.setCellType(type_from);
CellStyle style_to = cell_to.getCellStyle();
style_to.setDataFormat(df);
cell_to.setCellStyle(style_to);
And I need to change some other style, like border, background color, font italic, etcs. Could you give out one example: create one xlsx file, set 1A to number( say 10 ), 2A to text ("10") 1B to date(01/12/2018), 2B to 10000(just a number), then try to turn 2A into number with font 16 and green cell background, and turn 2B into date with same format as 1B but italic font.
As said in comment already, the issue is not reproducible having your code snippet only. That shows why Minimal, Complete, and Verifiable examples are necessary.
I suspect the following: You are having the snippet in a loop and do changing the same style style_to
multiple times having different style_from
as source. This is possible since multiple cells cell_to
may sharing the same style.
Manipulating cell styles for Excel
spreadsheets is not as simple as one may think. The cell styles are stored on workbook level and are limited to 64,000 unique cell formats/cell styles in modern Excel
versions. So one must be careful with new creating cell styles. At least one should not trying creating a new cell style for each single cell.
Apache poi
provides CellUtil which has various utility functions that make working with a cells and rows easier. The various methods that deal with style's allow you to create your CellStyle
s as you need them. When you apply a style change to a cell, the code will attempt to see if a style already exists that meets your needs. If not, then it will create a new style. This is to prevent creating too many styles. What lacks until now is the same utility functions for dealing with fonts. Fonts also are on workbook level and so also should not being created without care.
The following example provides utility functions for creating fonts too.
It takes the ExcelTest.xlsx
as you had described in your last comment and makes the changings you also had described there. It also makes some additional changings to show how the utility functions are working.
Source:
Code:
import java.io.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.CellUtil;
import java.util.Map;
import java.util.HashMap;
public class ExcelSetCellStyleDataFormat {
//method for getting current font from cell
private static Font getFont(Cell cell) {
Workbook wb = cell.getRow().getSheet().getWorkbook();
CellStyle style = cell.getCellStyle();
return wb.getFontAt(style.getFontIndex());
}
private enum FontProperty {
BOLD, COLOR, FONTHEIGHT, FONTNAME, ITALIC, STRIKEOUT, TYPEOFFSET, UNDERLINE
}
//method for getting font having special settings additional to given source font
private static Font getFont(Workbook wb, Font fontSrc, Map<FontProperty, Object> fontproperties) {
boolean isBold = fontSrc.getBold();
short color = fontSrc.getColor();
short fontHeight = fontSrc.getFontHeight();
String fontName = fontSrc.getFontName();
boolean isItalic = fontSrc.getItalic();
boolean isStrikeout = fontSrc.getStrikeout();
short typeOffset = fontSrc.getTypeOffset();
byte underline = fontSrc.getUnderline();
for (FontProperty property : fontproperties.keySet()) {
switch (property) {
case BOLD:
isBold = (boolean)fontproperties.get(property);
break;
case COLOR:
color = (short)fontproperties.get(property);
break;
case FONTHEIGHT:
fontHeight = (short)fontproperties.get(property);
break;
case FONTNAME:
fontName = (String)fontproperties.get(property);
break;
case ITALIC:
isItalic = (boolean)fontproperties.get(property);
break;
case STRIKEOUT:
isStrikeout = (boolean)fontproperties.get(property);
break;
case TYPEOFFSET:
typeOffset = (short)fontproperties.get(property);
break;
case UNDERLINE:
underline = (byte)fontproperties.get(property);
break;
}
}
Font font = wb.findFont(isBold, color, fontHeight, fontName, isItalic, isStrikeout, typeOffset, underline);
if (font == null) {
font = wb.createFont();
font.setBold(isBold);
font.setColor(color);
font.setFontHeight(fontHeight);
font.setFontName(fontName);
font.setItalic(isItalic);
font.setStrikeout(isStrikeout);
font.setTypeOffset(typeOffset);
font.setUnderline(underline);
}
return font;
}
public static void main(String[] args) throws Exception {
Workbook wb = WorkbookFactory.create(new FileInputStream("ExcelTest.xlsx"));
DataFormatter formatter = new DataFormatter();
Sheet sheet = wb.getSheetAt(0);
Row row = null;
Cell cell = null;
Font font = null;
Map<String, Object> styleproperties = null;
Map<FontProperty, Object> fontproperties = null;
//turn cell A2 into numeric, font size 16pt and green fill color:
//get cell A2
row = CellUtil.getRow(1, sheet);
cell = CellUtil.getCell(row, 0);
//get old cell value and set it as numeric
String cellvalue = formatter.formatCellValue(cell);
cell.setCellValue(Double.valueOf(cellvalue));
//get the needed font
fontproperties = new HashMap<FontProperty, Object>();
fontproperties.put(FontProperty.FONTHEIGHT, (short)(16*20));
font = getFont(wb, getFont(cell), fontproperties);
//set new cell style properties
styleproperties = new HashMap<String, Object>();
styleproperties.put(CellUtil.DATA_FORMAT, BuiltinFormats.getBuiltinFormat("General"));
styleproperties.put(CellUtil.FILL_FOREGROUND_COLOR, IndexedColors.GREEN.getIndex());
styleproperties.put(CellUtil.FILL_PATTERN, FillPatternType.SOLID_FOREGROUND);
styleproperties.put(CellUtil.FONT, font.getIndex());
CellUtil.setCellStyleProperties(cell, styleproperties);
//get data format from B1
row = CellUtil.getRow(0, sheet);
cell = CellUtil.getCell(row, 1);
short dataFormatB1 = cell.getCellStyle().getDataFormat();
//turn B2 into same data format as B1 and italic font:
//get cell B2
row = CellUtil.getRow(1, sheet);
cell = CellUtil.getCell(row, 1);
//get the needed font
fontproperties = new HashMap<FontProperty, Object>();
fontproperties.put(FontProperty.ITALIC, true);
font = getFont(wb, getFont(cell), fontproperties);
//set new cell style properties
styleproperties = new HashMap<String, Object>();
styleproperties.put(CellUtil.DATA_FORMAT, dataFormatB1);
styleproperties.put(CellUtil.FONT, font.getIndex());
CellUtil.setCellStyleProperties(cell, styleproperties);
//set new cell D6 having special font settings
row = CellUtil.getRow(5, sheet);
cell = CellUtil.getCell(row, 3);
fontproperties = new HashMap<FontProperty, Object>();
fontproperties.put(FontProperty.BOLD, true);
fontproperties.put(FontProperty.COLOR, IndexedColors.BLUE.getIndex());
fontproperties.put(FontProperty.FONTHEIGHT, (short)(20*20));
fontproperties.put(FontProperty.FONTNAME, "Courier New");
fontproperties.put(FontProperty.STRIKEOUT, true);
fontproperties.put(FontProperty.UNDERLINE, Font.U_DOUBLE);
font = getFont(wb, getFont(cell), fontproperties);
styleproperties = new HashMap<String, Object>();
styleproperties.put(CellUtil.FONT, font.getIndex());
CellUtil.setCellStyleProperties(cell, styleproperties);
cell.setCellValue("new cell");
//set new cell C4 having special font settings
row = CellUtil.getRow(3, sheet);
cell = CellUtil.getCell(row, 2);
fontproperties = new HashMap<FontProperty, Object>();
fontproperties.put(FontProperty.BOLD, true);
fontproperties.put(FontProperty.COLOR, IndexedColors.DARK_RED.getIndex());
fontproperties.put(FontProperty.FONTHEIGHT, (short)(42*20));
fontproperties.put(FontProperty.FONTNAME, "Times New Roman");
fontproperties.put(FontProperty.ITALIC, true);
font = getFont(wb, getFont(cell), fontproperties);
styleproperties = new HashMap<String, Object>();
styleproperties.put(CellUtil.FONT, font.getIndex());
CellUtil.setCellStyleProperties(cell, styleproperties);
//set rich textt string into that cell
RichTextString richString = new XSSFRichTextString("E = m c2");
//^0 ^7
fontproperties = new HashMap<FontProperty, Object>();
fontproperties.put(FontProperty.TYPEOFFSET, Font.SS_SUPER);
font = getFont(wb, getFont(cell), fontproperties);
richString.applyFont(7, 8, font);
cell.setCellValue(richString);
wb.write(new FileOutputStream("ExcelTestNew.xlsx"));
wb.close();
}
}
Result: