依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.6</version>
</dependency>
package cn.visight;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import java.util.*;
import java.util.stream.Collectors;
public class ExcelTest {
public static void main(String args[]) {
// 文件输出位置
String fileName = "D:\\visi\\workspace\\统计.xlsx";
Set<String> allDateList = new HashSet<>();
Set<String> allOutletsNameList = new HashSet();
List<XData> dataList = getDataList();
dataList.forEach(r -> {
// 1.获取所有的日期List
allDateList.add(r.getDate());
// 2.获取所有的名字Map
allOutletsNameList.add(r.getOutletsName());
});
// 3.获取所有的日期对应的数据Map
Map<String, List<XData>> date2XDataMap = dataList.stream().collect(Collectors.groupingBy(XData::getDate));
ExcelWriterBuilder builder = EasyExcel.write(fileName);
List<List<String>> headData = getExcelHeadData(allOutletsNameList);
List<List<Object>> excelDataList = getExcelDataList(allDateList, allOutletsNameList, date2XDataMap);
builder.head(headData).sheet("统计数据").doWrite(excelDataList);
}
private static List<List<Object>> getExcelDataList(Set<String> allDateList, Set<String> allOutletsNameList, Map<String, List<XData>> date2XDataMap) {
List<List<Object>> excelDatalist = new ArrayList<>();
//网点小计
Map<String, Subtotal> outletsName2Subtotal = new HashMap<>();
//过包总计
Integer totalNumCount = 0;
//违禁品总计
Integer dangerNumCount = 0;
// 2.获取excel表数据
for (String currDate : allDateList) {
List<Object> rowData = new ArrayList<>();
rowData.add(currDate);
for (String outletsName : allOutletsNameList) {
//初始化小计数据
Subtotal subtotal = outletsName2Subtotal.get(outletsName);
if (subtotal == null) {
outletsName2Subtotal.put(outletsName, new Subtotal(0, 0));
}
List<XData> numList = date2XDataMap.get(currDate);
boolean isNotExist = false;
for (XData xData : numList) {
if (outletsName.equals(xData.getOutletsName())) {
Integer dangerNum = xData.getDangerNum() == null ? 0 : xData.getDangerNum();
Integer totalNum = xData.getTotalNum() == null ? 0 : xData.getTotalNum();
rowData.add(totalNum);
rowData.add(dangerNum);
isNotExist = false;
//统计小计数量
Subtotal currSubtotal = outletsName2Subtotal.get(outletsName);
currSubtotal.setSubTotalNum(currSubtotal.getSubTotalNum() + totalNum);
currSubtotal.setSubDangerNum(currSubtotal.getSubDangerNum() + dangerNum);
//统计总计数量
totalNumCount += totalNum;
dangerNumCount += dangerNum;
break;
} else {
isNotExist = true;
}
}
//没有该网点的数量,则给默认值0
if (isNotExist) {
rowData.add(0);
rowData.add(0);
}
}
excelDatalist.add(rowData);
}
// 3.存入小计
List<Object> rowSubtotalData = new ArrayList<>();
rowSubtotalData.add("小计");
allOutletsNameList.forEach(outletsName -> {
Subtotal subtotal = outletsName2Subtotal.get(outletsName);
Integer subTotalNum = subtotal.getSubTotalNum();
Integer subDangerNum = subtotal.getSubDangerNum();
rowSubtotalData.add(subTotalNum);
rowSubtotalData.add(subDangerNum);
});
excelDatalist.add(rowSubtotalData);
// 4.存入总计
List<Object> rowTotalCountData = new ArrayList<>();
rowTotalCountData.add("过包总计");
rowTotalCountData.add(totalNumCount);
excelDatalist.add(rowTotalCountData);
List<Object> rowDangerCountData = new ArrayList<>();
rowDangerCountData.add("违禁品数总计");
rowDangerCountData.add(dangerNumCount);
excelDatalist.add(rowDangerCountData);
return excelDatalist;
}
private static List<List<String>> getExcelHeadData(Set<String> allOutletsNameList) {
List<List<String>> list = new ArrayList<>();
// 1.获取excel表头
List<String> head0 = new ArrayList<>();
head0.add("网点\n数目\n日期");
list.add(head0);
List<String> childrenHeadTitleList = new ArrayList<>();
childrenHeadTitleList.add("总数");
childrenHeadTitleList.add("违禁品数");
allOutletsNameList.forEach(outletsName -> {
childrenHeadTitleList.forEach(childName -> {
List<String> head = new ArrayList<>();
head.add(outletsName);
head.add(childName);
list.add(head);
});
});
return list;
}
private static List<XData> getDataList() {
List<XData> list = new ArrayList<>();
list.add(new XData("2021-08-19", 239, 0, "韵达"));
list.add(new XData("2021-08-19", 6, 8, "申通"));
list.add(new XData("2021-08-20", 5, 0, "德邦"));
list.add(new XData("2021-08-20", 623, 0, "韵达"));
list.add(new XData("2021-08-20", 74, 2, "长途汽车站"));
list.add(new XData("2021-08-20", 2, 3, "申通"));
return list;
}
}
class XData {
private String date;
private String outletsName;
private Integer totalNum;
private Integer dangerNum;
public XData(String date, Integer totalNum, Integer dangerNum, String outletsName) {
this.date = date;
this.outletsName = outletsName;
this.totalNum = totalNum;
this.dangerNum = dangerNum;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getOutletsName() {
return outletsName;
}
public void setOutletsName(String outletsName) {
this.outletsName = outletsName;
}
public Integer getTotalNum() {
return totalNum;
}
public void setTotalNum(Integer totalNum) {
this.totalNum = totalNum;
}
public Integer getDangerNum() {
return dangerNum;
}
public void setDangerNum(Integer dangerNum) {
this.dangerNum = dangerNum;
}
}
class Subtotal {
private Integer subTotalNum;
private Integer subDangerNum;
public Integer getSubTotalNum() {
return subTotalNum;
}
public void setSubTotalNum(Integer subTotalNum) {
this.subTotalNum = subTotalNum;
}
public Integer getSubDangerNum() {
return subDangerNum;
}
public void setSubDangerNum(Integer subDangerNum) {
this.subDangerNum = subDangerNum;
}
public Subtotal(Integer subTotalNum, Integer subDangerNum) {
this.subTotalNum = subTotalNum;
this.subDangerNum = subDangerNum;
}
}