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());
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;
}
}
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);
}
}
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
本站由北京市万商天勤律师事务所王兴未律师提供法律服务