• java 导出excel示例(easyExcel)


    1.情景展示

    在javaweb项目当中,如何将数据导入excel,并将生成的excel文件返回给前端?

    2.具体分析

    可通过阿里巴巴的easyExcel来实现。

    所需jar包

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>2.2.6</version>
    </dependency>

    如果是maven项目的话,只需要引入这一个easyexcel.jar就可以了,easyExcel所依赖的其它jar包会自动被maven下载;

    截至发文,easyExcel的最新版本为:3.1.1;

    如果是非maven项目的话,我们还需要下载以下jar包;

    注意:jar包版本号不能出错。

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.17</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.17</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-schemas</artifactId>
        <version>3.17</version>
    </dependency>
    <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-collections4</artifactId>
       <version>4.1</version>
    </dependency>
    <dependency>
       <groupId>cglib</groupId>
       <artifactId>cglib</artifactId>
       <version>2.2</version>
    </dependency>

    上述这些jar包,是easyExcel-2.26.jar所依赖的版本号,如果更高版本,需要诸君自行查找对应版本号,否则会jar包冲突,这里我分享一个查找办法:

    在idea当中,我们随意打开一个maven项目的pom.xml文件,将easyexcel的依赖引入到项目当中,切换到pom树视图,搜索easyexcel,就能扒到对应的从属jar包,及其版本号。

    3.具体实现

    说明:只能导出xls格式,不支持*.xlsx格式。

    excel工具类

    package metadata.web.actions.utils;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.List;
    
    import javax.servlet.http.HttpSession;
    
    import com.alibaba.excel.EasyExcel;
    
    /**
     * Excel操作工具类
     * @description
     * @author Marydon
     * @creationTime 2022年6月18日下午3:23:41
     * @version 1.0
     * @since
     * @email marydon20170307@163.com
     */
    public class ExcelUtil {
    	
        /**
         * 根据模板导出excel
         * <p>
         * 支持简易循环填写excel
         * @param templatePath 模板路径
         * @param temporaryName 临时文件名称
         * @param out 文件输出流
         * @param head easyPoi 表头对象class
         * @param list 填充列表
         * @param col 导出类class
         * @param session session
         */
        public static void exportTemplate(String templatePath, String temporaryName, OutputStream out, Class head, Class col, List<?> list, HttpSession session) {
            String path = null;
            try {
                // 如果模板文件在resources目录下使用这个
                // InputStream resourceAsStream = col.getClassLoader().getResourceAsStream(templatePath);
                // 如果模板文件在WebRoot/WebContent目录下
                InputStream resourceAsStream = session.getServletContext().getResourceAsStream(templatePath);
                path = ExcelUtil.getFilePath(temporaryName, resourceAsStream, session);
                EasyExcel.write(out, head).needHead(false).withTemplate(path).sheet().doWrite(list);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {//删除临时文件
                if (path!=null && !"".equals(path)) {
                    File tempFile = new File(path);
                    tempFile.delete();
                    System.err.println("删除临时文件成功=====path:" + path);
                }
            }
        }
    
        /**
         * 获取临时文件路径
         * @param inputStream
         * @param session
         * @param fileName
         * @return
         * @throws IOException
         */
        public static String getFilePath(String fileName, InputStream inputStream, HttpSession session) throws IOException {
            // 模板临时目录
            String rootPath = session.getServletContext().getRealPath("templates/");
            // 临时文件路径名
            String filePath = rootPath + "_" + System.currentTimeMillis() + fileName;
            File tempFile = new File(filePath);
            // 保存到临时文件
            saveTempFile(inputStream, tempFile);
            return filePath;
        }
    
        // 保存到临时目录
        private static void saveTempFile(InputStream inputStream, File tempFile) throws IOException {
            if (!tempFile.getParentFile().exists()) { //如果文件的目录不存在
                tempFile.getParentFile().mkdirs(); //创建目录
            }
            OutputStream os = new FileOutputStream(tempFile);
            byte[] b = new byte[2048];
            int length;
            while ((length = inputStream.read(b)) > 0) {
                os.write(b, 0, length);
            }
            os.flush();
            os.close();
            inputStream.close();
        }
    
    }

    模板文件

    说明:

    我们可以在excel当中不仅可设置每一列对应的的列名称,还可以设置每列的格式。

    存放位置:

     

    模板对应的实体类

    查看代码
    /**
     * 资源库数量验证日志实体类
     * @description
     * @author Marydon
     * @creationTime 2022年6月19日下午6:21:25
     * @version 1.0
     * @since
     * @email marydon20170307@163.com
     */
    public class DataCheckEntity {
    	/**
         * 机构名称
         */
        @ExcelProperty(value = "机构名称",index = 0)
        private String ORGNAME;
        
        /**
         * 主题名称
         */
        @ExcelProperty(value = "主题名称",index = 1)
        private String PARENT_THEME_NAME;
    
        /**
         * 表名
         */
        @ExcelProperty(value = "表名",index = 2)
        private String TABLE_NAME;
    
        /**
         * 数据量
         */
        @ExcelProperty(value="数据量",index = 3)
        private Long DATA_NUM;
    
        
        /**
         * 验证日期
         */
        @ExcelProperty(value = "验证日期",index = 4)
        private String CHECK_DATE;
        
        /**
         * 批次号
         */
        @ExcelProperty(value = "批次号",index = 5)
        private String BATCH_CODE;
    
    	public String getORGNAME() {
    		return ORGNAME;
    	}
    
    	public void setORGNAME(String oRGNAME) {
    		ORGNAME = oRGNAME;
    	}
    
    	public String getPARENT_THEME_NAME() {
    		return PARENT_THEME_NAME;
    	}
    
    	public void setPARENT_THEME_NAME(String pARENT_THEME_NAME) {
    		PARENT_THEME_NAME = pARENT_THEME_NAME;
    	}
    	
    	public String getTABLE_NAME() {
    		return TABLE_NAME;
    	}
    
    	public void setTABLE_NAME(String tABLE_NAME) {
    		TABLE_NAME = tABLE_NAME;
    	}
    
    	public Long getDATA_NUM() {
    		return DATA_NUM;
    	}
    
    	public void setDATA_NUM(Long dATA_NUM) {
    		DATA_NUM = dATA_NUM;
    	}
    
    	public String getCHECK_DATE() {
    		return CHECK_DATE;
    	}
    
    	public void setCHECK_DATE(String cHECK_DATE) {
    		CHECK_DATE = cHECK_DATE;
    	}
    	
    	public String getBATCH_CODE() {
    		return BATCH_CODE;
    	}
    
    	public void setBATCH_CODE(String bATCH_CODE) {
    		BATCH_CODE = bATCH_CODE;
    	}
    
    	@Override
    	public String toString() {
    		return "DataCheckEntity [ORGNAME=" + ORGNAME + ", PARENT_THEME_NAME=" + PARENT_THEME_NAME + ", TABLE_NAME="
    				+ TABLE_NAME + ", DATA_NUM=" + DATA_NUM + ", CHECK_DATE=" + CHECK_DATE + ", BATCH_CODE=" + BATCH_CODE
    				+ "]";
    	}
    
    }

    如果使用了lombok插件,可以使用@Setter、@Getter和@ToString注解来替代。

    注解@ExcelProperty的value属性,可以不要,在插入数据的时候,是按index来决定每列所在位置的;

    所以说,即使excel的列名和实体类没有按顺序对照或者完全匹配,并不影响实际数据的插入,只会影响展示效果。

    web层调用

    /**
     * 导出至excel文件
     * @description 
     * 使用EasyExcel模板导出excel
     * @return 文件流 
     */
    public String export(){
        
        try {
            HttpServletResponse response = WebUtils.getResponse();
            HttpSession session = WebUtils.getRequest().getSession();
            
            // 响应参数设置
            response.setContentType("multipart/form-data");
            response.setContentType("application/octet-stream;charset=utf-8");
            
            // excel格式及文件名
            String fileName = URLDecoder.decode("资源库数量验证日志_" + DateUtils.getSysdateStr("yyyyMMddHHmmss"), "UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + new String(fileName.getBytes("gb2312"), "ISO8859-1") + ".xls" + "\"");
            OutputStream out = response.getOutputStream();
            
            // 获取请求参数
            //TODO 看中文是否乱码
            Map map = WebUtils.getParameterMap();
            // 查询将要导出的数据
            // 获取数据
            List<Map<String, Object>> data = boZYK_DATE_CHECK.getZYK_DATE_CHECK(map);
            List<DataCheckEntity> data2 = new ArrayList<>(data.size()); 
            // map转实体类
            for (Map<String, Object> map2 : data) {
                data2.add(MapUtil.toJavaBean(DataCheckEntity.class, map2));
            }
            
            // 根据模板导出数excel
            // ExcelUtil.exportTemplate("templates/template.xls", "model.xls", out, DataCheckEntity.class,ExcelUtil.class, data2, session);
            ExcelUtil.exportTemplate("/templates/template.xls", "model.xls", out, DataCheckEntity.class,ExcelUtil.class, data2, session);
            
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            model.put("msg", "excel导出失败");
            model.put("expMsg", e.getMessage());
        }
        
        return getResult();
    }

    写在最后

      哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

     相关推荐:

  • 相关阅读:
    Aix_bugzilla
    aix Mysql安装 Oracle官方教程
    Aix6.1安装openssh
    日媒:阿里巴巴上市融资或超Facebook
    设计模式(一)---单例模式
    Handler具体解释系列(七)——Activity.runOnUiThread()方法具体解释
    TCP/IP协议族——IP工作原理及实例具体解释(上)
    leetCode 41.First Missing Positive (第一个丢失的正数) 解题思路和方法
    Material Design之RecyclerView的使用(一)
    jQuery和CSS3超酷表单美化插件
  • 原文地址:https://www.cnblogs.com/Marydon20170307/p/16415369.html
Copyright © 2020-2023  润新知