• Springboot导出Excel并下载


    一、引入相关依赖

    <!--数据导出excel-->
    <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.17</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.17</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-schemas</artifactId>
        <version>3.17</version>
    </dependency>
    

    二、Controller接口

    package com.huang.controller;
    
    import com.huang.mapper.UsersMapper;
    import com.huang.util.excelExport.ExcelExport2;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import javax.annotation.Resource;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * @Author:huang
     * @Date:2019-09-21 13:13
     * @Description:<描述>
     */
    @Controller
    public class TestController {
    
        @Resource
        private UsersMapper usersMapper;
    
        @RequestMapping("/test")
        public void testExprotExcel(HttpServletResponse response){
    
            //创建一个数组用于设置表头
            String[] arr = new String[]{"ID","用户名","账号","密码","备注"};
    
            //调用Excel导出工具类
            ExcelExport2.export(response,usersMapper.selectAll(),arr);
    
        }
    
    }
    
    

    三、工具类

    3.1文件导出excel工具类

    大体思路是传入一个需要导出的数据集合,获取该对象类,然后遍历集合,使用下面的类操作工具类,通过反射获取对象类的属性的get方法,然后将数据对象的值取出来放到excel里

    package com.huang.util.excelExport;
    
    import org.apache.poi.hssf.usermodel.*;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.CellType;
    import org.apache.poi.ss.usermodel.Row;
    
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.List;
    
    /**
     * @Author:haung
     * @Date:2019-09-21 11:21
     * @Description:Excel导出工具类,依赖于ClassUtil工具类
     */
    public final class ExcelExport2 {
    
        /**
         * 将传入的数据导出excel表并下载
         * @param response 返回的HttpServletResponse
         * @param importlist 要导出的对象的集合
         * @param attributeNames 含有每个对象属性在excel表中对应的标题字符串的数组(请按对象中属性排序调整字符串在数组中的位置)
         */
        public static void export(HttpServletResponse response, List<?> importlist, String[] attributeNames) {
            //获取数据集
            List<?> datalist = importlist;
    
            //声明一个工作薄
            HSSFWorkbook workbook = new HSSFWorkbook();
            //生成一个表格
            HSSFSheet sheet = workbook.createSheet();
            //设置表格默认列宽度为15个字节
            sheet.setDefaultColumnWidth((short) 18);
    
            //获取字段名数组
            String[] tableAttributeName = attributeNames;
            //获取对象属性
            Field[] fields = ClassUtil.getClassAttribute(importlist.get(0));
            //获取对象get方法
            List<Method> methodList = ClassUtil.getMethodGet(importlist.get(0));
    
            //循环字段名数组,创建标题行
            Row row = sheet.createRow(0);
            for (int j = 0; j< tableAttributeName.length; j++){
                //创建列
                Cell cell = row.createCell(j);
                //设置单元类型为String
                cell.setCellType(CellType.STRING);
                cell.setCellValue(transCellType(tableAttributeName[j]));
            }
            //创建普通行
            for (int i = 0;i<datalist.size();i++){
                //因为第一行已经用于创建标题行,故从第二行开始创建
                row = sheet.createRow(i+1);
                //如果是第一行就让其为标题行
                Object targetObj = datalist.get(i);
                for (int j = 0;j<fields.length;j++){
                    //创建列
                    Cell cell = row.createCell(j);
                    cell.setCellType(CellType.STRING);
                    //
                    try {
                        Object value = methodList.get(j).invoke(targetObj, new Object[]{});
                        cell.setCellValue(transCellType(value));
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }
            response.setContentType("application/octet-stream");
            //默认Excel名称
            response.setHeader("Content-Disposition", "attachment;fileName="+"test.xls");
    
            try {
                response.flushBuffer();
                workbook.write(response.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
        private static String transCellType(Object value){
            String str = null;
            if (value instanceof Date){
                Date date = (Date) value;
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                str = sdf.format(date);
            }else{
                str = String.valueOf(value);
                if (str == "null"){
                    str = "";
                }
            }
    
            return str;
        }
    
    }
    
    

    3.2类操作工具类

    该工具类用于Excel导出工具类里的属性操作

    package com.huang.util.excelExport;
    
    import org.springframework.stereotype.Component;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @Author:huang
     * @Date:2019-09-21 13:41
     * @Description:关于类的操作的工具类
     */
    public final class ClassUtil {
    
        private ClassUtil() {
            throw new Error("工具类不允许实例化!");
        }
    
        /**
         * 获取类属性
         * @param targetObj 要获取属性的类
         * @return 含有类属性的集合
         */
        public static Field[] getClassAttribute(Object targetObj){
    
            Class<?> objectClass = targetObj.getClass();
            return objectClass.getDeclaredFields();
    
        }
    
        /**
         * 获取对象的所有get或set方法
         * @param targetObj 要获取属性的类
         * @param methodKeyword get或者set关键字
         * @return 含有类get或set方法的集合
         */
        public static List<Method> getMethod(Object targetObj,String methodKeyword){
            List<Method> methodList = new ArrayList<>();
    
            Class<?> objectClass = targetObj.getClass();
    
            Field[] field = objectClass.getDeclaredFields();
            for (int i = 0;i<field.length;i++){
                //获取属性名并组装方法名
                String fieldName = field[i].getName();
                String getMethodName = methodKeyword
                    + fieldName.substring(0, 1).toUpperCase()
                    + fieldName.substring(1);
    
                try {
                    Method method = objectClass.getMethod(getMethodName,new Class[]{});
                    methodList.add(method);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
            }
            return methodList;
        }
    
        /**
         * 获取对象的所有get方法
         * @param targetObj 要获取属性的类
         * @return 含有类方法的集合
         */
        public static List<Method> getMethodGet(Object targetObj){
            return getMethod(targetObj,"get");
        }
    
        /**
         * 获取对象的所有set方法
         * @param targetObj 要获取属性的类
         * @return 含有类方法的集合
         */
        public static List<Method> getMethodSet(Object targetObj){
            return getMethod(targetObj,"set");
        }
    }
    
    

    四、后续补充的话

    这篇文章是做项目的时候第一次遇到导出Excel需求的时候写的,当时头铁硬生生自己造了个轮子出来,上述代码可以用,但是仍然存在表头设置麻烦,内存占用高,而且导出数据可控性低的问题。
    实际上,针对这个需求:如果是需要导出大量数据而没有排版要求的话,可以用EasyExcel,顺带还能把Excel导入给解决了;如果是需要按照复杂模板导出的话,可以使用jxls,或者大佬进一步封装的jxlss。
    这些都是实用而且成熟的框架,如果是有确实的业务用途而不是参考学习的话,建议直接使用这些框架......

  • 相关阅读:
    西门子1200/1500 PLC FC/FB块的区别
    Monaco Editor --Web编辑器 自定义主题、代码提示等
    C# 强制GC垃圾回收
    C# 注册表操作类(查询、修改、删除)
    WinForm重绘Combobox控件无边框样式
    Http-server搭建本地服务
    C# 压缩解压文件夹
    递归获取当前节点和所有父节点
    递归获取当前父节点下的所有子集
    轻量级的通信引擎 StriveEngine
  • 原文地址:https://www.cnblogs.com/Createsequence/p/11563460.html
Copyright © 2020-2023  润新知