在工作有個需求需要導(dǎo)出工單的列表信息匪凉,大致原型如下:
采用阿里開源的easyExcel(https://easyexcel.opensource.alibaba.com/)匈庭,
并進(jìn)行數(shù)據(jù)-中文枚舉轉(zhuǎn)換convert,
系統(tǒng)中已經(jīng)搭建了minio oss , 如果不需要可以用java 自帶的文件流處理
話不多說開干:
1.pom.xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.3</version>
</dependency>
2.VO和相關(guān)的轉(zhuǎn)換類
2.1 工單VO
/**
* Description: $
* <br/>
* $
*
* @author 泥石流
* @date 2023/1/4 15:12
*/
@Data
@ExcelSheet(name = "工單列表")
@ColumnWidth(value = 15)
@ContentRowHeight(value = 22)
@ContentStyle(borderLeft = BorderStyleEnum.THIN, borderBottom = BorderStyleEnum.THIN, borderRight = BorderStyleEnum.THIN)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class WorkOrderExcelVO {
@ColumnWidth(value = 20)
@ExcelProperty(value = "工單創(chuàng)建時間", index = 0)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createdTime;
/**
* 投訴人姓名
*/
@ExcelProperty(value = "消費者姓名", index = 1)
private String complainantName;
/**
* 電話號碼
*/
@ColumnWidth(value = 20)
@ExcelProperty(value = "消費者聯(lián)系方式", index = 2)
private String complainantPhone;
/**
* 工單編號
*/
@ExcelProperty(value = "工單號", index = 3)
private String workOrderCode;
/**
* 投訴類型 1消費投訴,2消費舉報
*/
@ExcelProperty(value = "投訴類型", index = 4, converter = ComplaintTypeConvert.class)
private Integer complaintType;
/**
* 投訴來源(SH MSA,SZ MSA,SH ODR,CN ODR,SH 12315,Other)
*/
@ExcelProperty(value = "投訴來源", index = 5)
private String complaintSource;
/**
* 來源備注
*/
@ColumnWidth(value = 20)
@ExcelProperty(value = "投訴來源備注", index = 6)
private String complaintSourceRemark;
/**
* 貨號
*/
@ExcelProperty(value = "貨號", index = 7)
private String productCode;
/**
* 產(chǎn)品類型(FW,APP,HW&ACC)
*/
@ExcelProperty(value = "產(chǎn)品類型", index = 8)
private String productType;
/**
* 產(chǎn)品價格
*/
@ExcelProperty(value = "產(chǎn)品價格", index = 9)
private BigDecimal productPrice;
/**
* 購買日期
*/
@ColumnWidth(value = 20)
@ExcelProperty(value = "購買日期", index = 10)
@JsonFormat(pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date purchaseDate;
/**
* 訂單號
*/
@ExcelProperty(value = "投訴訂單號", index = 11)
private String orderCode;
/**
* 店鋪類型(eCom,OR,Franchise,Other)
*/
@ExcelProperty(value = "店鋪類型", index = 12)
private String storeType;
/**
* 店鋪詳細(xì)信息(TM,JD,OS,DouYin,PDD,Comfirm APP,WeChat PLT,Other
)
*/
@ColumnWidth(value = 18)
@ExcelProperty(value = "店鋪類型詳情", index = 13)
private String storeInfo;
/**
* 店鋪詳細(xì)信息備注
*/
@ColumnWidth(value = 25)
@ExcelProperty(value = "店鋪類型詳情備注", index = 14)
private String storeInfoRemark;
/**
* 工單級別(1-Normal,2-Urgent)
*/
@ExcelProperty(value = "工單級別", index = 15)
private String workOrderLevelName;
/**
* 處理時限(d)
*/
@ColumnWidth(value = 18)
@ExcelProperty(value = "處理時限(d)", index = 16)
private Long dealDays;
/**
* 工單內(nèi)容
*/
@ColumnWidth(value = 30)
@ExcelProperty(value = "投訴內(nèi)容(工單內(nèi)容)", index = 17)
private String workOrderContent;
/**
* 預(yù)計辦結(jié)時間
*/
@ColumnWidth(value = 20)
@ExcelProperty(value = "預(yù)計辦結(jié)時間", index = 18)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime expectDealTime;
@ExcelProperty(value = "問題分類", index = 19)
private String problemTypeName;
/**
* 問題細(xì)分
*/
@ExcelProperty(value = "問題細(xì)分", index = 20)
private String problemSubTypeName;
/**
* 工單狀態(tài)(1-處理中,2-暫辦結(jié),3-辦結(jié))
*/
@ExcelProperty(value = "工單狀態(tài)", index = 21, converter = ComplaintStatusConvert.class)
private Integer workOrderStatus;
/**
* 結(jié)案總結(jié)
*/
@ColumnWidth(value = 30)
@ExcelProperty(value = "結(jié)案總結(jié)", index = 22)
private String closingSummary;
/**
* 實際辦結(jié)時間
*/
@ColumnWidth(value = 25)
@ExcelProperty(value = "工單實際辦結(jié)時間", index = 23)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime actualDealTime;
/**
* 辦結(jié)時長(h)
*/
@ColumnWidth(value = 18)
@ExcelProperty(value = "辦結(jié)時長(h)", index = 24)
private Long finishedHours;
/**
* 辦結(jié)天數(shù)(d)
*/
@ColumnWidth(value = 18)
@ExcelProperty(value = "辦結(jié)天數(shù)(d)", index = 25)
private Long finishedDays;
/**
* 超期時長(h)
*/
@ColumnWidth(value = 18)
@ExcelProperty(value = "超期時長(h)", index = 26)
private Long overHours;
/**
* 是否超期(0-否庐扫,1-是)
*/
@ColumnWidth(value = 0)
// @ExcelProperty(value = "是否超期", index = 27, converter = ComplaintIsOverDateConvert.class)
private Integer isOverDate;
@ColumnWidth(value = 0)
@ExcelProperty(value = "id")
private Long id;
/**
* 客戶ID
*/
@ExcelProperty("客戶ID")
@ColumnWidth(value = 0)
private String consumerCode;
/**
* 工單級別(1-Normal,2-Urgent)
*/
@ColumnWidth(value = 0)
@ExcelProperty(value = "工單級別level")
private Integer workOrderLevel;
/**
* 問題分類
*/
@ColumnWidth(value = 0)
private Long problemType;
/**
* 問題細(xì)分
*/
@ColumnWidth(value = 0)
private Long problemSubType;
/**
* 辦結(jié)時長
*/
@ColumnWidth(value = 0)
private Long dealHours;
@ColumnWidth(value = 0)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updatedTime;
@ColumnWidth(value = 0)
private String createdBy;
@ColumnWidth(value = 0)
private String updatedBy;
}
2.2 convert
/**
* Description: 工單狀態(tài)轉(zhuǎn)換
* <br/>
* $
*
* @author 泥石流
* @date 2023/1/9 12:31
*/
public class ComplaintStatusConvert implements Converter<Integer> {
@Override
public Class<?> supportJavaTypeKey() {
return Integer.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
@Override
public Integer convertToJavaData(ReadConverterContext<?> context) {
return WorkOrderStatusEnum.getCode(context.getReadCellData().getStringValue());
}
@Override
public WriteCellData<?> convertToExcelData(WriteConverterContext<Integer> context) {
return new WriteCellData<String>(WorkOrderStatusEnum.getValue(context.getValue()));
}
}
2.3 工單狀態(tài)枚舉
/**
* Description: $
* <br/>
* $
*
* @author 泥石流
* @date 2023/1/9 12:34
*/
@Getter
@AllArgsConstructor
public enum WorkOrderStatusEnum {
/**
* 處理中
*/
DEALING(1, "處理中"),
/**
* 暫辦結(jié)
*/
TENTATIVE_SETTLEMENT(2, "暫辦結(jié)"),
/**
* 辦結(jié)
*/
CONCLUDE(3, "辦結(jié)");
/**
* 根據(jù)code獲取value
* @param code
* @return
*/
public static String getValue(Integer code) {
for (WorkOrderStatusEnum en : WorkOrderStatusEnum.values()) {
if (en.getCode().equals(code)) {
return en.getValue();
}
}
return "error";
}
/**
* 根據(jù)value獲取code
* @param value
* @return
*/
public static Integer getCode(String value){
for (WorkOrderStatusEnum en : WorkOrderStatusEnum.values()) {
if (en.getValue().equals(value)) {
return en.getCode();
}
}
return -1;
}
private Integer code;
private String value;
}
3.業(yè)務(wù)代碼
-----------------------------------------------------------------exportWorkOrder---------------------------------------------------------------
@Override
public WorkOrderExcelFileVO exportWorkOrder(LocalDateTime createTimeStart, LocalDateTime createTimeEnd) {
WorkOrderQueryDTO dto = new WorkOrderQueryDTO();
dto.setCreateTimeStart(createTimeStart);
dto.setCreateTimeEnd(createTimeEnd);
dto.setSort("id desc");
List<WorkOrderVO> workOrderVOS = workOrderMapper.queryList(dto);
//數(shù)據(jù)庫VO 和 需要的導(dǎo)出字段VO 轉(zhuǎn)換
List<WorkOrderExcelVO> vos = WorkOrderConvert.INSTANCE.convertExcelList(workOrderVOS);
if (ObjectUtils.isEmpty(vos)) {
return null;
}
//轉(zhuǎn)換問題類型
convertProblemType(vos);
//轉(zhuǎn)換工單級別-數(shù)據(jù)轉(zhuǎn)換
convertLevel(vos);
//轉(zhuǎn)換辦結(jié)信息
convertFinishInfo(vos);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
EasyExcel.write(byteArrayOutputStream, WorkOrderExcelVO.class)
.sheet("work_order_list")
.doWrite(vos);
String fileName = System.currentTimeMillis() + ".xls";
MultipartFile file = new MockMultipartFile("file", fileName, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", byteArrayOutputStream.toByteArray());
// 上傳到minio服務(wù)
String uploadFileUrl = awsService.uploadFile(file);
// 返回文件url供前端下載
return WorkOrderExcelFileVO.builder()
.fileName(fileName)
.fileUrl(uploadFileUrl).build();
}
-----------------------------------------------------------------uploadFile---------------------------------------------------------------
@Override
@SneakyThrows(Exception.class)
public String uploadFile(MultipartFile multiFile) {
String type = null;
if(multiFile.getOriginalFilename().contains(StringPool.DOT)){
type = multiFile.getOriginalFilename().substring(multiFile.getOriginalFilename().lastIndexOf(StringPool.DOT)+1);
}
String s3Key = StringConstants.PRODUCT_FILE
+ StringPool.SLASH + RandomUtil.generateNumber(2)
+ StringPool.SLASH + IdUtil.fastSimpleUUID()+ StringPool.DOT + type;
amazonDefaultS3ClientProvider.getS3Client().putObject(
PutObjectRequest.builder()
.bucket(callCenterProperties.getS3BucketName())
.key(s3Key)
.acl(ObjectCannedACL.PUBLIC_READ)
.build(),
RequestBody.fromInputStream(multiFile.getInputStream(), multiFile.getInputStream().available()));
return callCenterProperties.getCloudFrontDomain() + s3Key;
}
-----------------------------------------------------------------AmazonDefaultS3ClientProvider---------------------------------------------------------------
public class AmazonDefaultS3ClientProvider {
private final S3Client s3Client;
private final S3AsyncClient s3AsyncClient;
public AmazonDefaultS3ClientProvider(S3Client s3Client, S3AsyncClient s3AsyncClient) {
this.s3Client = s3Client;
this.s3AsyncClient = s3AsyncClient;
}
/**
* 獲取S3異步客戶端
*
* @return S3AsyncClient
*/
public S3AsyncClient getS3AsyncClient() {
return this.s3AsyncClient;
}
/**
* 獲取S3同步客戶端
*
* @return S3Client
*/
public S3Client getS3Client() {
return s3Client;
}
}
4.利用postman調(diào)用
結(jié)果展示:
完成。