由于作者没有提供样式的解决办法,我使用writerHandle进行解决,我自己测试通过,但是不同场景下难免会有BUG,这里算是提供思路了 xlsx和xls字体类的问题,所以这个代码只支持xlsx的,如果要支持xls可以进行修改 版本要求 1.12-beta5 以上
准备首先定义样式注解,我只定义了部分常用样式
注解1 CellStyleFormat
/**
* @author luoxiao22525
* @date 2019-1-8
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CellStyleFormat {
/**
* 水平居中方式 默认左居中
* @see HorizontalAlignment
*/
HorizontalAlignment horizontalalignment() default HorizontalAlignment.LEFT;
/**
*
* 垂直居中方式 默认居中
* @see VerticalAlignment
*/
VerticalAlignment verticalAlignment() default VerticalAlignment.CENTER;
/**
* 边框方式 默认无
* @see BorderStyle
*/
BorderStyle borderStyle() default BorderStyle.NONE;
/**
* 边框颜色 默认白
* @see IndexedColors
*/
IndexedColors borderColor() default IndexedColors.WHITE;
/**
* 字体设置
* @see org.apache.poi.xssf.usermodel.XSSFFont
* @see org.apache.poi.hssf.usermodel.HSSFFont
*/
CellFontFormat cellFont() default @CellFontFormat();
/**
* 背景颜色
* @see IndexedColors
*/
IndexedColors fillBackgroundColor() default IndexedColors.WHITE;
/**
* 单元格是否换行
*/
boolean warpText() default false;
}
注解2 CellFontFormat 字体类型注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CellFontFormat {
String fontName() default "宋体";
short fontHeightInPoints() default 11;
IndexedColors fontColor() default IndexedColors.BLACK;
}
编写自定义writerhandler
/**
* @author luoxiao22525
* @param <T> 必须是继承BaseRowModel类的class
*/
public class PreWriterHandler<T extends Class<? extends BaseRowModel>> implements WriteHandler {
private T rowModel;
private Map<Integer, CellStyleFormat> colStyleFormat = new HashMap<>();
private Map<Integer, CellStyle> colStyle = new HashMap<>();
private Map<String, String> infos = new HashMap<>();
public static final String TITLE_NUM = "title_num";
public PreWriterHandler(T rowModel) {
this.rowModel = rowModel;
init(rowModel);
}
private void init(T rowModel) {
Field[] declaredFields = rowModel.getDeclaredFields();
//查找有CellStyle注解和ExcelProperty注解的Field加入cellStyle
int titleNum = 0;
for (Field field : declaredFields) {
CellStyleFormat cellStyle = field.getAnnotation(CellStyleFormat.class);
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
if (excelProperty != null) {
titleNum =Math.max(excelProperty.value().length, titleNum);
}
if (cellStyle == null || excelProperty == null) {
continue;
}
colStyleFormat.put(excelProperty.index(), cellStyle);
}
infos.put(TITLE_NUM, String.valueOf(titleNum));
}
@Override
public void sheet(int sheetNo, Sheet sheet) {
// 只初始化一次
if (sheetNo == 1) {
colStyle = colStyleFormat.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, x -> {
CellStyle cellStyle = sheet.getWorkbook().createCellStyle();
CellStyleFormat value = x.getValue();
//居中方式
cellStyle.setVerticalAlignment(value.verticalAlignment());
cellStyle.setAlignment(value.horizontalalignment());
// 设置边框
cellStyle.setBorderBottom(value.borderStyle());
cellStyle.setBorderLeft(value.borderStyle());
cellStyle.setBorderRight(value.borderStyle());
cellStyle.setBorderTop(value.borderStyle());
cellStyle.setBottomBorderColor(value.borderColor().getIndex());
cellStyle.setLeftBorderColor(value.borderColor().getIndex());
cellStyle.setRightBorderColor(value.borderColor().getIndex());
cellStyle.setTopBorderColor(value.borderColor().getIndex());
// 设置字体
XSSFFont font = (XSSFFont) sheet.getWorkbook().createFont();
font.setFontName(value.cellFont().fontName());
font.setColor(value.cellFont().fontColor().getIndex());
font.setFontHeightInPoints(value.cellFont().fontHeightInPoints());
cellStyle.setFont(font);
// 设置单元格是否换行
cellStyle.setWrapText(value.warpText());
// 背景颜色
cellStyle.setFillBackgroundColor(value.fillBackgroundColor().getIndex());
return cellStyle;
},
(u, v) -> v));
}
}
@Override
public void row(int rowNum, Row row) {
}
@Override
public void cell(int cellNum, Cell cell) {
CellStyle cellStyle = colStyle.get(cellNum);
// 表头不操作 行序号是从0开始的
if (cell.getRowIndex() <= Integer.valueOf(infos.get(TITLE_NUM))-1) {
return;
}
// 没有不操作
if (cellStyle == null) {
return;
}
//设置居中方式
cell.setCellStyle(cellStyle);
}
}
使用
以上准备完毕,现在给实体类添加注解,以右居中为例 注意必须有@ExcelProperty并且是从0开始,支持多行表头 这个例子里 eeee和 ffff进行的样式修改,进行右居中
public class demoExport extends BaseRowModel {
private static final long serialVersionUID = 1L;
@ExcelProperty(value = "aaaaa",index = 0)
private String aaaaa;
@ExcelProperty(value = "bbbb",index = 1)
private String bbbbb;
@ExcelProperty(value = "cccc",index = 2)
private String ccccc;
@ExcelProperty(value = "dddd",index = 3)
private String dddd;
@ExcelProperty(value = "eeee",index = 4)
@CellStyleFormat(horizontalalignment = HorizontalAlignment.RIGHT)
private String eeee;
@CellStyleFormat(horizontalalignment = HorizontalAlignment.RIGHT)
@ExcelProperty(value = "ffff",index = 5)
private String ffffff;
最后进行调用,只需要writer获取方式修改一下
ExcelWriter writer = EasyExcelFactory.getWriterWithTempAndHandler(null, out, ExcelTypeEnum.XLSX, true, new PreWriterHandler<>(demoExport .class));
我自己还弄了一个数字类型格式化的注解,这个如果有需要我再分享吧