公司最近有个需求 就是将day这一列 变为excel表格表头,然后列显示薪水。
然后再到网上找教程最终终于找到相关的大神写的博客,具体网址忘记了。抱歉。现在写下具体教程。
- ExcelHead 代码
import lombok.Data;
/**
* @author hunterhou
* @date 2023/2/28 10:14
*/
@Data
public class ExcelHead<T> {
//内容里的字段名称
private String fieldName;
//显示值,一般为中文的
private String title;
private T nullValue; //如果为null情况下要显示的值
public ExcelHead(String fieldName, String title) {
this.fieldName = fieldName;
this.title = title;
}
public ExcelHead(String fieldName, String title, T nullValue) {
this.fieldName = fieldName;
this.title = title;
this.nullValue = nullValue;
}
}
ExcelUtils
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.google.common.collect.Lists;
import com.ltu.util.easyexcel.HorizontalCellStyleStrategy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author hunterhou
* @date 2023/2/28 9:18
*/
public class ExcelUtils<T> {
// public static void main(String[] args) {
// String filePath = "d:\\temp\\a.xlsx";
List<ExcelHead> headList = new ArrayList();
headList.add(new ExcelHead<String>("23-05-05", "23-05-05",""));
headList.add(new ExcelHead<String>("23-05-06", "23-05-06", ""));
List<Map<String, Object>> dataList = new ArrayList();
Map<String, Object> one = new HashMap();
one.put("23-05-05", "285.65");
one.put("23-05-06", "257.36");
dataList.add(one);
Map<String, Object> two = new HashMap();
two.put("23-05-05", "283.65");
two.put("23-05-06", "25712.36");
dataList.add(two);
// Map<String, Object> there = new HashMap();
// there.put("name", "不知道年龄");
// there.put("age", null);
// dataList.add(there);
ExcelUtils.write(filePath, headList, dataList);
//
//
// List<ExcelHead> headList2 = new ArrayList();
// headList2.add(new ExcelHead<String>("dept", "部门", ""));
// headList2.add(new ExcelHead<String>("code", "工号", ""));
// headList2.add(new ExcelHead<String>("name", "姓名", ""));
// headList2.add(new ExcelHead<String>("23-05-05", "23-05-05",""));
// headList2.add(new ExcelHead<String>("23-05-06", "23-05-06", ""));
// headList2.add(new ExcelHead<String>("23-05-07", "23-05-07", ""));
//
// List<Map<String, Object>> dataList2 = new ArrayList();
// Map<String, Object> one2 = new HashMap();
// one2.put("code", "A001");
// one2.put("23-05-05", "285.65");
// one2.put("23-05-06", "257.36");
// one2.put("23-05-07", "25734.36");
// dataList2.add(one2);
//
// Map<String, Object> two2 = new HashMap();
// two2.put("code", "A002");
// two2.put("23-05-05", "283.65");
// two2.put("23-05-06", "25712.36");
// two2.put("23-05-07", "25712e2.36");
// dataList2.add(two2);
//
// ExcelUtils.write(filePath, headList2, dataList2);
//
// }
/**
* 写excel
*
* @param filePath 保存的路径名
* @param headList
* @param dataList
*/
public static void write(String filePath, List<ExcelHead> headList, List<Map<String, Object>> dataList) {
ExcelWriterBuilder writerBuilder = EasyExcel.write();
writerBuilder.file(filePath);
writerBuilder.excelType(ExcelTypeEnum.XLSX);
writerBuilder.autoCloseStream(true);
writerBuilder.head(convertHead(headList)).sheet("sheet1")
.doWrite(convertData(headList, dataList));
}
/**
* 写excel
*
* @param filePath 保存的路径名
* @param headList 表头
* @param dataList 数据源
* @param sheetName sheet名称
*/
public static void write(String filePath, List<ExcelHead> headList, List<Map<String, Object>> dataList,String sheetName) {
ExcelWriterBuilder writerBuilder = EasyExcel.write();
writerBuilder.file(filePath);
writerBuilder.excelType(ExcelTypeEnum.XLSX);
writerBuilder.autoCloseStream(true);
writerBuilder.head(convertHead(headList)).sheet(sheetName)
.doWrite(convertData(headList, dataList));
}
/**
* 写excel
*
* @param filePath 保存的路径名
* @param headList 表头
* @param dataList 数据源
* @param sheetName sheet名称
* @param horizontalCellStyleStrategy 单元格样式设置
*/
public static void write(String filePath, List<ExcelHead> headList, List<Map<String, Object>> dataList, String sheetName, HorizontalCellStyleStrategy horizontalCellStyleStrategy) {
ExcelWriterBuilder writerBuilder = EasyExcel.write();
writerBuilder.file(filePath);
writerBuilder.excelType(ExcelTypeEnum.XLSX);
writerBuilder.autoCloseStream(true);
writerBuilder.head(convertHead(headList))
.sheet(sheetName)
// 设置单元格样式
.registerWriteHandler(horizontalCellStyleStrategy)
.doWrite(convertData(headList, dataList));
}
/**
* 会先删除excel所有sheet,再写入
*/
public static <T> void writeSheet(String filePath, String sheetName, Class<T> c, List<T> list) {
EasyExcel.write(filePath, c).sheet(sheetName).doWrite(list);
}
public static <T> List<T> read(String fileName, String sheetName, Class c) {
List<T> list = new ArrayList();
EasyExcel.read(fileName, c, new ReadListener<T>() {
@Override
public void invoke(T o, AnalysisContext analysisContext) {
list.add(o);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
}).sheet(sheetName).doRead();
return list;
}
private static List<List<String>> convertHead(List<ExcelHead> headList) {
List<List<String>> list = new ArrayList<>();
for (ExcelHead head : headList) {
list.add(Lists.newArrayList(head.getTitle()));
}
//沒有搞清楚head的参数为List<List<String>>,用List<String>就OK了
return list;
}
/**
* @param headList
* @param dataList key为head里的fieldName
* @return
*/
private static List<List<Object>> convertData(List<ExcelHead> headList, List<Map<String, Object>> dataList) {
List<List<Object>> result = new ArrayList();
//对dataList转为easyExcel的数据格式
for (Map<String, Object> data : dataList) {
List<Object> row = new ArrayList();
for (ExcelHead h : headList) {
Object o = data.get(h.getFieldName());
//需要对null的处理,比如age的null,要转为对应设置的值
row.add(handler(o, h.getNullValue()));
}
result.add(row);
}
return result;
}
/**
* null值处理
*
* @param o
* @param nullValue
* @return
*/
private static Object handler(Object o, Object nullValue) {
return o != null ? o : nullValue;
}
}
设置单元格样式
import java.util.List;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.AbstractCellStyleStrategy;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;
@Getter
@Setter
@EqualsAndHashCode
public class HorizontalCellStyleStrategy extends AbstractCellStyleStrategy {
private WriteCellStyle headWriteCellStyle;
private List<WriteCellStyle> contentWriteCellStyleList;
public HorizontalCellStyleStrategy() {
}
public HorizontalCellStyleStrategy(WriteCellStyle headWriteCellStyle,
List<WriteCellStyle> contentWriteCellStyleList) {
this.headWriteCellStyle = headWriteCellStyle;
this.contentWriteCellStyleList = contentWriteCellStyleList;
}
public HorizontalCellStyleStrategy(WriteCellStyle headWriteCellStyle, WriteCellStyle contentWriteCellStyle) {
this.headWriteCellStyle = headWriteCellStyle;
if (contentWriteCellStyle != null) {
this.contentWriteCellStyleList = ListUtils.newArrayList(contentWriteCellStyle);
}
}
@Override
protected void setHeadCellStyle(CellWriteHandlerContext context) {
if (stopProcessing(context) || headWriteCellStyle == null) {
return;
}
WriteCellData<?> cellData = context.getFirstCellData();
WriteCellStyle.merge(headWriteCellStyle, cellData.getOrCreateStyle());
}
@Override
protected void setContentCellStyle(CellWriteHandlerContext context) {
if (stopProcessing(context) || CollectionUtils.isEmpty(contentWriteCellStyleList)) {
return;
}
WriteCellData<?> cellData = context.getFirstCellData();
if (context.getRelativeRowIndex() == null || context.getRelativeRowIndex() <= 0) {
WriteCellStyle.merge(contentWriteCellStyleList.get(0), cellData.getOrCreateStyle());
} else {
WriteCellStyle.merge(
contentWriteCellStyleList.get(context.getRelativeRowIndex() % contentWriteCellStyleList.size()),
cellData.getOrCreateStyle());
}
}
protected boolean stopProcessing(CellWriteHandlerContext context) {
return context.getFirstCellData() == null;
}
}
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import org.apache.poi.ss.usermodel.*;
public class StyleUtils {
/**
* 标题样式
* @return
*/
public static WriteCellStyle getHeadStyle(){
// 头的策略
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
// 背景颜色
// headWriteCellStyle.setFillForegroundColor(IndexedColors.LIGHT_TURQUOISE1.getIndex());
// headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
// 字体
WriteFont headWriteFont = new WriteFont();
headWriteFont.setFontName("宋体");//设置字体名字
headWriteFont.setFontHeightInPoints((short)14);//设置字体大小
headWriteFont.setBold(true);//字体加粗
headWriteCellStyle.setWriteFont(headWriteFont); //在样式用应用设置的字体;
// 样式
headWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
headWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
headWriteCellStyle.setBorderLeft(BorderStyle.THIN); //设置左边框;
headWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
headWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
headWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
headWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
headWriteCellStyle.setTopBorderColor((short) 0); //设置顶边框颜色;
headWriteCellStyle.setWrapped(true); //设置自动换行;
headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);//设置水平对齐的样式为居中对齐;
headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); //设置垂直对齐的样式为居中对齐;
headWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适
return headWriteCellStyle;
}
/**
* 内容样式
* @return
*/
public static WriteCellStyle getContentStyle(){
// 内容的策略
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
// 背景绿色
// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
// contentWriteCellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
// contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
// 设置字体
WriteFont contentWriteFont = new WriteFont();
contentWriteFont.setFontHeightInPoints((short) 12);//设置字体大小
contentWriteFont.setFontName("宋体"); //设置字体名字
contentWriteCellStyle.setWriteFont(contentWriteFont);//在样式用应用设置的字体;
//设置样式;
contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
contentWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
contentWriteCellStyle.setBorderLeft(BorderStyle.THIN); //设置左边框;
contentWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
contentWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
contentWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
contentWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
contentWriteCellStyle.setTopBorderColor((short) 0); ///设置顶边框颜色;
contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 水平居中
contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
contentWriteCellStyle.setWrapped(true); //设置自动换行;
// contentWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适
return contentWriteCellStyle;
}
}
使用案例
public CodeDataResp exportWorkFeeByDate(UserWorkProcedureEntity req, HttpServletResponse response){
String sheetName ="人员工资明细表";
String startTime = null;
String endTime = null;
String now = DateUtil.now();
String threeDaysAgoStart = DateUtil.format(DateUtil.offsetDay(DateUtil.beginOfDay(new Date()), -3), "yyyy-MM-dd HH:mm:ss");
// 默认查3天内的
// 设置开始时间为 3天前的 开始
startTime = StringUtils.isNotBlank(req.getStartTime())?req.getStartTime():threeDaysAgoStart;
// 结束时间为 now
endTime = StringUtils.isNotBlank(req.getEndTime())?req.getEndTime():now;
QueryWrapper<UserWorkProcedureEntity> wrapper2 = new QueryWrapper<UserWorkProcedureEntity>();
wrapper2.lambda().ge(UserWorkProcedureEntity :: getCreateTime, startTime);
// 结束时间为 now
wrapper2.lambda().le(UserWorkProcedureEntity :: getCreateTime, endTime);
// 姓名过滤
if (StringUtils.isNotBlank(req.getKeyWords())){
wrapper2.lambda().like(UserWorkProcedureEntity :: getUserName,req.getKeyWords());
}
// 工号过滤
if (StringUtils.isNotBlank(req.getKeyWords2())){
wrapper2.lambda().eq(UserWorkProcedureEntity :: getUserCode,req.getKeyWords2());
}
List<SalaryByDateVO> data = userWorkProcedureMapper.exportWorkFeeByDate(wrapper2);
if(CollectionUtils.isEmpty(data))
return CodeDataResp.valueOfFailed("无记录");
String fileName = DatePattern.PURE_DATETIME_FORMAT.format(new Date())+sheetName+".xlsx";
String folderStr="export-excel";
String userDir = System.getProperties().getProperty("user.dir").concat(File.separator).concat("static");
String uploadPath = userDir.concat(File.separator).concat(folderStr);
String filePath = uploadPath.concat(File.separator).concat(fileName);
String returnPath=folderStr.concat("/").concat(fileName);
// 定义表头和数据格式
List<ExcelHead> headList = new ArrayList();
headList.add(new ExcelHead<String>("dept", "部门", ""));
headList.add(new ExcelHead<String>("code", "工号", ""));
headList.add(new ExcelHead<String>("name", "姓名", ""));
// 设置日期
Set<Date> set = new TreeSet<>();
data.forEach(i->{
set.add(i.getDay());
});
set.forEach(i->{
String date = DateUtil.format(i, "yyyy-MM-dd");
headList.add(new ExcelHead(date, date+"工资", 0));
});
// 定位 列 日期作为主键
Map<String,List<Map<String,String>>> map = new HashMap<>();
Map<String,String> deptMap = new HashMap<>();
Map<String,String> nameMap = new HashMap<>();
// 定位 行 某个部门的某个人 工号
data.forEach(i->{
// 时间格式化
String date= DateUtil.format(i.getDay(), "yyyy-MM-dd");
String key = i.getUserCode();
if (!deptMap.containsKey(key)){
deptMap.put(key,i.getGroupName());
}
if (!nameMap.containsKey(key)){
nameMap.put(key,i.getUserName());
}
Map<String,String> oneMap = new HashMap<>();
// 保留两位小数
oneMap.put(date,String.format("%.2f", (double) i.getTotalSalary() / 100));
if (map.containsKey(key)){
map.get(key).add(oneMap);
}else {
//
List<Map<String,String>> salaryList = new ArrayList<>();
salaryList.add(oneMap);
map.put(key,salaryList);
}
});
List<Map<String, Object>> dataList = new ArrayList();
List<Map<String, Object>> finalDataList = dataList;
map.forEach((k, v)->{
Map<String, Object> one = new HashMap();
one.put("code",k);
one.put("name",nameMap.get(k));
one.put("dept",deptMap.get(k));
// 把值设置进去
v.forEach(one::putAll);
finalDataList.add(one);
});
// List 根据 部门 姓名 排序
dataList = dataList.stream()
.sorted(Comparator.comparing(m -> {
String dept = (String) m.get("dept");
String name = (String) m.get("name");
return dept == null ? "" : dept + "-" + (name == null ? "" : name);
}))
.collect(Collectors.toList());
// 设置单元格样式
HorizontalCellStyleStrategy horizontalCellStyleStrategy =
new HorizontalCellStyleStrategy(StyleUtils.getHeadStyle(), StyleUtils.getContentStyle());
ExcelUtils.write(filePath, headList, dataList,fileName,horizontalCellStyleStrategy);
return CodeDataResp.valueOfSuccess(returnPath);
}