「这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战」
引言
同事做的导出Excel表格功能,使用Easypoi组件做的,💰类字段导出后,在Excel表格中显示的是文本格式。业务方每次需要手动改成数值格式。看网上的答案说是将@Excel
注解中添加type=10
属性即可,实测无效,所以用其他形式实现,分享一下。大佬勿喷,喷就是水文,为了得一个☕️机。
业务源码
实体类部分
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class ItemExport extends IntegerDomain {
/**
* 应付日期
*/
@Excel(name = "应付日期", orderNum = "0", width = 25)
private LocalDate payableDate;
/**
* 付款单编号
*/
@Excel(name = "付款单编号", orderNum = "1", width = 25)
private String statementNo;
/**
* 付款金额
*/
@Excel(name = "付款金额", orderNum = "2", width = 25, type = 10)
private BigDecimal itemAmountCny;
/**
* 付款金额(原币)
*/
@Excel(name = "付款金额(原币)", orderNum = "3", width = 25, type = 10)
private BigDecimal itemAmount;
/**
* 币种
*/
@Excel(name = "币种", orderNum = "4", width = 25)
private String currency;
/**
* 明细状态
*/
@Excel(name = "明细状态", orderNum = "5", width = 25)
private String itemStatus;
/**
* 财务类型
*/
@Excel(name = "财务类型", orderNum = "6", width = 25)
private String financeType;
/**
* 商务类型
*/
@Excel(name = "商务类型", orderNum = "7", width = 25)
private String businessType;
/**
* 实际支付方式
*/
@Excel(name = "实际支付方式", orderNum = "8", width = 25)
private String bizPayMode;
/**
* 导入支付方式
*/
@Excel(name = "导入支付方式", orderNum = "9", width = 25)
private String importPayMode;
/**
* 实际支付方式
*/
@Excel(name = "资金支付方式", orderNum = "10", width = 25)
private String financePayMode;
/**
* 实际支付时间
*/
@Excel(name = "实际支付时间", orderNum = "11", width = 25)
private String payCompleteDate;
/**
* 付款项目
*/
@Excel(name = "付款项目", orderNum = "12", width = 25)
private String itemTitle;
/**
* 供应商
*/
@Excel(name = "供应商", orderNum = "13", width = 25)
private String supplierName;
/**
* 支付主体
*/
@Excel(name = "支付主体", orderNum = "14", width = 25)
private String companyName;
/**
* 商务
*/
@Excel(name = "商务", orderNum = "15", width = 25)
private String businessName;
/**
* 支出类别
*/
@Excel(name = "支出类别", orderNum = "16", width = 25)
private String expendType;
/**
* 创建时间
*/
@Excel(name = "创建时间", orderNum = "17", width = 25)
private String createdAt;
/**
* 更新时间
*/
@Excel(name = "更新时间", orderNum = "18", width = 25)
private String modifiedAt;
public static List<ItemExport> convertDataList(List<Item> items) {
List<ItemExport> itemExports = new ArrayList<>();
if (CollectionUtils.isEmpty(items)) {
return itemExports;
}
items.forEach(
item -> {
String expendTypeEnum = ExcelUtil.convertEnumMessage("ExpendTypeEnum", Integer.valueOf(item.getExpendType()));
ItemExport export = ItemExport.builder()
.itemStatus(ExcelUtil.convertEnumMessage("ItemStatusEnum", item.getItemStatus()))
.bizPayMode(ExcelUtil.convertEnumMessage("BizPayModeEnum", item.getBizPayMode()))
.importPayMode(ExcelUtil.convertEnumMessage("BizPayModeEnum", item.getImportPayMode()))
.financePayMode(ExcelUtil.convertEnumMessage("PayModeEnum", item.getFinancePayMode()))
.createdAt(item.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
.modifiedAt(item.getModifiedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
.payCompleteDate(item.getPayCompleteDate() == null ? "" : item.getPayCompleteDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
.build();
item.setExpendType(expendTypeEnum);
BeanUtils.copyProperties(item, export);
itemExports.add(export);
}
);
return itemExports;
}
}
导出部分代码:
public void exportPlanItem(HttpServletResponse response, String no){
Long currentTimeMillis = System.currentTimeMillis();
String fileName = currentTimeMillis.toString() + ".xlsx";
try {
Workbook workbook = null;
ExportParams exportParams = new ExportParams();
exportParams.setSheetName("sheet1");
if (StringUtils.isEmpty(no)){
throw new BizRuntimeException(ErrorCode.COMMON_PARAM_ERROR, "no不能为空");
}
Example example = new Example(Item.class);
example.createCriteria().andEqualTo("no", no);
List<Item> items = itemService.find(example);
//
workbook = ExcelExportUtil.exportBigExcel(exportParams, ItemExport.class, ItemExport.convertDataList(items));
// 结束导出
ExcelExportUtil.closeExportBigExcel();
// 写出
ExcelUtil.downLoadExcel(fileName, workbook, response);
} catch (Exception e) {
log.error("导出明细失败:", e);
}
}
解决过程
导出用到的主要元素和依赖关系
使用easypoi 导出excel只用简单的一个方法。
ExcelExportUtil.exportBigExcel(exportParams, ItemExport.class, ItemExport.convertDataList(items));
主要元素列表如下:
名称 | 描述 |
---|---|
ExportParams | 定义导出的文件名,中文名,文件类型,导出样式等。 |
ExcelExportStatisticStyler | 继承自ExcelExportStylerDefaultImpl类,定义样式。通过params.setStyle(ExcelExportStatisticStyler.class); 设置到ExportParams中。如果不指定,默认使用ExcelExportStylerDefaultImpl |
ItemExport | 导出单元格的实体,这里可以设置数据规则 |
既然ExportParams中可以设置导出样式,那继承ExcelExportStylerDefaultImpl
类,重写样式,就可以将导出字段设置为业务需要的格式了。
实现Style
public class ExcelExportStatisticStyle extends ExcelExportStylerDefaultImpl {
private CellStyle numberCellStyle;
public ExcelExportStatisticStyle(Workbook workbook) {
super(workbook);
createNumberCellStyle();
}
private void createNumberCellStyle() {
numberCellStyle = workbook.createCellStyle();
numberCellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
numberCellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
numberCellStyle.setDataFormat((short) BuiltinFormats.getBuiltinFormat("#,##0.00"));
numberCellStyle.setWrapText(true);
}
@Override
public CellStyle getStyles(boolean noneStyler, ExcelExportEntity entity) {
if (entity != null
&& 10==entity.getType()) {
return numberCellStyle;
}
return super.getStyles(noneStyler, entity);
}
}
设置Style
ExportParams exportParams = new ExportParams();
exportParams.setSheetName("sheet1");
exportParams.setStyle(ExcelExportStatisticStyle.class);
导出结果对比
设置Style之前导出的表格,💰字段的单元格格式为:
设置之后导出的表格字段单元格格式为:
问题解决,提交代码。
总结
- 设置文本居中时,可能会出现报错,根据版本不同选择不同的代码实现: 实现1:
numberCellStyle.setAlignment(HorizontalAlignment.CENTER);
numberCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
实现2:
numberCellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); numberCellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
- easypoi支持的格式列表
static {
List<String> m = new ArrayList();
putFormat(m, 0, "General");
putFormat(m, 1, "0");
putFormat(m, 2, "0.00");
putFormat(m, 3, "#,##0");
putFormat(m, 4, "#,##0.00");
putFormat(m, 5, ""$"#,##0_);("$"#,##0)");
putFormat(m, 6, ""$"#,##0_);[Red]("$"#,##0)");
putFormat(m, 7, ""$"#,##0.00_);("$"#,##0.00)");
putFormat(m, 8, ""$"#,##0.00_);[Red]("$"#,##0.00)");
putFormat(m, 9, "0%");
putFormat(m, 10, "0.00%");
putFormat(m, 11, "0.00E+00");
putFormat(m, 12, "# ?/?");
putFormat(m, 13, "# ??/??");
putFormat(m, 14, "m/d/yy");
putFormat(m, 15, "d-mmm-yy");
putFormat(m, 16, "d-mmm");
putFormat(m, 17, "mmm-yy");
putFormat(m, 18, "h:mm AM/PM");
putFormat(m, 19, "h:mm:ss AM/PM");
putFormat(m, 20, "h:mm");
putFormat(m, 21, "h:mm:ss");
putFormat(m, 22, "m/d/yy h:mm");
for(int i = 23; i <= 36; ++i) {
putFormat(m, i, "reserved-0x" + Integer.toHexString(i));
}
putFormat(m, 37, "#,##0_);(#,##0)");
putFormat(m, 38, "#,##0_);[Red](#,##0)");
putFormat(m, 39, "#,##0.00_);(#,##0.00)");
putFormat(m, 40, "#,##0.00_);[Red](#,##0.00)");
putFormat(m, 41, "_("$"* #,##0_);_("$"* (#,##0);_("$"* "-"_);_(@_)");
putFormat(m, 42, "_(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)");
putFormat(m, 43, "_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)");
putFormat(m, 44, "_("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_)");
putFormat(m, 45, "mm:ss");
putFormat(m, 46, "[h]:mm:ss");
putFormat(m, 47, "mm:ss.0");
putFormat(m, 48, "##0.0E+0");
putFormat(m, 49, "@");
String[] ss = new String[m.size()];
m.toArray(ss);
_formats = ss;
}
可以根据需求在numberCellStyle.setDataFormat((short) BuiltinFormats.getBuiltinFormat("#,##0.00"));
处设置需要的导出格式。