SpringBoot 통합 EasyExcel 파일 가 져 오기 내 보 내기

준비 작업
주의:클릭 하여 홈 페이지 데모 보기
1.pom 의존 도입

        <!--easyExcel-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
        </dependency>
2.기능 실현
  • Vue 전단 과 결합 하여 브 라 우 저 페이지 에서 로그 파일 을 직접 내 보 냅 니 다
  • 파일 가 져 오기
    엑셀 파일 다운로드
    3.로그 실체 클래스
    실체 클래스 에는 사용자 정의 변환기 가 있 습 니 다.자바 형식 데이터 와 엑셀 형식 데이터 의 변환 에 사용 되 며 매우 사 용 됩 니 다.주 해 를 결합 하면 엑셀 파일 내 보 내기 가 매우 편리 합 니 다.
    
    /**
     * <p>
     *       
     * </p>
     *
     * @author horse
     * @since 2020-09-08
     *   :         @Accessory(chain=true),               ,        
     */
    @Data
    @EqualsAndHashCode(callSuper = false)
    @TableName("tb_operational_log")
    @ApiModel(value = "OperationalLog  ", description = "      ")
    public class OperationalLog implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @ExcelProperty({"    ", "  ID"})
        @ApiModelProperty(value = "  ID")
        @TableId(value = "id", type = IdType.ASSIGN_ID)
        private String id;
    
        @ExcelProperty({"    ", "    "})
        @ApiModelProperty(value = "    ")
        private String operType;
    
        @ExcelProperty({"    ", "    "})
        @ApiModelProperty(value = "    ")
        private String operDesc;
    
        @ExcelProperty({"    ", "   ID"})
        @ApiModelProperty(value = "   ID")
        private String operUserId;
    
        @ExcelProperty({"    ", "     "})
        @ApiModelProperty(value = "     ")
        private String operUserName;
    
        @ExcelProperty({"    ", "    "})
        @ApiModelProperty(value = "    ")
        private String operMethod;
    
        @ExcelProperty({"    ", "    "})
        @ApiModelProperty(value = "    ")
        private String operRequWay;
    
        @ExcelProperty(value = {"    ", "    :  -ms"}, converter = CustomRequestTimeConverter.class)
        @ApiModelProperty(value = "    :  -ms")
        private Long operRequTime;
    
        @ExcelProperty({"    ", "    "})
        @ApiModelProperty(value = "    ")
        private String operRequParams;
    
        @ExcelProperty({"    ", "  Body"})
        @ApiModelProperty(value = "  Body")
        private String operRequBody;
    
        @ExcelProperty({"    ", "  IP"})
        @ApiModelProperty(value = "  IP")
        private String operRequIp;
    
        @ExcelProperty({"    ", "  URL"})
        @ApiModelProperty(value = "  URL")
        private String operRequUrl;
    
        @ExcelProperty(value = {"    ", "    "}, converter = CustomLogFlagConverter.class)
        @ApiModelProperty(value = "    : 1-admin,0-portal")
        private Boolean logFlag;
    
        @ExcelProperty({"    ", "    "})
        @ApiModelProperty(value = "    :1-  ,0-  ")
        @TableField(value = "is_success")
        private Boolean success;
    
        @ExcelIgnore
        @ApiModelProperty(value = "     1-   , 0-  ")
        @TableField(value = "is_deleted")
        @TableLogic(value = "1", delval = "0")
        private Boolean deleted;
    
        @ExcelProperty(value = {"    ", "    "}, converter = CustomTimeFormatConverter.class)
        @ApiModelProperty(value = "    ")
        private Date gmtCreate;
    }
    
    4.인터페이스 와 구체 적 실현
    4.1 인터페이스
    
        @OperatingLog(operType = BlogConstants.EXPORT, operDesc = "      ,       ")
        @ApiOperation(value = "      ", hidden = true)
        @PostMapping("/oper/export")
        public void operLogExport(@RequestBody List<String> logIds, HttpServletResponse response) {
            operationalLogService.operLogExport(logIds, response);
        }
    
    4.2 구체 적 실현
    사용자 정의 내 보 내기 정책 HorizontalCellStyleStrategy사용자 정의 내 보 내기 차단기 CellWrite Handler,더 정확 한 사용자 정의 내 보 내기 정책
    
        /**
         *       (        )
         *
         * @param logIds
         * @param response
         */
        @Override
        public void operLogExport(List<String> logIds, HttpServletResponse response) {
            OutputStream outputStream = null;
            try {
                List<OperationalLog> operationalLogs;
                LambdaQueryWrapper<OperationalLog> queryWrapper = new LambdaQueryWrapper<OperationalLog>()
                        .orderByDesc(OperationalLog::getGmtCreate);
                //   logIds  null,  id    ,      
                if (!CollectionUtils.isEmpty(logIds)) {
                    operationalLogs = this.listByIds(logIds);
                } else {
                    operationalLogs = this.list(queryWrapper);
                }
                outputStream = response.getOutputStream();
    
                //        
                HorizontalCellStyleStrategy strategy = MyCellStyleStrategy.getHorizontalCellStyleStrategy();
    
                //          
                EasyExcel.write(outputStream, OperationalLog.class).excelType(ExcelTypeEnum.XLSX).sheet("      ")
                        // .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) //      (     ,     )
                        .registerWriteHandler(strategy) //            
                        .registerWriteHandler(new CustomCellWriteHandler()) //          
                        .doWrite(operationalLogs);
            } catch (Exception e) {
                log.error(ExceptionUtils.getMessage(e));
                throw new BlogException(ResultCodeEnum.EXCEL_DATA_EXPORT_ERROR);
            } finally {
                IoUtil.close(outputStream);
            }
        }
    
    
    사용자 정의 내 보 내기 정책 은 다음 과 같 습 니 다.
    
    /**
     * @author Mr.Horse
     * @version 1.0
     * @description:        
     * @date 2021/4/30 8:43
     */
    
    public class MyCellStyleStrategy {
    
        /**
         *        (     )
         *
         * @return     
         */
        public static HorizontalCellStyleStrategy getHorizontalCellStyleStrategy() {
            //     
            WriteCellStyle headerCellStyle = new WriteCellStyle();
            //         
            headerCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
            //    
            headerCellStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
            WriteFont headerFont = new WriteFont();
            headerFont.setFontHeightInPoints((short) 14);
            headerCellStyle.setWriteFont(headerFont);
            //     
            headerCellStyle.setWrapped(Boolean.FALSE);
    
            //     
            WriteCellStyle contentCellStyle = new WriteCellStyle();
            //            ,  49           
            contentCellStyle.setDataFormat((short) 49);
            //      :      FillPatternType  FillPatternType.SOLID_FOREGROUND           .     FillPatternType       
            contentCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
            contentCellStyle.setFillForegroundColor(IndexedColors.GREY_40_PERCENT.getIndex());
            //         
            contentCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
            //     
            WriteFont contentFont = new WriteFont();
            contentFont.setFontHeightInPoints((short) 12);
            contentCellStyle.setWriteFont(contentFont);
            //       
            contentCellStyle.setWrapped(Boolean.FALSE);
            //          
            contentCellStyle.setBorderLeft(MEDIUM);
            contentCellStyle.setBorderTop(MEDIUM);
            contentCellStyle.setBorderRight(MEDIUM);
            contentCellStyle.setBorderBottom(MEDIUM);
            contentCellStyle.setTopBorderColor(IndexedColors.RED.getIndex());
            contentCellStyle.setBottomBorderColor(IndexedColors.GREEN.getIndex());
            contentCellStyle.setLeftBorderColor(IndexedColors.YELLOW.getIndex());
            contentCellStyle.setRightBorderColor(IndexedColors.ORANGE.getIndex());
    
            //             
            return new HorizontalCellStyleStrategy(headerCellStyle, contentCellStyle);
        }
    }
    
    
    사용자 정의 내 보 내기 차단 기 는 다음 과 같 습 니 다.
    
    /**
     * @author Mr.Horse
     * @version 1.0
     * @description   CellWriteHandler  ,              
     * @date 2021/4/29 21:11
     */
    public class CustomCellWriteHandler implements CellWriteHandler {
    
        private static Logger logger = LoggerFactory.getLogger(CustomCellWriteHandler.class);
    
        @Override
        public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
                                     Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
    
        }
    
        /**
         *        (     )
         *
         * @param writeSheetHolder
         * @param writeTableHolder
         * @param cell
         * @param head
         * @param relativeRowIndex
         * @param 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 relativeRowIndex,
                                           Boolean isHead) {
    
        }
    
        /**
         *       (    ):               EasyExcel   (       excel 0,1     ,            )
         *                  ,          
         *
         * @param writeSheetHolder
         * @param writeTableHolder
         * @param cellDataList
         * @param cell
         * @param head
         * @param relativeRowIndex
         * @param isHead
         */
        @Override
        public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
                                     List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex,
                                     Boolean isHead) {
            //      
            if (isHead && cell.getRowIndex() == 0 && cell.getColumnIndex() == 0) {
                logger.info(" ==>  {} , {}        ", cell.getRowIndex(), cell.getColumnIndex());
                CreationHelper helper = writeSheetHolder.getSheet().getWorkbook().getCreationHelper();
                Hyperlink hyperlink = helper.createHyperlink(HyperlinkType.URL);
                hyperlink.setAddress("https://github.com/alibaba/easyexcel");
                cell.setHyperlink(hyperlink);
            }
            //          
            boolean bool = isHead && cell.getRowIndex() == 1 &&
                    (cell.getStringCellValue().equals("    ") || cell.getStringCellValue().equals("  Body"));
            if (bool) {
                logger.info(" {} , {}          。", cell.getRowIndex(), cell.getColumnIndex());
                //      
                Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
                CellStyle cellStyle = workbook.createCellStyle();
    
                Font cellFont = workbook.createFont();
                cellFont.setBold(Boolean.TRUE);
                cellFont.setFontHeightInPoints((short) 14);
                cellFont.setColor(IndexedColors.SEA_GREEN.getIndex());
                cellStyle.setFont(cellFont);
                cell.setCellStyle(cellStyle);
            }
        }
    }
    
    
    4.3 전단 요청
    프론트 엔 드 는 Vue+Element 기반 으로 내 보 내기 단 추 를 눌 러 브 라 우 저 페이지 에서 다운로드 할 수 있 습 니 다.
    
    //     
        batchExport() {
          //     id    
          const logIds = []
          this.multipleSelection.forEach(item => {
            logIds.push(item.id)
          })
           //       
          axios({
            url: this.BASE_API + '/admin/blog/log/oper/export',
            method: 'post',
            data: logIds,
            responseType: 'arraybuffer',
            headers: { 'token': getToken() }
          }).then(response => {
            // type           ,     excel  
            const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' })
            const pdfUrl = window.URL.createObjectURL(blob)
            const fileName = 'HorseBlog    ' //        
            //   <a>  ,   Firefox   Chrome(  )   download   
            if ('download' in document.createElement('a')) {
              const link = document.createElement('a')
              link.href = pdfUrl
              link.setAttribute('download', fileName)
              document.body.appendChild(link)
              link.click()
              window.URL.revokeObjectURL(pdfUrl) //   URL   
            } else {
              // IE        
              window.navigator.msSaveBlob(blob, fileName)
            }
          })
        }
    
    테스트 결과:괜 찮 습 니 다.페이지 다운로드 기능 이 기본적으로 구현 되 었 습 니 다.
    Excel 파일 가 져 오기
    5.파일 읽 기 설정
    이 설정 은 일반적인 방식 으로 작 성 됩 니 다.확장 성 이 강 합 니 다.
    
    /**
     * @author Mr.Horse
     * @version 1.0
     * @description: EasyExcel      (   spring  )
     * @date 2021/4/27 13:24
     */
    
    public class MyExcelImportConfig<T> extends AnalysisEventListener<T> {
    
        private static Logger logger = LoggerFactory.getLogger(MyExcelImportConfig.class);
    
        /**
         *            
         */
        private static final int MAX_BATCH_COUNT = 10;
    
        /**
         *   bean  
         */
        private T dynamicService;
    
        /**
         *           List  
         */
        List<T> list = new ArrayList<>();
    
    
        /**
         *       bean(     bean    )
         *
         * @param dynamicService
         */
        public MyExcelImportConfig(T dynamicService) {
            this.dynamicService = dynamicService;
        }
    
        /**
         *            
         *
         * @param data
         * @param context
         */
        @Override
        public void invoke(T data, AnalysisContext context) {
            logger.info(" ==>       : {}", JacksonUtils.objToString(data));
            list.add(data);
            if (list.size() > MAX_BATCH_COUNT) {
                //     
                saveData();
                //   list
                list.clear();
            }
        }
    
        /**
         *          ,      
         *   :           MAX_BATCH_COUNT          
         *
         * @param context
         */
        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
            saveData();
            logger.info(" ==>        <==");
        }
    
        /**
         *     :          ,      
         */
        private void saveData() {
            logger.info(" ==>       : {}", list.size());
            list.forEach(System.out::println);
            logger.info(" ==>        <==");
        }
    
        /**
         *                    。                  。                  。
         *
         * @param exception
         * @param context
         * @throws Exception
         */
        @Override
        public void onException(Exception exception, AnalysisContext context) throws Exception {
            logger.error(" ==>       ,         :{}", exception.getMessage());
            //                         
            if (exception instanceof ExcelDataConvertException) {
                ExcelDataConvertException convertException = (ExcelDataConvertException) exception;
                logger.error(" {} , {}       ", convertException.getRowIndex(), convertException.getColumnIndex());
            }
        }
    
    }
    
    
    6.읽 기 테스트
    
        @ApiOperation(value = "      ", notes = "        [OperationalLog]", hidden = true)
        @PostMapping("/import")
        public R excelImport(@RequestParam("file") MultipartFile file) throws IOException {
            EasyExcel.read(file.getInputStream(), OperationalLog.class, new MyExcelImportConfig<>(operationalLogService))
                    .sheet().doRead();
            return R.ok().message("      ");
        }
    
    7.사용자 정의 속성 변환기 첨부
    변환기 의 속성 내용 전환 은 자신의 실제 업무 수요 에 따라 정 해 야 한다.여 기 는 간단 한 사례 로 만 볼 수 있다.
    
    /**
     * @author Mr.Horse
     * @version 1.0
     * @description:    excel   :                "ms"
     * @date 2021/4/27 10:25
     */
    
    public class CustomRequestTimeConverter implements Converter<Long> {
    
        /**
         *      :      java    
         *
         * @return
         */
        @Override
        public Class<Long> supportJavaTypeKey() {
            return Long.class;
        }
    
        /**
         *      : excel       ,       long  ,  excel NUMBER  ,    "ms     STRING  "
         *
         * @return
         */
        @Override
        public CellDataTypeEnum supportExcelTypeKey() {
            return CellDataTypeEnum.STRING;
        }
    
        /**
         *     
         *
         * @param cellData
         * @param contentProperty
         * @param globalConfiguration
         * @return
         * @throws Exception
         */
        @Override
        public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
            //      : "ms",   long  
            String value = cellData.getStringValue();
            return Long.valueOf(value.substring(0, value.length() - 2));
        }
    
        @Override
        public CellData<Long> convertToExcelData(Long value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
            //      : "ms"
            return new CellData<>(String.valueOf(value).concat("ms"));
        }
    }
    
    포맷 시간
    
    /**
     * @author Mr.Horse
     * @version 1.0
     * @description: {description}
     * @date 2021/4/27 14:01
     */
    
    public class CustomTimeFormatConverter implements Converter<Date> {
    
        @Override
        public Class<Date> supportJavaTypeKey() {
            return Date.class;
        }
    
        @Override
        public CellDataTypeEnum supportExcelTypeKey() {
            return CellDataTypeEnum.STRING;
        }
    
        @Override
        public Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
            String value = cellData.getStringValue();
            return DateUtil.parse(value, DatePattern.NORM_DATETIME_PATTERN);
        }
    
        @Override
        public CellData<Date> convertToExcelData(Date value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
            return new CellData<>(DateUtil.format(value, DatePattern.NORM_DATETIME_PATTERN));
        }
    }
    
    
    Easy Excel 간단하게 사용,여기 서 끝,마무리.
    이상 은 SpringBoot 통합 Easy Excel 구현 파일 가 져 오기 내 보 내기 에 대한 상세 한 내용 입 니 다.SpringBoot 통합 Easy Excel 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!

    좋은 웹페이지 즐겨찾기