Springboot导出Excel并下载[通俗易懂]

Springboot导出Excel并下载[通俗易懂]一、引入相关依赖<!–数据导出excel–><!–https://mvnrepository.com/artifact/org.apache.poi/poi–>

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一、引入相关依赖

<!--数据导出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。
这些都是实用而且成熟的框架,如果是有确实的业务用途而不是参考学习的话,建议直接使用这些框架……

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/170832.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Android银弧刀之ProgressBar之最炫民族风「建议收藏」

    Android银弧刀之ProgressBar之最炫民族风「建议收藏」传送门 ☞ Android兵器谱 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229银弧刀     陆无双抬起头来,只见四名乞丐,一字排在门外,或高或矮,一齐望着自己。她曾用银弧刀伤了一个乞丐,一见这四人来意不善,心中暗暗吃惊。。。杨过听了她声音,也是大吃一惊,只听另一个女人声音道:“那叫化子背上的,明明是师妹的银弧刀,就可惜没能起

    2022年9月16日
    2
  • navicat15永久激活码最新【2021免费激活】[通俗易懂]

    (navicat15永久激活码最新)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年3月30日
    487
  • 《老友记》典故集解 Season 1-10

    《老友记》典故集解 Season 1-10第一季第一集Mr.PotatoHead瑞秋和众人谈到了她逃婚的原因,她说这是因为她突然发现她的未婚夫巴里医生长得活像“薯头先生(Mr.PotatoHead)”,这是在美国家喻户晓的卡通人物。如果大家看过《玩具总动员(ToyStory)》,就会在里面发现他和他的夫人“薯头太太(Mrs.PotatoHead)”叽叽歪歪,经常批评这、批评那的形象。尽管“薯头先生”很…

    2022年7月11日
    17
  • 定时任务时间设置[通俗易懂]

    每天凌晨2点002**?和每天隔一小时0**/1**?例1:每隔5秒执行一次:*/5****?例2:每隔5分执行一次:0*/5***?在26分、29分、33分执行一次:026,29,33***?例3:每天半夜12点30分执行一次:0300**?(注意日期域为0不是24)每天凌晨1点执行一次:001**?…

    2022年4月15日
    48
  • c++ CreateThread

    c++ CreateThread1.基本使用方式1.1DWORDWINAPI函数名(LPVOIDlpParam);//标准格式DWORDWINAPI函数名(LPVOIDlpParam){return0;}CreateThread(NULL,0,函数名,0,0,0);1.2使用void函数名()此种线程声明方式时,lpStartAddress需要加入LPTHREAD_START_ROUTINE转换void函数名(){return;}CreateThre

    2022年7月21日
    12
  • Laravel find in set排序

    Laravel find in set排序

    2021年11月9日
    53

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号