spring boot +vue 读取excel数据代码生成器

项目介绍

最近在开发工程中,需要根据excel中的数据生成标签类,手写太费劲啦,还得一边写一边对,受不了啦 决定写一个解析工具,自动生成代码

项目架构

项目采用springboot +vue的开发方式,但vue并不是分离项目,而是集成在项目内部,加入定时任务每天零点删除指定文件夹的生成文件,避免产生垃圾文件,提供工具生成和下载功能

项目开发 

引入依赖

    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        


        
            com.alibaba
            easyexcel
            2.1.1
        

        
            com.squareup
            javapoet
            1.11.1
        


    

配置文件

server.port=10086
spring.servlet.multipart.max-file-size=20MB
spring.servlet.multipart.max-request-size=25MB

日志配置








    
    
    
    

    
        
        
            %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger -%msg%n
        
    


    
    
        
            %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger -%msg%n
        
        
        
        
            
            ${logPath}/info/%d.log
            
            ${maxHistory}

        
    

    
    
        
        
            ERROR
        
        
            %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger -%msg%n
        
        
            ${logPath}/error/%d.log
            60
        
    

    
    
    

    
        
        
        
        
    


引入vue、axios、element-ui以及字体文件

spring boot +vue 读取excel数据代码生成器_第1张图片

具体项目会放在资源中,想要的私聊或者下载 

index.html 




    
    
    微服务生成Tag工具
    
    
    
    
    
    
    
    
    
    



微服务生成Tag工具

自动生成表单信息

将文件拖到此处,或点击上传

路由页面配置

package com.test.excelservice.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 跳转页面配置
 * @author shilei
 */
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
    }

}

 解析逻辑

package com.test.excelservice.controller;

import com.alibaba.excel.EasyExcel;
import com.test.excelservice.generateor.GeneratorUtils;
import com.test.excelservice.model.GeneInfo;
import com.test.excelservice.model.ReqParam;
import com.test.excelservice.model.ResParam;
import com.test.excelservice.result.Result;
import com.test.excelservice.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 解析excel信息生成tag
 * @author shilei
 */
@RestController
public class ExcelController {

    private Logger logger = LoggerFactory.getLogger(ExcelController.class);

    private  Pattern pattern = Pattern.compile("[\u4e00-\u9fa5]");

    @RequestMapping("/parse/file")
    public Result> pareExcel(MultipartFile file, GeneInfo geneInfo) {

        try{
            logger.info("读取"+file.getOriginalFilename()+"文件");
            logger.info("读取"+geneInfo.getSheetName()+"sheet页的excel数据");
            // 读取excel数据
            List> data = EasyExcel
                    .read(file.getInputStream())
                    .sheet(geneInfo.getSheetName())
                    .headRowNumber(0)
                    .doReadSync();

            // 请求参数list
            List reqParams = new ArrayList<>();
            // 响应参数list
            List resParams = new ArrayList<>();
            // 读取请求参数标识
            boolean readerReqFlag =false;
            // 读取响应参数标识
            boolean readerResFlag =false;
            for (int i = 0; i < data.size(); i++) {

                HashMap stringStringHashMap = data.get(i);

                if(stringStringHashMap.containsValue("请求报文")){
                    // 跳过一条
                    i+=1;
                    readerReqFlag = true;
                    continue;
                }
                if(stringStringHashMap.containsValue("响应报文")){
                    // 跳过一条
                    i+=1;
                    readerReqFlag = false;
                    readerResFlag = true;
                    continue;
                }
                // 读取请求报文
                if(readerReqFlag){
                    ReqParam reqParam = new ReqParam();
                    reqParam.setFiledName(stringStringHashMap.get(0));
                    reqParam.setFiledDesc(stringStringHashMap.get(1));
                    reqParams.add(reqParam);
                }
                // 读取响应报文
                if(readerResFlag){
                    String field = stringStringHashMap.get(0).toLowerCase();
                    Matcher matcher = pattern.matcher(field);
                    // 跳过List Row和中文描述的响应报文行
                    if(field.contains("list")||field.contains("row")||matcher.find()){
                        // 跳过一条
                        i+=1;
                        continue;
                    }
                    ResParam resParam = new ResParam();
                    resParam.setFiledName(stringStringHashMap.get(0));
                    resParam.setFiledDesc(stringStringHashMap.get(1));
                    resParams.add(resParam);
                }

            }
            logger.info("读取"+geneInfo.getSheetName()+"成功");
            if(StringUtils.isNotNull(reqParams) && StringUtils.isNotNull(resParams)){
                logger.info("正在生成接口中....");
                GeneratorUtils.generatorInterFace(geneInfo,reqParams,resParams);
                logger.info("生成接口成功!!!");
            }
            ArrayList geneInfos = new ArrayList<>();
            geneInfo.setFileName(geneInfo.getClientInterFaceName());
            // 添加客户端下载对象
            geneInfos.add(geneInfo);
            // 创建服务端下载对象
            GeneInfo serverGeneInfo = new GeneInfo();
            BeanUtils.copyProperties(geneInfo,serverGeneInfo);
            serverGeneInfo.setFileName(serverGeneInfo.getServerInterFaceName());
            geneInfos.add(serverGeneInfo);
            return new Result>(200,geneInfos);
        }catch (Exception e){
            logger.error("自动生成接口失败",e);
            return new Result>(500, Collections.emptyList());
        }
    }


    @GetMapping("/downLoadFile")
    public void downLoadFile(@RequestParam("path") String path, @RequestParam("name") String name, HttpServletResponse response) throws Exception {

        response.setContentType("text/html;charset=UTF-8");
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        long fileLength = (new File(path)).length();
        response.setContentType("application/octet-stream;charset=GBK");
        response.setHeader("Content-disposition", "attachment; filename=" + new String(name.getBytes("GB2312"), "ISO-8859-1"));
        response.setHeader("Content-Length", String.valueOf(fileLength));
        bis = new BufferedInputStream(new FileInputStream(path));
        bos = new BufferedOutputStream(response.getOutputStream());
        byte[] buff = new byte[2048];

        int bytesRead;
        while(-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
            bos.write(buff, 0, bytesRead);
        }

        bis.close();
        bos.close();

    }


}

解析工具类

package com.test.excelservice.generateor;

import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.TypeSpec;
import com.test.excelservice.model.GeneInfo;
import com.test.excelservice.model.ReqParam;
import com.test.excelservice.model.ResParam;
import com.test.excelservice.util.StringUtils;

import javax.lang.model.element.Modifier;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * 生成接口工具类
 * @Author shilei
 */
public class GeneratorUtils {


     // 请求前缀
    public static final String RQ_PREFIX = "RQ_";

    // 响应前缀
    public static final String RS_PREFIX = "RS_";

    // 下划线
    public static final String UNDERLINE = "_";

    /**
     * 生成接口工具类
     */
    public static  void  generatorInterFace(GeneInfo geneInfo, List reqParams, List resParams) throws IOException {

        HashMap> filedHashMap = generatorFiled(reqParams, resParams,geneInfo);


        Iterator>> iterator = filedHashMap.entrySet().iterator();

        while (iterator.hasNext()){
            Map.Entry> next = iterator.next();

            TypeSpec builder = TypeSpec.interfaceBuilder(next.getKey()).addFields(next.getValue()).build();
            JavaFile file = JavaFile.builder(geneInfo.getPackageName(), builder)
                    .indent("    ")
                    .build();
            File dirFile = new File(geneInfo.getDirPath());
            if (!dirFile.getParentFile().exists()) {
                dirFile.getParentFile().mkdirs();
            }
            file.writeTo(dirFile);

        }
    }


    /**
     * 生成属性列表
     */

    public static HashMap> generatorFiled(List reqParams, List resParams,GeneInfo geneInfo){
        // 最终结果
        HashMap> result = new HashMap<>();
        // 请求字段列表
        List reqFiledList = new ArrayList<>();
        // 响应字段列表
        List resFiledList = new ArrayList<>();
        // 处理之后的请求参数
        List reqParamResult =new ArrayList<>();
        // 处理之后的响应参数
        List resParamResult =new ArrayList<>();

        for (ReqParam reqParam : reqParams) {
            // 响应报文加请求
            ResParam resParam = new ResParam();
            resParam.setFiledName(RQ_PREFIX+reqParam.getFiledName());
            resParam.setFiledDesc(reqParam.getFiledDesc());
            resParamResult.add(resParam);
            // 请求报文加前缀
            reqParam.setFiledName(RQ_PREFIX+reqParam.getFiledName());
            reqParamResult.add(reqParam);


        }
        for (ResParam resParam : resParams) {
            // 请求报文加响应
            ReqParam reqParam = new ReqParam();
            reqParam.setFiledName(RS_PREFIX+resParam.getFiledName());
            reqParam.setFiledDesc(resParam.getFiledDesc());
            reqParamResult.add(reqParam);
            // 响应报文加前缀
            resParam.setFiledName(RS_PREFIX+resParam.getFiledName());
            resParamResult.add(resParam);
        }

        if(StringUtils.isNotNull(reqParamResult)){
            for (ReqParam reqItem : reqParamResult) {
                FieldSpec filed = FieldSpec.builder(String.class, reqItem.getFiledName().toUpperCase())
                        .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
                        .initializer("$S",lowerFirst(removePrefix(reqItem.getFiledName())))
                        .addJavadoc(reqItem.getFiledDesc())
                        .build();
                reqFiledList.add(filed);
            }
        }

        if(StringUtils.isNotNull(resParamResult)){
            for (ResParam resItem : resParamResult) {
                FieldSpec filed = FieldSpec.builder(String.class, resItem.getFiledName().toUpperCase())
                        .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
                        .initializer("$S",upperFirst(removePrefix(resItem.getFiledName())))
                        .addJavadoc(resItem.getFiledDesc())
                        .build();
                resFiledList.add(filed);
            }
        }

        result.put(geneInfo.getClientInterFaceName(),reqFiledList);
        result.put(geneInfo.getServerInterFaceName(),resFiledList);

        return result;
    }


    /**
     * 去掉字符串前缀
     * @return String
     */
    public  static String removePrefix(String str) {
        if (str == null || "".equals(str)) {
            return "";
        } else {
            if (str.contains(UNDERLINE)) {
                String[] split = str.split(UNDERLINE);
                return split[1];
            }
            return str;

        }
    }

    /**
     * 首字母转小写
     * @param str
     * @return
     */
    public static String lowerFirst(String str) {
        str = Character.toLowerCase(str.charAt(0)) + str.substring(1);
        return str;
    }

    /**
     * 首字母转大写
     * @param str
     * @return
     */
    public static String upperFirst(String str) {
        str = Character.toUpperCase(str.charAt(0)) + str.substring(1);
        return str;
    }

}



定时任务删除指定文件

package com.test.excelservice.scheduled;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;

import java.io.File;

/**
 * 定时任务删除指定文件夹下的所有文件
 * @author shilei
 */
public class RemoveFileScheduled {

    /**
     * PATH 服务器下指定文件目录
     */
    public static final  String  PATH = "/opt/exceldata/data";

    private final Logger logger = LoggerFactory.getLogger(RemoveFileScheduled.class);

    @Scheduled(cron = "0 0 00 * * ?")
    public void executeRemove() {
        removeFile(new File(PATH));
    }

    public  void removeFile(File file){
        if (file == null || !file.exists()){
            logger.error("文件删除失败,请检查文件路径是否正确");
            return;
        }
        //取得这个目录下的所有子文件对象
        File[] files = file.listFiles();
        //遍历该目录下的文件对象
        for (File f: files){
            String name = file.getName();
            logger.info("文件名为"+ name);
            //判断子目录是否存在子目录,如果是文件则删除
            if (f.isDirectory()){
                removeFile(f);
            }else {
                f.delete();
            }
        }
        //删除空文件夹  for循环已经把上一层节点的目录清空。
        file.delete();
    }
}

运行效果 

spring boot +vue 读取excel数据代码生成器_第2张图片

spring boot +vue 读取excel数据代码生成器_第3张图片

 spring boot +vue 读取excel数据代码生成器_第4张图片

 由于没有持久化到数据库,所以,下载不能够刷新页面,想加可以加一下

你可能感兴趣的:(工作中,spring,boot,vue.js,后端)