您好,欢迎来到汇智旅游网。
搜索
您的当前位置:首页EasyExcel导出表格处理日期格式,数字格式,字体和大小设置(日期导出后无法日期筛选问题)

EasyExcel导出表格处理日期格式,数字格式,字体和大小设置(日期导出后无法日期筛选问题)

来源:汇智旅游网
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
EasyExcel.write(byteArrayOutputStream, ExportVO.class).sheet("data").registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).registerWriteHandler(new CommonExcelCellHandler(ExportVO.getHandleColumns())).doWrite(dataList);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());

  1. ExportVO
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.NumberFormat;
import com.alibaba.excel.annotation.write.style.ContentStyle;
import com.alibaba.excel.annotation.write.style.HeadFontStyle;
import com.alibaba.excel.annotation.write.style.HeadStyle;
import com.alibaba.excel.enums.BooleanEnum;
import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum;
import com.shoplife.life.didi.util.DateConverter;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@HeadFontStyle(fontName = "宋体",bold = BooleanEnum.FALSE,fontHeightInPoints =11)
@HeadStyle( fillForegroundColor = )
public class ExportMerchantCommonOrderVO implements Serializable {

    private static final long serialVersionUID = -2880421630771568703L;

    /**
     * 订单编号
     */
    @ExcelProperty(value = "订单编号")
    private String orderCode;

    /**
     * 创建时间
     */
    @ExcelProperty(value = "创建时间", converter = DateConverter.class)
    private Date createTime;

    /**
     * 订单金额
     */
    @ExcelProperty(value = "订单金额")
    //处理数据格式,保留几位小数,小数点后几个0,下划线和空格不能去除
    @NumberFormat("0.00_ ")
    private BigDecimal orderPrice;
    
    /**
     * 付款积分
     */
    @ExcelProperty(value = "付款积分")
    //处理数据格式,保留几位小数,小数点后几个0,下划线和空格不能去除
    @NumberFormat("0_ ")
    private BigDecimal payPoint;


    /**
     * 获取需要处理的日期字段,处理excel表格内单元格格式,可以进行日期筛选
     * @return
     */
    public static Map<String, Object> getHandleColumns(){
        Map<String, Object> map = new HashMap<>(3);
        map.put("dateTimeColumns", new String[]{"创建时间"});
        map.put("dateColumns", new String[]{});
        map.put("numberColumns", new String[]{});
        return map;
    }
}
  1. DateConverter
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * excel导出日期转化类
 */
public class DateConverter implements Converter<Date> {

    private static final String PATTERN_YYYY_MM_DD_HH_mm_ss = "yyyy/MM/dd HH:mm:ss";

    @Override
    public Class<?> supportJavaTypeKey() {
        return Converter.super.supportJavaTypeKey();
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return Converter.super.supportExcelTypeKey();
    }

    @Override
    public WriteCellData<?> convertToExcelData(Date value, ExcelContentProperty contentProperty,GlobalConfiguration globalConfiguration) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat(PATTERN_YYYY_MM_DD_HH_mm_ss);
        String dateValue = sdf.format(value);
        return new WriteCellData<>(dateValue);
    }
}
  1. CommonExcelCellHandler
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import com.alibaba.excel.write.metadata.style.WriteFont;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.poi.ss.usermodel.*;

/**
 * Excel 导出处理日期格式与数值类型 调用端需要将三个参数 dateColumns、dateTimeColumns、numberColumns 传进来,构造方法进行初始化 注意:仅需要对导出的
 * excel 日期筛选以及数值合计有问题的列传入即可,没问题的列可以不用传入 数值类型有问题的,主要原因是 dto 里定义的是 String 类型导致,如果是 double 与 Integer
 * 类型则正常导出不需要传入处理
 *
 * @author liumingxing
 */
@Slf4j
public class CommonExcelCellHandler implements CellWriteHandler {

    /**
     * 列名存储列表 数据量超过500时,会刷新缓存,表头会丢失,所以要存一下,以便查找
     */
    private static final List<String> COLUMNS = new ArrayList<>();

    /**
     * 时间+日期样式存储 一个excel的sheet页,最多可以创建000个样式,频繁创建会倒是程序报错
     */
    private CellStyle dateTimeStyle;
    /**
     * 时间样式存储 一个excel的sheet页,最多可以创建000个样式,频繁创建会倒是程序报错
     */
    private CellStyle dateStyle;
    /**
     * 金额样式存储 一个excel的sheet页,最多可以创建000个样式,频繁创建会倒是程序报错 数值类型有问题的,主要原因是 dto 里定义的是 String 类型导致,如果是
     * double 与 Integer 类型则正常导出不需要传入处理
     */
    private CellStyle numberStyle;

    /**
     * 需要处理日期列名
     */
    private Object dateColumns;
    /**
     * 需要处理日期含时间的列名
     */
    private Object dateTimeColumns;
    /**
     * 需要处理数值的列名
     */
    private Object numberColumns;

    /**
     * 列宽时需要乘256
     */
    private Integer widthCommon = 256;

    /**
     * 初始化参数 注意:数值类型传入前提是列dto里数值类型的字段定义的是字符串类型(如果定义的是double或intger则不需要转换)
     *
     * @param map 传入需要特殊处理的三个类型 dateColumns、dateTimeColumns、numberColumns
     */
    public CommonExcelCellHandler(Map<String, Object> map) {
        COLUMNS.clear();
        dateTimeStyle = null;
        dateStyle = null;
        numberStyle = null;

        this.dateColumns = map.get("dateColumns");
        this.dateTimeColumns = map.get("dateTimeColumns");
        this.numberColumns = map.get("numberColumns");
    }

    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder,
                                 WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex,
                                 Integer relativeRowIndex, Boolean isHead) {

    }

    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder,
                                WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex,
                                Boolean isHead) {

    }

    @Override
    public void afterCellDispose(CellWriteHandlerContext context) {

        Cell cell = context.getCell();
        Boolean isHead = context.getHead();
        WriteSheetHolder writeSheetHolder = context.getWriteSheetHolder();
        // 列宽
        int width = 20;

        if (isHead != null && isHead) {
            //获取表头,存储起来,否则但数据超过500时会 flush 导致列名丢失报错
            COLUMNS.add(cell.getStringCellValue());
        } else if (isHead != null) {
            // 当前列名
            String columnName = COLUMNS.get(cell.getColumnIndex());

            //是否是日期加时间
            boolean dateTimeFlag = StringUtils.isNotBlank(Arrays.stream(
                            (String[]) dateTimeColumns).filter(item -> item.equals(columnName)).findAny()
                    .orElse(""));

            //是否是日期
            boolean dateFlag = StringUtils.isNotBlank(
                    Arrays.stream((String[]) dateColumns).filter(item -> item.equals(columnName))
                            .findAny().orElse(""));

            //是否是数值(前提:要处理的列dto里得是字符串类型)
            boolean numberColumnFlag = StringUtils.isNotBlank(
                    Arrays.stream((String[]) numberColumns).filter(item -> item.equals(columnName))
                            .findAny().orElse(""));

            // 日期类标识
            boolean dateFlags = dateTimeFlag || dateFlag;

            if (dateFlags || numberColumnFlag) {
                Workbook wk = writeSheetHolder.getSheet().getWorkbook();

                String stringCellValue = null;
                try {
                    stringCellValue = cell.getStringCellValue();
                } catch (Exception e) {
                    // double或integer 类型数值不需要转换单元格格式,前端不要传入,后台直接去掉转换解决!
                    dateFlags = false;
                }
                try {
                    CreationHelper createHelper = wk.getCreationHelper();
                    if (StringUtils.isNotBlank(stringCellValue) && dateFlags) {
                        String[] patterns = {"yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd"};
                        Date date = DateUtils.parseDate(stringCellValue, patterns);
                        if (dateTimeFlag) {
                            width = 20;
                            //订单生成日期
                            if (dateTimeStyle == null) {
                                dateTimeStyle = wk.createCellStyle();
                                //设置表格内日期格式
                                dateTimeStyle.setDataFormat(createHelper.createDataFormat().getFormat("yyyy/mm/dd hh:mm:ss"));
                                //设置表格样式
                                Font font = writeSheetHolder.getSheet().getWorkbook().createFont();
                                //设置字体大小
                                font.setFontHeight((short) (11 * 20));
                                //设置字体
                                font.setFontName("Calibri");
                                dateTimeStyle.setFont(font);
                            }
                            cell.setCellStyle(dateTimeStyle);
                        }
//                        else {
//                            //其他日期列
//                            width = 15;
//                            if (dateStyle == null) {
//                                dateStyle = wk.createCellStyle();
//                            }
//                            dateStyle.setDataFormat(
//                                    createHelper.createDataFormat().getFormat("yyyy/mm/dd"));
//                            cell.setCellStyle(dateStyle);
//                        }
                        //设置表格内容
                        cell.setCellValue(date);
                        //设置列宽
                        writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), width * widthCommon);
                    }
//                    else if (StringUtils.isNotBlank(stringCellValue) && numberColumnFlag && isNumber(stringCellValue)) {
//                        //其他数值列(数值类型有问题的,主要原因是 dto 里定义的是 String 类型导致,如果是 double 与 Integer 类型则正常导出不需要传入处理)
//                        width = 11;
//                        double money = Double.parseDouble(stringCellValue);
//                        if (numberStyle == null) {
//                            numberStyle = wk.createCellStyle();
//                        }
//                        numberStyle
//                                .setDataFormat(createHelper.createDataFormat().getFormat("0.00"));
//                        cell.setCellStyle(numberStyle);
//                        cell.setCellValue(money);
//                    }
                    // 由于这里没有指定dataformat 最后展示的数据 格式可能会不太正确
                    // 这里要把 WriteCellData的样式清空, 不然后面还有一个 FillStyleCellWriteHandler 默认会将 WriteCellStyle 设置到
                    // cell里面去 会导致自己设置的不一样
                    context.getFirstCellData().setWriteCellStyle(null);

                    // 统一处理列宽
//                    int columnWidth = writeSheetHolder.getSheet()
//                            .getColumnWidth(cell.getColumnIndex());
//                    if (columnWidth < width * widthCommon) {
//                        writeSheetHolder.getSheet()
//                                .setColumnWidth(cell.getColumnIndex(), width * widthCommon);
//                    }
                } catch (ParseException e) {
                    log.info("导出信息时出现错误:值:{},行:{},列:{},Exception:{}", stringCellValue,
                            cell.getRow().getRowNum(), cell.getColumnIndex(),e.getMessage());
                    cell.setCellValue("");
                }
            }
        }


        afterCellDispose(context.getWriteSheetHolder(), context.getWriteTableHolder(), context.getCellDataList(),
                context.getCell(), context.getHeadData(), context.getRelativeRowIndex(), context.getHead());
    }

    /**
     * 判断一个字符串是否是数字。
     *
     * @param value
     * @return
     */
    public static boolean isNumber(String value) {
        String regex = "^-?\\d+(\\.\\d+)?$";
        Pattern pattern = Pattern.compile(regex);
        return pattern.matcher(value).matches();
    }
}

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- hzar.cn 版权所有 赣ICP备2024042791号-5

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务