需要导出的报表的模板
处理数据及格式(行列合并、sheet页重命名)
public class ExportDailyReportService {
@Autowired
private Environment env;
public String exportDailyReport(List<DailyReportExportVo> dataList, String dateStr){
File savePath = new File(env.getProperty("excel.path"));
String number = DateUtils.formatDate(new Date(), "HHmmss");
String fileName = new StringBuilder("xxx数据日报月报").append(dateStr).append("-"+number).append(ExcelTypeEnum.XLSX.getValue()).toString();
long startTime = System.currentTimeMillis();
ExcelWriter excelWriter = null;
try {
if(!savePath.exists()){
savePath.mkdir();
}
File file = new File(savePath,fileName);
excelWriter = EasyExcel.write(file)
.registerWriteHandler(new MergeSameRowsStrategy(2,new int[]{2}))
.registerWriteHandler(new TotalMergeStrategy(dataList.size()))
.registerWriteHandler(new UpdateSheetNameStrategy())
.withTemplate(Thread.currentThread().getContextClassLoader().getResourceAsStream("templates/excel/export/DailyReportExport.xlsx")).build();
WriteSheet writeSheet = EasyExcel.writerSheet(0, dateStr.concat("日报数据")).build();
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
DailyReportExportVo dailyReportExportVo = dataList.get(dataList.size()-1);
dailyReportExportVo.setArea(dailyReportExportVo.getYqMerchantName());
Map<String, Object> map =new HashMap<>();
map.put("exportDate",dateStr);
excelWriter.fill(dataList,fillConfig,writeSheet);
excelWriter.fill(map,writeSheet);
return env.getProperty("excel.url") + fileName;
}finally{
excelWriter.finish();
log.info("export {} excel use {}ms",fileName,System.currentTimeMillis() - startTime);
}
}
class UpdateSheetNameStrategy extends AbstractSheetWriteHandler {
public UpdateSheetNameStrategy() {
}
@Override
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
super.afterSheetCreate(writeWorkbookHolder, writeSheetHolder);
writeWorkbookHolder.getWorkbook().setSheetName(writeSheetHolder.getSheetNo(), writeSheetHolder.getSheetName());
}
}
class MergeSameRowsStrategy implements CellWriteHandler {
private int[] mergeColumnIndex;
private int mergeRowIndex;
public MergeSameRowsStrategy() {
}
public MergeSameRowsStrategy(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) {
}
@Override
public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {
}
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
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;
}
}
}
}
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();
if (curData.equals(preData)) {
Sheet sheet = writeSheetHolder.getSheet();
List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
boolean isMerged = false;
for (int i = 0; i < mergedRegions.size() && !isMerged; i++) {
CellRangeAddress cellRangeAddr = mergedRegions.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);
}
}
}
}
class TotalMergeStrategy extends AbstractMergeStrategy {
private final int size;
public TotalMergeStrategy(int size) {
this.size = size;
}
@Override
protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
if (cell.getRowIndex()==size+1 && cell.getColumnIndex() == 1) {
sheet.addMergedRegionUnsafe(new CellRangeAddress(cell.getRowIndex(), cell.getRowIndex(), cell.getColumnIndex(), cell.getColumnIndex() + 4));
}
}
}
}
导出结果
例2:
package cn.com.glsx.dj.smartcarlife.service.smartcarlife;
import cn.com.glsx.dj.smartcarlife.dto.PurchaseOrderExportPageDTO;
import cn.com.glsx.dj.smartcarlife.model.PurchaseOrderGoods;
import cn.com.glsx.dj.smartcarlife.vo.excel.PurchaseOrderExportVo;
import cn.com.glsx.framework.core.util.DateUtils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.handler.AbstractSheetWriteHandler;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import java.io.File;
import java.util.*;
@Service
@Slf4j
public class ExportPurchaseOrderService {
@Autowired
private Environment env;
public String exportPurchaseOrder(List<PurchaseOrderExportPageDTO> dataList) {
File savePath = new File(env.getProperty("gop.excel.tem.path"));
String number = DateUtils.formatDate(new Date(), "yyyyMMddHHmmss");
String fileName = new StringBuilder("采购订单").append("-" + number).append(ExcelTypeEnum.XLSX.getValue()).toString();
long startTime = System.currentTimeMillis();
ExcelWriter excelWriter = null;
try {
if (!savePath.exists()) {
savePath.mkdir();
}
File file = new File(savePath, fileName);
List<CellRangeAddress> addressList = new ArrayList<>();
List<PurchaseOrderExportVo> exportVoList = new ArrayList<>();
for (int i = 0; i < dataList.size(); i++) {
PurchaseOrderExportPageDTO dto = dataList.get(i);
if (i < 1) {
addressList.add(new CellRangeAddress(1, dto.getGoodsList().size(), 0, 0));
} else {
int firstRow = addressList.get(i - 1).getLastRow() + 1;
int lastRow = addressList.get(i - 1).getLastRow() + dto.getGoodsList().size();
addressList.add(new CellRangeAddress(firstRow, lastRow, 0, 0));
}
for (PurchaseOrderGoods goods : dto.getGoodsList()) {
PurchaseOrderExportVo vo = new PurchaseOrderExportVo();
BeanUtils.copyProperties(dto, vo);
BeanUtils.copyProperties(goods, vo);
exportVoList.add(vo);
}
}
excelWriter = EasyExcel.write(file)
.registerWriteHandler(new UpdateSheetNameStrategy())
.registerWriteHandler(new MergeRowsAndConvertedStrategy(1, new int[]{8, 11}, addressList))
.withTemplate(Thread.currentThread().getContextClassLoader().getResourceAsStream("templates/excel/export/采购订单导出.xlsx")).build();
WriteSheet writeSheet = EasyExcel.writerSheet(0, "采购订单").build();
FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
excelWriter.fill(exportVoList, fillConfig, writeSheet);
return env.getProperty("gop.excel.tem.url") + fileName;
} finally {
excelWriter.finish();
log.info("export {} excel use {}ms", fileName, System.currentTimeMillis() - startTime);
}
}
class UpdateSheetNameStrategy extends AbstractSheetWriteHandler {
public UpdateSheetNameStrategy() {
}
@Override
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
super.afterSheetCreate(writeWorkbookHolder, writeSheetHolder);
writeWorkbookHolder.getWorkbook().setSheetName(writeSheetHolder.getSheetNo(), writeSheetHolder.getSheetName());
}
}
class MergeRowsAndConvertedStrategy implements CellWriteHandler {
private int[] mergeColumnIndex;
private int startRow;
private List<CellRangeAddress> addressList;
public MergeRowsAndConvertedStrategy() {
}
public MergeRowsAndConvertedStrategy(int startRow, int[] mergeColumnIndex, List<CellRangeAddress> addressList) {
this.startRow = startRow;
this.mergeColumnIndex = mergeColumnIndex;
this.addressList = addressList;
}
@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) {
}
@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) {
}
@Override
public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {
}
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
int curRowIndex = cell.getRowIndex();
int curColIndex = cell.getColumnIndex();
if (curRowIndex >= startRow) {
for (int i = 0; i < mergeColumnIndex.length; i++) {
if (curColIndex == mergeColumnIndex[i]) {
dataConverted(cell, curColIndex);
break;
}
}
}
if (curRowIndex > this.startRow && curColIndex >= 0 && curColIndex < 12) {
Sheet sheet = writeSheetHolder.getSheet();
mergeRow(sheet, cell, curRowIndex, curColIndex);
}
}
private void mergeRow(Sheet sheet, Cell cell, int curRowIndex, int curColIndex) {
List<CellRangeAddress> list = this.addressList;
for (int i = 0; i < list.size(); i++) {
CellRangeAddress cellRangeAddress = list.get(i);
if (cellRangeAddress.containsRow(curRowIndex)) {
if (cellRangeAddress.getLastRow() == cellRangeAddress.getFirstRow()) {
return;
}
CellRangeAddress cra = new CellRangeAddress(cellRangeAddress.getFirstRow(), cellRangeAddress.getLastRow(), curColIndex, curColIndex);
List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
if (mergedRegions.contains(cra)) {
return;
}
sheet.addMergedRegion(cra);
return;
}
}
}
private void dataConverted(Cell cell, int curColIndex) {
if (curColIndex == 8) {
double numericCellValue = cell.getNumericCellValue();
switch ((int) numericCellValue) {
case 1:
cell.setCellValue("未发货");
break;
case 2:
cell.setCellValue("已发货");
break;
}
} else if (curColIndex == 11) {
double numericCellValue = cell.getNumericCellValue();
switch ((int) numericCellValue) {
case 1:
cell.setCellValue("待审核");
break;
case 2:
cell.setCellValue("已审核");
break;
case 3:
cell.setCellValue("已取消");
break;
}
}
}
}
}
结果
例二的另一种做法
一对多的场景:一条订单对应多个商品
模板
导出类
package cn.com.glsx.dj.smartcarlife.vo.excel;
import cn.com.glsx.dj.smartcarlife.dto.purchase.PurchaseOrderGoodsExportDTO;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import lombok.Data;
import org.oreframework.commons.office.easyexcel.annotation.ExcelMergeRow;
import org.oreframework.commons.office.easyexcel.annotation.ExcelValueReplace;
import org.oreframework.commons.office.easyexcel.converter.ReplaceByteToStringConvert;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@Data
public class PurchaseOrderExportVo implements Serializable{
private static final long serialVersionUID = 4223969010443009963L;
@ExcelMergeRow(columIndex = 0)
private Integer index;
@ExcelMergeRow(columIndex = 1)
private String orderCode;
@ExcelMergeRow(columIndex = 2)
private BigDecimal totalPrice;
@ExcelMergeRow(columIndex = 3)
@DateTimeFormat(value="yyyy-MM-dd HH:mm:ss")
private Date orderTime;
@ExcelMergeRow(columIndex = 4)
private String merchantName;
@ExcelMergeRow(columIndex = 5)
private String contactName;
@ExcelMergeRow(columIndex = 6)
private String contactPhone;
@ExcelMergeRow(columIndex = 7)
private String contactAddress;
@ExcelMergeRow(columIndex = 8)
@ExcelProperty(converter = ReplaceByteToStringConvert.class)
@ExcelValueReplace(replace={"未发货_1","已发货_2","部分发货_3"})
private Byte deliveryStatus;
@ExcelMergeRow(columIndex = 9)
@ExcelProperty(converter = ReplaceByteToStringConvert.class)
@ExcelValueReplace(replace={"商城采购_1","自采入库_2"})
private Byte purchaseType;
@ExcelMergeRow(columIndex = 10)
@ExcelProperty(converter = ReplaceByteToStringConvert.class)
@ExcelValueReplace(replace={"未入库_1","全部入库_2","部分入库_3"})
private Byte putStatus;
@ExcelMergeRow(columIndex = 11)
@ExcelProperty(converter = ReplaceByteToStringConvert.class)
@ExcelValueReplace(replace={"运营审核_1","商务审核_2","已取消_3","已驳回_4","已审核_5"})
private Byte status;
private List<PurchaseOrderGoodsExportDTO> goodsList;
}