好友
阅读权限 10
听众
最后登录 1970-1-1
本帖最后由 wshy3366 于 2020-8-12 10:03 编辑
导出excel是一个很常用的功能,最常用的实现方式大家也都清楚,都是基于HSSF或者XSSF这些类,只是需要写的代码比较多,实现起来比较繁琐。
最近使用了项目中使用了easy poi,有些优化任务落到自己身上,就顺便看了一些资料,在这里做个大概的总结。
1、首先记录要引入的dependency
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-base</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-web</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
<version>4.0.0</version>
</dependency>
2、在需要导出的方法中使用如下代码:
Workbook workbook = ExcelExportUtil
.exportExcel(exportParams, Data.class, dataList);
dataList是要导出的数据集合,Data是要导出数据实体类
实体类中要导出的变量上可以使用easy poi的@Excel注解,该注解常用的属性有name、width、type等,另外还有一些不常用的,例如isColumnHidden。具体可查看@Excel注解的源码来了解。
exportParams可以设置一些参数,例如通过 ExportParams exportParams = new ExportParams("title","sheetName")指定标题和sheet页
另外可以通过exportParams.setStyle(ExcelStyle.class);来设置自定义的样式,其中ExcelStyle是自己定义的类,可以继承ExcelExportStylerDefaultImpl类 或者实现IExcelExportStyler接口
3、自定义样式
这次遇到的优化需求是将导出的部分列的单元格格式设置为数值,以方便进行运算
为实现这个需求,在网上进行了搜索并做了验证。
方式1:在实体类的变量前通过@Excel注解的type属性来设置,type=10表示数值。这样导出的单元格格式仍然为文本,但是可以进行运算
方式2:在实体类的变量前通过@Excel注解的type属性进行设置,同时在自定义样式类中(实现IExcelExportStyler接口方式)对于type=10的entity通过以下两行代码重新设置单元格格式,设置为整数类型。这样设置后可以进行运算同时单元格格式为自定义了,并且类型为0。
private static final short INTEGER_FORMAT = (short) BuiltinFormats.getBuiltinFormat("0");
style.setDataFormat(INTEGER_FORMAT);
完整代码如下:
public class ExcelStyle implements IExcelExportStyler {
private static final short STRING_FORMAT = (short) BuiltinFormats.getBuiltinFormat("TEXT");
private static final short INTEGER_FORMAT = (short) BuiltinFormats.getBuiltinFormat("0");
private static final short FONT_SIZE_TEN = 10;
private static final short FONT_SIZE_ELEVEN = 11;
private static final short FONT_SIZE_TWELVE = 12;
private CellStyle numberCellStyle;
/**
* 大标题样式
*/
private CellStyle headerStyle;
/**
* 每列标题样式
*/
private CellStyle titleStyle;
/**
* 数据行样式
*/
private CellStyle styles;
public ExcelStyle(Workbook workbook) {
this.init(workbook);
}
/**
* 初始化样式
*
* @Param workbook
*/
private void init(Workbook workbook) {
this.headerStyle = initHeaderStyle(workbook);
this.titleStyle = initTitleStyle(workbook);
this.styles = initStyles(workbook);
this.numberCellStyle = initNumberStyles(workbook);
}
/**
* 大标题样式
*
* @param color
* @return
*/
@Override
public CellStyle getHeaderStyle(short color) {
return headerStyle;
}
/**
* 每列标题样式
*
* @param color
* @return
*/
@Override
public CellStyle getTitleStyle(short color) {
return titleStyle;
}
/**
* 数据行样式
*
* @param parity 可以用来表示奇偶行
* @param entity 数据内容
* @Return 样式
*/
@Override
public CellStyle getStyles(boolean parity, ExcelExportEntity entity) {
if (entity != null
&& 10==entity.getType()) {
return numberCellStyle;
}
return styles;
}
/**
* 获取样式方法
*
* @param dataRow 数据行
* @param obj 对象
* @param data 数据
*/
@Override
public CellStyle getStyles(Cell cell, int dataRow, ExcelExportEntity entity, Object obj, Object data) {
return getStyles(true, entity);
}
/**
* 模板使用的样式设置
*/
@Override
public CellStyle getTemplateStyles(boolean isSingle, ExcelForEachParams excelForEachParams) {
return null;
}
/**
* 初始化--大标题样式
*
* @param workbook
* @return
*/
private CellStyle initHeaderStyle(Workbook workbook) {
CellStyle style = getBaseCellStyle(workbook);
style.setFont(getFont(workbook, FONT_SIZE_TWELVE, true));
return style;
}
/**
* 初始化--每列标题样式
*
* @param workbook
* @return
*/
private CellStyle initTitleStyle(Workbook workbook) {
CellStyle style = getBaseCellStyle(workbook);
style.setFont(getFont(workbook, FONT_SIZE_ELEVEN, false));
//背景色
style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
return style;
}
/**
* 初始化--数据行样式
*
* @param workbook
* @return
*/
private CellStyle initStyles(Workbook workbook) {
CellStyle style = getBaseCellStyle(workbook);
style.setFont(getFont(workbook, FONT_SIZE_TEN, false));
style.setDataFormat(STRING_FORMAT);
return style;
}
/**
* 初始化--数据行样式
*
* @param workbook
* @return
*/
private CellStyle initNumberStyles(Workbook workbook) {
CellStyle style = getBaseCellStyle(workbook);
style.setDataFormat(INTEGER_FORMAT);
return style;
}
/**
* 基础样式
*
* @return
*/
private CellStyle getBaseCellStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
//下边框
style.setBorderBottom(BorderStyle.THIN);
//左边框
style.setBorderLeft(BorderStyle.THIN);
//上边框
style.setBorderTop(BorderStyle.THIN);
//右边框
style.setBorderRight(BorderStyle.THIN);
//水平居中
style.setAlignment(HorizontalAlignment.CENTER);
//上下居中
style.setVerticalAlignment(VerticalAlignment.CENTER);
//设置自动换行
style.setWrapText(true);
return style;
}
/**
* 字体样式
*
* @param size 字体大小
* @param isBold 是否加粗
* @return
*/
private Font getFont(Workbook workbook, short size, boolean isBold) {
Font font = workbook.createFont();
//字体样式
font.setFontName("宋体");
//是否加粗
font.setBold(isBold);
//字体大小
font.setFontHeightInPoints(size);
return font;
}
}
方式3、另外网上还说可以通过ExcelExportEntity对象的setType(BaseEntityTypeConstants.DoubleTYpe)方法设置格式,没有亲测,个人理解和方式1是一样的效果。
方式4、在生成workbook后统一设置默认的格式,没有exportParams.setStyle(ExcelStyle.class);方式设置的优先级高,不太容易区分哪些单元格要设置,哪些单元格不设置。
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, colList, Collections.emptyList());CellStyle textStyle = workbook.createCellStyle();textStyle.setDataFormat(( short ) BuiltinFormats.getBuiltinFormat("TEXT"));Sheet sheet = workbook.getSheet(sheetName); for (int i = 0; i < colList.size(); i++) { sheet.setDefaultColumnStyle(i, textStyle);}
4、总结:easy poi这个开源工具的好处是写的代码少,实现简单,不好的地方就是定制化不同单元格的属性、样式时不太方便。
发帖前要善用【论坛搜索 】 功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。