有关后端使用Springboot导出Excel,前端使用vue实现Excel下载的功能实现

简介: 有关后端使用Springboot导出Excel,前端使用vue实现Excel下载的功能实现

有关后端使用Springboot导出Excel,前端使用vue实现Excel下载的功能实现

接到一个需求 ,是有关Excel导出的功能,用户通过页面的数据,进行批量的导出操作。话不多说,直接上代码:

后端

package com.ly.travelaround.cms.common.utils;
import org.apache.poi.hssf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
 * 导出实体到Excel的工具类
 * @Date 2021/9/2 10:17
 */
public class ExportEntityToExcel {
    private static final Logger logger = LoggerFactory.getLogger(ExportEntityToExcel.class);
    public static <T> void export(String excelName, List<T> list, LinkedHashMap<String, String> fieldMap, HttpServletResponse response, HttpServletRequest request) {
        // 设置默认文件名为当前时间:年月日时分秒
        if (excelName == null || excelName == "") {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
            String defaultName = sdf.format(new Date());
            excelName = defaultName;
        }
        try {
            String fileName = new String(excelName.getBytes("gb2312"), "ISO8859-1") + ".xls";
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/vnd.ms-excel"); // 改成输出excel文件
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "No-cache");
            // 设置response头信息
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        } catch (Exception e1) {
            logger.info(e1.getMessage());
        }
        try {
            //创建一个WorkBook,对应一个Excel文件
            HSSFWorkbook workbook = new HSSFWorkbook();
            //在Workbook中,创建一个sheet,对应Excel中的工作薄(sheet)
            HSSFSheet sheet = workbook.createSheet(excelName);
            //创建单元格,并设置值表头 设置表头居中
            HSSFCellStyle style = workbook.createCellStyle();
            //创建一个居中格式
            style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            // 填充工作表
            fillSheet(sheet, list, fieldMap, style);
            //将文件输出
            OutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            logger.info("导出Excel失败!");
            logger.error(e.getMessage());
        }
    }
    /**
     * 根据字段名获取字段
     */
    public static Field getFieldByName(String fieldName, Class<?> clazz) {
        // 获取所有字段
        Field[] selfFields = clazz.getDeclaredFields();
        // 如果本类中存在该字段,则返回
        for (Field field : selfFields) {
            //如果本类中存在该字段,则返回
            if (field.getName().equals(fieldName)) {
                return field;
            }
        }
        // 否则,查看父类中是否存在此字段,如果有则返回
        Class<?> superClazz = clazz.getSuperclass();
        if (superClazz != null && superClazz != Object.class) {
            //递归
            return getFieldByName(fieldName, superClazz);
        }
        // 如果本类和父类都没有,则返回空
        return null;
    }
    /**
     * 根据字段名获取字段值
     */
    public static Object getFieldValueByName(String fieldName, Object o) throws Exception {
        Object value = null;
        //根据字段名得到字段
        Field field = getFieldByName(fieldName, o.getClass());
        //如果该字段存在,则取出该字段的值
        if (field != null) {
            field.setAccessible(true);//类中的成员变量为private,在类外边使用属性值,故必须进行此操作
            value = field.get(o);//获取当前对象中当前Field的value
        } else {
            throw new Exception(o.getClass().getSimpleName() + "类不存在字段名: " + fieldName);
        }
        return value;
    }
    /**
     * 根据带路径或不带路径的属性名获取属性值,即接受简单属性名,
     * 如userName等,又接受带路径的属性名,如student.department.name等
     */
    public static Object getFieldValueByNameSequence(String fieldNameSequence, Object o) throws Exception {
        Object value = null;
        // 将fieldNameSequence进行拆分
        String[] attributes = fieldNameSequence.split("\\.");
        if (attributes.length == 1) {
            value = getFieldValueByName(fieldNameSequence, o);
        } else {
            // 根据数组中第一个连接属性名获取连接属性对象,如student.department.name
            Object fieldObj = getFieldValueByName(attributes[0], o);
            //截取除第一个属性名之后的路径
            String subFieldNameSequence = fieldNameSequence.substring(fieldNameSequence.indexOf(".") + 1);
            //递归得到最终的属性对象的值
            value = getFieldValueByNameSequence(subFieldNameSequence, fieldObj);
        }
        return value;
    }
    /**
     * 向工作表中填充数据
     */
    public static <T> void fillSheet(HSSFSheet sheet, List<T> list, LinkedHashMap<String, String> fieldMap, HSSFCellStyle style) throws Exception {
        // 定义存放英文字段名和中文字段名的数组
        String[] enFields = new String[fieldMap.size()];
        String[] cnFields = new String[fieldMap.size()];
        // 填充数组
        int count = 0;
        for (Map.Entry<String, String> entry : fieldMap.entrySet()) {
            enFields[count] = entry.getKey();
            cnFields[count] = entry.getValue();
            count++;
        }
        //在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
        HSSFRow row = sheet.createRow((int) 0);
        // 填充表头
        for (int i = 0; i < cnFields.length; i++) {
            HSSFCell cell = row.createCell(i);
            cell.setCellValue(cnFields[i]);
            cell.setCellStyle(style);
            sheet.setColumnWidth(i, 3000);//设置表格宽度
        }
        // 填充内容
        for (int index = 0; index < list.size(); index++) {
            row = sheet.createRow(index + 1);
            // 获取单个对象
            T item = list.get(index);
            for (int i = 0; i < enFields.length; i++) {
                Object objValue = getFieldValueByNameSequence(enFields[i], item);
                String fieldValue = objValue == null ? "" : objValue.toString();
                row.setRowStyle(style);
                row.createCell(i).setCellValue(fieldValue);
            }
        }
    }
}
/**
*对应着导出的Excel实体信息 
*/
//略
/**
*控制层
*/
@RestController("excel")
public class ExcelExportController {
    @PostMapping(value = "downLoadExcel")
    public void downLoadExcel(HttpServletResponse response, HttpServletRequest request, @RequestBody() List<ExcelPo> dataList) {
        if (null == dataList || dataList.size() <= 0) {
            return ;
        }
        response.setCharacterEncoding("utf-8");
        String excelName = "酒店列表";
        LinkedHashMap<String, String> fieldMap = new LinkedHashMap<>();
        fieldMap.put("order", "排序值");
        fieldMap.put("cityId", "城市ID");
        fieldMap.put("hotelId", "商品ID");
        fieldMap.put("hotelName", "商品名称");
        fieldMap.put("start", "星级");
        fieldMap.put("score", "评分");
        fieldMap.put("commentTotal", "点评数量");
        fieldMap.put("price", "价格");
        fieldMap.put("filterName", "商圈名称");
        new ExportEntityToExcel().export(excelName, dataList, fieldMap, response, request);
    }
}

其中后端代码是使用的—参考链接—的代码。

前端

<el-button :disabled="isActive" @click="exportChoosed" type="info"
        >导出数据</el-button>
   exportChoosed() {
      // 利用a标签自定义下载文件名
      const link = document.createElement("a");
      //let choosedList = this.multipleSelection.map((item) => {
        //return item;
      //});
      //这里的choosedList是你需要导出的数据集合 我这里是我的具体使用场景 你需要什么就传什么
      console.log("chooosedList", choosedList);
      //请求后端接口 进行excel的导出
      hotelList
        .exportChoosedToExcel(choosedList)
        .then((res) => {
          let blob = new Blob([res], { type: "application/vnd.ms-excel" }); // res就是接口返回的文件流了
          let objectUrl = URL.createObjectURL(blob);
          debugger;
          link.href = objectUrl;
          link.download = "酒店列表"; // 自定义文件名
          link.click(); // 下载文件
          // window.location.href = objectUrl;
          window.URL.revokeObjectURL(objectUrl); // 释放内存
        })
        .catch((err) => {
          console.log("被catch到了", err);
          return {
            code: 500,
            success: false,
            msg: err,
          };
        });
        }
相关文章
|
10月前
|
Python
Excel中如何批量重命名工作表与将每个工作表导出到单独Excel文件
本文介绍了如何在Excel中使用VBA批量重命名工作表、根据单元格内容修改颜色,以及将工作表导出为独立文件的方法。同时提供了Python实现导出工作表的代码示例,适用于自动化处理Excel文档。
|
数据格式 UED
记录一次NPOI库导出Excel遇到的小问题解决方案
【11月更文挑战第16天】本文记录了使用 NPOI 库导出 Excel 过程中遇到的三个主要问题及其解决方案:单元格数据格式错误、日期格式不正确以及合并单元格边框缺失。通过自定义单元格样式、设置数据格式和手动添加边框,有效解决了这些问题,提升了导出文件的质量和用户体验。
1153 3
|
前端开发 Java easyexcel
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
1100 8
|
前端开发
实现Excel文件和其他文件导出为压缩包,并导入
实现Excel文件和其他文件导出为压缩包,并导入
375 1
|
Java API Apache
|
存储 缓存 负载均衡
后端开发中的性能优化策略
本文将探讨几种常见的后端性能优化策略,包括代码层面的优化、数据库查询优化、缓存机制的应用以及负载均衡的实现。通过这些方法,开发者可以显著提升系统的响应速度和处理能力,从而提供更好的用户体验。
596 6
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
723 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
10月前
|
人工智能 Java API
后端开发必看:零代码实现存量服务改造成MCP服务
本文介绍如何通过 **Nacos** 和 **Higress** 实现存量 Spring Boot 服务的零代码改造,使其支持 MCP 协议,供 AI Agent 调用。全程无需修改业务代码,仅通过配置完成服务注册、协议转换与工具映射,显著降低改造成本,提升服务的可集成性与智能化能力。
2972 1
|
10月前
|
前端开发 Java 数据库连接
后端开发中的错误处理实践:原则与实战
在后端开发中,错误处理是保障系统稳定性的关键。本文介绍了错误分类、响应设计、统一处理机制及日志追踪等实践方法,帮助开发者提升系统的可维护性与排障效率,做到防患于未然。
|
12月前
|
存储 消息中间件 前端开发
PHP后端与uni-app前端协同的校园圈子系统:校园社交场景的跨端开发实践
校园圈子系统校园论坛小程序采用uni-app前端框架,支持多端运行,结合PHP后端(如ThinkPHP/Laravel),实现用户认证、社交关系管理、动态发布与实时聊天功能。前端通过组件化开发和uni.request与后端交互,后端提供RESTful API处理业务逻辑并存储数据于MySQL。同时引入Redis缓存热点数据,RabbitMQ处理异步任务,优化系统性能。核心功能包括JWT身份验证、好友系统、WebSocket实时聊天及活动管理,确保高效稳定的用户体验。
656 4
PHP后端与uni-app前端协同的校园圈子系统:校园社交场景的跨端开发实践

热门文章

最新文章