使用Groovy 动态编译生成class文件,再结合 easyexcel 导出excel

使用Groovy 动态编译生成class文件,再结合 easyexcel 导出excel

前提

​ easyexcel 的使用必须要有实体类,然后根据实体类上的注解@ExcelProperty 实现,根据字段导出数据到excel中

缺点

​ 必须要具有一个entity.java 文件,如果只是为了解决日常的解决问题,那么当遇到需要导出excel的问题时,就要再生成一个对应的java文件,这样就很麻烦了,如果在工作中,那么就需要大量繁琐的实体java文件

解决办法

​ 只需要输入表名、列名,查询数据库结果,动态编译生成class文件,然后使用生成的class文件作为实体和数据库结果进行excel数据的导出。

  1. 依赖文件,需要 mysql、easyexcel、groovy
<dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.19</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>2.2.10</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>2.4.13</version>
    </dependency>
  1. 具体工具类
package com.rule.utils;

        import com.alibaba.excel.EasyExcelFactory;
        import groovy.lang.GroovyClassLoader;
        import org.springframework.util.Assert;

        import java.io.File;
        import java.io.IOException;
        import java.lang.reflect.Method;
        import java.sql.Connection;
        import java.sql.DriverManager;
        import java.sql.PreparedStatement;
        import java.sql.ResultSet;
        import java.sql.SQLException;
        import java.util.ArrayList;
        import java.util.List;

        public class GenEntityUtil {

            private static String tableName;

            private static String queryFields;
            /**
             * 解析处理(生成实体类主体代码)
             */

            private static String parse(String[] colNames) {
                StringBuilder sb = new StringBuilder();

                sb.append("package com.rule.pojo;").append("\n");
                sb.append("import com.alibaba.excel.annotation.ExcelProperty;").append("\n\n");

                sb.append("public class ").append(camelStr(tableName, true)).append(" {\r\n");

                processAllAttrs(sb, colNames);

                processAllMethod(sb, colNames);

                sb.append("}\r\n");

                System.out.println(sb.toString());

                return sb.toString();

            }

            /**
             * 生成所有的方法
             *
             * @param sb
             */

            private static void processAllMethod(StringBuilder sb, String[] colNames) {
                for (String colname : colNames) {
                    sb.append("\tpublic " + "String" + " get").append(camelStr(colname, true)).append("(){\r\n");

                    sb.append("\t\treturn ").append(camelStr(colname)).append(";\r\n");

                    sb.append("\t}\r\n");

                    sb.append("\tpublic void set").append(camelStr(colname, true)).append("(").append("String").append(" ").append(camelStr(colname)).append("){\r\n");

                    sb.append("\t\tthis.").append(camelStr(colname)).append(" = ").append(camelStr(colname)).append(";\r\n");

                    sb.append("\t}\r\n");

                }
            }


            /**
             * 解析输出属性
             *
             * @return
             */

            private static void processAllAttrs(StringBuilder sb, String[] colNames) {
                for (String colname : colNames) {
                    sb.append("\t@ExcelProperty(\"").append(colname).append("\")\r\n");
                    sb.append("\tprivate " + "String" + " ").append(camelStr(colname)).append(";\r\n");
                }

            }

            /**
             * 把输入字符串的首字母改成大写, 下划线的colName转换为驼峰
             *
             * @param str colName
             * @return camel name
             */

            private static String camelStr(String str, boolean... method) {
                char[] ch = str.toCharArray();
                for (int i = 1; i < ch.length; i++) {
                    if (ch[i - 1] == '_') {
                        ch[i] = (char) (ch[i] - 32);
                    }
                }
                if (method.length > 0) {
                    ch[0] = (char) (ch[0] - 32);
                }
                return new String(ch).replace("_", "");
            }

            /**
             * 获取项目所在路径
             *
             * @return
             */
            public static String getRealPath() throws IOException {
                String realPath = GenEntityUtil.class.getClassLoader().getResource("").getPath();
                realPath = realPath + File.separator + "com" +
                        File.separator + "rule" +
                        File.separator + "pojo" +
                        File.separator;
                try {
                    //路径decode转码
                    realPath = java.net.URLDecoder.decode(realPath, "utf-8");
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return realPath;
            }

            public static void doGen() throws Exception {
                String[] columnNames = queryFields.split(",");
                String content = parse(columnNames);
                GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
                Class<?> clazz = groovyClassLoader.parseClass(content);
                export(clazz, data(clazz, columnNames, getData()));
            }

            public static List<Object> data(Class<?> loadClass, String[] columnNames, List<String[]> rawData) throws Exception {
                List<Object> data = new ArrayList<>(rawData.size());
                for (String[] rawDatum : rawData) {
                    Object instance = loadClass.newInstance();
                    for (int i = 0; i < rawDatum.length; i++) {
                        String field = camelStr(columnNames[i], true);
                        Method method = loadClass.getDeclaredMethod("set" + field, String.class);
                        method.invoke(instance, rawDatum[i]);

                    }
                    data.add(instance);
                }
                return data;
            }

            public static void export(Class<?> clazz, List<Object> tableList) {
                String fileName = "C:\\Users\\rulelau\\Desktop\\" + System.currentTimeMillis() + ".xlsx";
                EasyExcelFactory.write(fileName, clazz).sheet("sheet1").doWrite(tableList);

            }

            public static void main(String[] args) throws Exception {
                tableName = "undo_log";
                queryFields = "branch_id,xid,context,rollback_info,log_status,log_created,log_modified";
                doGen();
            }

            public static List<String[]> getData() {
                List<String[]> checkTables = new ArrayList<>(10000);
                String[] allArray = queryFields.split(",");
                String sql = "SELECT " + queryFields + " FROM " + tableName;
                Connection con = Conn.getConnection();
                Assert.notNull(con, "con 连接对象不能为空");
                try (PreparedStatement statement = con.prepareStatement(sql)) {
                    ResultSet rs = statement.executeQuery();
                    while (rs != null && rs.next()) {
                        String[] fieldValues = new String[allArray.length];
                        for (int i = 0; i < allArray.length; i++) {
                            Object value = rs.getObject(allArray[i]);
                            fieldValues[i] = value == null ? null : value.toString();
                        }
                        checkTables.add(fieldValues);
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                return checkTables;
            }

            public static class Conn {
                private static Connection conn;

                public static Connection getConnection() {
                    if (conn != null) {
                        return conn;
                    }
                    String url = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai";
                    String Driver = "com.mysql.cj.jdbc.Driver";
                    String Userid = "root";
                    String Password = "123456";
                    try {
                        Class.forName(Driver);
                        System.out.println(url);
                        conn = DriverManager.getConnection(url, Userid, Password);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return conn;
                }

            }

        }
```

效果

  1. 生成的class文件

  2. 下载的文件

猜你喜欢

转载自blog.csdn.net/LarrYFinal/article/details/117856487