easyExcel导出明细
controller方法
/**
* 导出流水明细
*
* @return
*/
@PostMapping("/receipt/statement/detail/export")
public void export(HttpServletResponse response, @RequestBody ExportDetailDto dto) throws ParseException {
List<ExportFieldVo> exportField = dto.getExportField();
List<String> names = exportField.stream().map(ExportFieldVo::getName).toList();
//查询数据
List<ExportDetailData> exportDetailData = receiptStatementDetailService.getExportData(dto);
// 查询
if (names.contains("明细表")) {
try {
int size = names.size() - 1;
// 设置响应结果
this.setExcelResponseProp(response, "流水明细");
List<List<String>> list = generateHeadForDetail(names);
List<List<Object>> dataList = new ArrayList<>();
for (ExportDetailData detailData : exportDetailData) {
List<ContractInfo> contractInfoList = detailData.getContractInfoList();
// List<ProjectInfo> projectInfoList = detailData.getProjectInfoList();
if (CollUtil.isEmpty(contractInfoList)) {
List<Object> data1 = generateHeadCommon(names, detailData);
for (int i = 0; i < 10; i++) {
data1.add("");
}
dataList.add(data1);
} else {
setContractInfoData(names, dataList, detailData, contractInfoList);
// setProjectInfoData(names, dataList, detailData, projectInfoList);
}
}
WriteCellStyle writeCellStyle = new WriteCellStyle();
writeCellStyle.setWrapped(true);
// 每隔2行会合并 把eachColumn 设置成 3 也就是我们数据的长度,所以就第一列会合并。当然其他合并策略也可以自己写
// LoopMergeStrategy loopMergeStrategy = new LoopMergeStrategy(2, 0);
HorizontalCellStyleStrategy horizontalCellStyleStrategy =
new HorizontalCellStyleStrategy(null, writeCellStyle);
// 调用合并单元格工具类,此工具类是根据工程名称相同则合并后面数据
//需要合并的列
//int[] mergeColumeIndex = {0, 1,2,3,4,5,6,7,8,9,10,11,12};
//int[] index = generateArray(mergeColumeIndex, size);
int[] mergeColumnIndex = new int[size];
for (int i = 0; i < size; i++) {
mergeColumnIndex[i] = i;
}
//从第1列开始合并
int mergeRowIndex = 0;
ExcelMergeUtil excelFillCellMergeStrategy = new ExcelMergeUtil(mergeRowIndex, mergeColumnIndex);
EasyExcel.write(response.getOutputStream())
.head(list)
.registerWriteHandler(horizontalCellStyleStrategy)
.registerWriteHandler(excelFillCellMergeStrategy)
.registerWriteHandler(new AutoColumnWidthHandler())
.excelType(ExcelTypeEnum.XLSX)
.sheet("流水明细")
.doWrite(dataList);
} catch (IOException e) {
throw new ServiceException(e);
}
} else {
try {
// 设置响应结果
Map<String, String> headMap = new HashMap<>();
this.setExcelResponseProp(response, "流水明细");
List<List<String>> list = getHead(names, headMap);
List<List<Object>> dataList = new ArrayList<>();
for (ExportDetailData detailData : exportDetailData) {
setDataCommonExport(headMap, dataList, detailData);
}
WriteCellStyle writeCellStyle = new WriteCellStyle();
writeCellStyle.setWrapped(true);
HorizontalCellStyleStrategy horizontalCellStyleStrategy =
new HorizontalCellStyleStrategy(null, writeCellStyle);
EasyExcel.write(response.getOutputStream())
.head(list)
.registerWriteHandler(horizontalCellStyleStrategy)
.registerWriteHandler(new AutoColumnWidthHandler())
.excelType(ExcelTypeEnum.XLSX)
.sheet("流水明细")
.doWrite(dataList);
} catch (IOException e) {
throw new ServiceException(e);
}
}
}
ExcelMergeUtil
package com.crfsdi.ocm.receipt.utils;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import java.util.List;
public class ExcelMergeUtil implements CellWriteHandler {
private int[] mergeColumnIndex;
private int mergeRowIndex;
public ExcelMergeUtil() {
}
public ExcelMergeUtil(int mergeRowIndex, int[] mergeColumnIndex) {
this.mergeRowIndex = mergeRowIndex;
this.mergeColumnIndex = mergeColumnIndex;
}
@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) {
}
public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
}
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
//当前行
int curRowIndex = cell.getRowIndex();
//当前列
int curColIndex = cell.getColumnIndex();
if (curRowIndex > mergeRowIndex) {
for (int i = 0; i < mergeColumnIndex.length; i++) {
if (curColIndex == mergeColumnIndex[i]) {
mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
break;
}
}
}
}
/**
* 当前单元格向上合并
*
* @param writeSheetHolder
* @param cell 当前单元格
* @param curRowIndex 当前行
* @param curColIndex 当前列
*/
private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();
Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();
// 将当前单元格数据与上一个单元格数据比较
Boolean dataBool = preData.equals(curData);
String stringCellValue = cell.getRow().getCell(0).getStringCellValue();
String stringCellValue1 = cell.getSheet().getRow(curRowIndex - 1).getCell(0).getStringCellValue();
//此处需要注意:因为我是按照工程名称确定是否需要合并的,所以获取每一行第二列数据和上一行第一列数据进行比较,如果相等合并,getCell里面的值,是工程名称所在列的下标
Boolean bool = cell.getRow().getCell(0).getStringCellValue().equals(cell.getSheet().getRow(curRowIndex - 1).getCell(0).getStringCellValue());
System.out.println("A");
if (dataBool && bool) {
Sheet sheet = writeSheetHolder.getSheet();
List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
boolean isMerged = false;
for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
CellRangeAddress cellRangeAddr = mergeRegions.get(i);
// 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
sheet.removeMergedRegion(i);
cellRangeAddr.setLastRow(curRowIndex);
sheet.addMergedRegion(cellRangeAddr);
isMerged = true;
}
}
// 若上一个单元格未被合并,则新增合并单元
if (!isMerged) {
CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);
sheet.addMergedRegion(cellRangeAddress);
}
}
}
}
表头设置方法
private static List<List<String>> getHead(List<String> names, Map<String, String> headMap) {
List<List<String>> list = new ArrayList<List<String>>();
List<String> head0 = new ArrayList<String>();
if (names.contains("流水号")) {
head0.add("流水号");
list.add(head0);
headMap.put("流水号", "流水号");
}
if (names.contains("金额(元)")) {
List<String> head1 = new ArrayList<String>();
head1.add("金额(元)");
list.add(head1);
headMap.put("金额(元)", "金额(元)");
}
if (names.contains("付款方")) {
List<String> head2 = new ArrayList<String>();
head2.add("付款方");
list.add(head2);
headMap.put("付款方", "付款方");
}
if (names.contains("用途")) {
List<String> head3 = new ArrayList<String>();
head3.add("用途");
list.add(head3);
headMap.put("用途", "用途");
}
if (names.contains("款项类别")) {
List<String> head4 = new ArrayList<String>();
head4.add("款项类别");
list.add(head4);
headMap.put("款项类别", "款项类别");
}
if (names.contains("到款时间")) {
List<String> head5 = new ArrayList<String>();
head5.add("到款时间");
list.add(head5);
headMap.put("到款时间", "到款时间");
}
if (names.contains("转至账户")) {
List<String> head6 = new ArrayList<String>();
head6.add("转至账户");
list.add(head6);
headMap.put("转至账户", "转至账户");
}
if (names.contains("款项类型")) {
List<String> head7 = new ArrayList<String>();
head7.add("款项类型");
list.add(head7);
headMap.put("款项类型", "款项类型");
}
if (names.contains("确认人")) {
List<String> head8 = new ArrayList<String>();
head8.add("确认人");
list.add(head8);
headMap.put("确认人", "确认人");
}
if (names.contains("单位名称")) {
List<String> head9 = new ArrayList<String>();
head9.add("单位名称");
list.add(head9);
headMap.put("单位名称", "单位名称");
}
if (names.contains("附件")) {
List<String> head10 = new ArrayList<String>();
head10.add("附件");
list.add(head10);
headMap.put("附件", "附件");
}
if (names.contains("当前节点")) {
List<String> head11 = new ArrayList<String>();
head11.add("当前节点");
list.add(head11);
headMap.put("当前节点", "当前节点");
}
if (names.contains("审批状态")) {
List<String> head12 = new ArrayList<String>();
head12.add("审批状态");
list.add(head12);
headMap.put("审批状态", "审批状态");
}
return list;
}