Easypoi导出金额字段,格式为数值

1,870 阅读4分钟

「这是我参与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之前导出的表格,💰字段的单元格格式为:

image.png 设置之后导出的表格字段单元格格式为:

image.png 问题解决,提交代码。

总结

  • 设置文本居中时,可能会出现报错,根据版本不同选择不同的代码实现: 实现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")); 处设置需要的导出格式。