Springboot+easyExcel 導(dǎo)出業(yè)務(wù)excel(利用自定義convert + minio)

在工作有個需求需要導(dǎo)出工單的列表信息匪凉,大致原型如下:


image.png

采用阿里開源的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)用

image.png

結(jié)果展示:

image.png

完成。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末曙砂,一起剝皮案震驚了整個濱河市埋凯,隨后出現(xiàn)的幾起案子脆诉,更是在濱河造成了極大的恐慌,老刑警劉巖伐坏,帶你破解...
    沈念sama閱讀 212,080評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件怔匣,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)每瞒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評論 3 385
  • 文/潘曉璐 我一進(jìn)店門金闽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人剿骨,你說我怎么就攤上這事代芜。” “怎么了浓利?”我有些...
    開封第一講書人閱讀 157,630評論 0 348
  • 文/不壞的土叔 我叫張陵挤庇,是天一觀的道長。 經(jīng)常有香客問我贷掖,道長嫡秕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,554評論 1 284
  • 正文 為了忘掉前任苹威,我火速辦了婚禮昆咽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘屠升。我一直安慰自己潮改,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,662評論 6 386
  • 文/花漫 我一把揭開白布腹暖。 她就那樣靜靜地躺著汇在,像睡著了一般。 火紅的嫁衣襯著肌膚如雪脏答。 梳的紋絲不亂的頭發(fā)上糕殉,一...
    開封第一講書人閱讀 49,856評論 1 290
  • 那天,我揣著相機(jī)與錄音殖告,去河邊找鬼阿蝶。 笑死,一個胖子當(dāng)著我的面吹牛黄绩,可吹牛的內(nèi)容都是我干的羡洁。 我是一名探鬼主播,決...
    沈念sama閱讀 39,014評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼爽丹,長吁一口氣:“原來是場噩夢啊……” “哼筑煮!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起粤蝎,我...
    開封第一講書人閱讀 37,752評論 0 268
  • 序言:老撾萬榮一對情侶失蹤真仲,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后初澎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秸应,經(jīng)...
    沈念sama閱讀 44,212評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,541評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了软啼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桑谍。...
    茶點故事閱讀 38,687評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖焰宣,靈堂內(nèi)的尸體忽然破棺而出霉囚,到底是詐尸還是另有隱情,我是刑警寧澤匕积,帶...
    沈念sama閱讀 34,347評論 4 331
  • 正文 年R本政府宣布盈罐,位于F島的核電站,受9級特大地震影響闪唆,放射性物質(zhì)發(fā)生泄漏盅粪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,973評論 3 315
  • 文/蒙蒙 一悄蕾、第九天 我趴在偏房一處隱蔽的房頂上張望票顾。 院中可真熱鬧,春花似錦帆调、人聲如沸奠骄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽含鳞。三九已至,卻和暖如春芹务,著一層夾襖步出監(jiān)牢的瞬間蝉绷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評論 1 266
  • 我被黑心中介騙來泰國打工枣抱, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留熔吗,地道東北人。 一個月前我還...
    沈念sama閱讀 46,406評論 2 360
  • 正文 我出身青樓佳晶,卻偏偏與公主長得像桅狠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子轿秧,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,576評論 2 349

推薦閱讀更多精彩內(nèi)容