首页 > 其他分享 >SpringBoot + Ant Design Vue实现数据导出功能

SpringBoot + Ant Design Vue实现数据导出功能

时间:2023-06-25 20:31:35浏览次数:45  
标签:Vue SpringBoot excel private alibaba Ant new import com

(SpringBoot + Ant Design Vue实现数据导出功能)

一、需求

  • 以xlsx格式导出所选表格中的内容
  • 要求进行分级
  • 设置表头颜色。

二、前端代码实现

2.1 显示实现

首先我们需要添加一个用于到导出的按钮上去,像这样的:

<a-button @click="exportBatchlistVerify">批量导出</a-button>

至于它放哪里,是什么样式可以根据自己的需求决定。

2.2 代码逻辑

按钮有了,下来我们开始实现这个按钮的功能。

  1. 导出数据确定。

表格设置: 表头添加以下代码

<s-table	
	:row-key="(record) => record.id"
	:row-selection="options.rowSelection"
	>

Vue代码 :获取选中的目标ID数组

   import listApi from '@/api/listApi'
	let selectedRowKeys = ref([])
	const options = {
		alert: {
			show: false,
			clear: () => {
				selectedRowKeys = ref([])
			}
		},
		rowSelection: {
			onChange: (selectedRowKey, selectedRows) => {
				selectedRowKeys.value = selectedRowKey
			},
			//这里是设置复选框的宽度,可以删掉
			columnWidth : 6
		}
	}

按钮功能实现:

	const exportBatchlistVerify = () => {
		if (selectedRowKeys.value.length < 1) {
			message.warning('请输入查询条件或勾选要导出的信息')
		}
		if (selectedRowKeys.value.length > 0) {
			const params = {
				checklistIds: selectedRowKeys.value
					.map((m) => {
						return m
					})
					.join()
			}
			exportBatchChecklist(params)
			return
		}
		exportBatchList(params)

	}
	const exportBatchList= (params) => {
		listApi.listExport(params).then((res) => {
			downloadUtil.resultDownload(res)
			table.value.clearSelected()
		})
	}

listApi: 导入部分和 baseRequest 请参考 Vue封装axios实现

import { baseRequest } from '@/utils/request'
const request = (url, ...arg) => baseRequest(`/list/` + url, ...arg)
	listExport(data) {
		return request('export', data, 'get', {
			responseType: 'blob'
		})
	},

三、后端代码实现

3.1 实体类

我们首先建一个简单的实体,展示将要导出的数据内容:

import com.baomidou.mybatisplus.annotation.TableName;
import com.fhs.core.trans.vo.TransPojo;
import lombok.Data;

/**
 * Auth lhd
 * Date 2023/6/21 9:42
 * Annotate 导出功能测试类
 */
@Data
@TableName("userTest")
public class UserTest implements TransPojo {

    private String id;
    private String name;
    private String tel;
    private String password;
    private String address;
}

3.2 接收参数和打印模板

有了实体类后,我们将开始进行具体的逻辑编写,但在这之前我们需要定义接收前端传参的类,和定义我们的打印模板。

接收参数:

import lombok.Data;

/**
 * Auth lhd
 * Date 2023/6/21 9:46
 * Annotate
 */
@Data
public class UserTestExportParam {
    private String listIds;
}

这部分很简单,我们只需要即将打印的内容ID即可。

打印模板:

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.HeadStyle;
import com.alibaba.excel.enums.poi.FillPatternTypeEnum;
import lombok.Data;

/**
 * Auth lhd
 * Date 2023/6/21 10:10
 * Annotate
 */
@Data
public class UserTestResult {

    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 40)
    @ExcelProperty({"人物名称"})
    private String name;

    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 29)
    @ExcelProperty({"基本信息","联系方式 "})
    private String tel;

    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 31)
    @ExcelProperty({"基本信息","地址 "})
    private String address;

    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 26)
    @ExcelProperty({"基本信息","不能外露","账号密码 "})
    private String password;

}

打印模板定义了我们们即将打印的表格的表头结构和列名、表头颜色。

备注:通过修改打印模板类的注解,可以实现自定义的表头和表头颜色

3.3 正式的逻辑

映射接口和XML:

  • 接口 UserTestMapper
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.modular.userTest.entity.UserTest;

/**
 * Auth lhd
 * Date 2023/6/21 10:02
 * Annotate
 */
public interface UserTestMapper extends BaseMapper<UserTest> {
}

  • XML UserTestMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.modular.userTest.mapper.UserTestMapper">

</ma

核心逻辑接口和实现:

  • 逻辑接口 UserTestService
import com.baomidou.mybatisplus.extension.service.IService;
import com.modular.userTest.entity.UserTest;
import com.modular.userTest.param.UserTestExportParam;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Auth lhd
 * Date 2023/6/21 9:44
 * Annotate
 */
public interface UserTestService extends IService<UserTest> {
    void exportUserTestList(UserTestExportParam listExportParam, HttpServletResponse response) throws IOException;
}

  • 接口实现 UserTestServiceImpl
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.alibaba.excel.write.style.row.AbstractRowHeightStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fhs.trans.service.impl.TransService;
import org.apache.poi.ss.usermodel.*;
import org.springframework.stereotype.Service;
import com.modular.userTest.entity.UserTest;
import com.modular.userTest.mapper.UserTestMapper;
import com.modular.userTest.param.UserTestExportParam;
import com.modular.userTest.result.UserTestResult;
import com.modular.userTest.service.UserTestService;
import com.common.excel.CommonExcelCustomMergeStrategy;
import com.common.exception.CommonException;
import com.common.util.CommonDownloadUtil;
import com.common.util.CommonResponseUtil;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Auth lhd
 * Date 2023/6/21 10:01
 * Annotate
 */
@Service
public class UserTestServiceImpl extends ServiceImpl<UserTestMapper, UserTest> implements UserTestService {

    @Resource
    private TransService transService;
    
    @Override
    public void exportUserTestList(UserTestExportParam listExportParam, HttpServletResponse response) throws IOException {
            File tempFile = null;
            try {
                QueryWrapper<UserTest> queryWrapper = new QueryWrapper<>();
                if(ObjectUtil.isNotEmpty(listExportParam.getListIds())) {
                    queryWrapper.lambda().in(UserTest::getId, StrUtil.split(listExportParam.getListIds(), StrUtil.COMMA));
                }
                String fileName = "人物信息表.xlsx";
                List<UserTest> userlists = this.list(queryWrapper);
                if(ObjectUtil.isEmpty(userlists)) {
                    throw new CommonException("无数据可导出");
                }
                transService.transBatch(userlists);
                List<UserTestResult> listResults = userlists.stream()
                        .map(userlist -> {
                            UserTestResult listExportResult = new UserTestResult();
                            BeanUtil.copyProperties(userlist, listExportResult);
                            listExportResult.setName(ObjectUtil.isNotEmpty(listExportResult.getName())?
                                    listExportResult.getName():"无检查地址");
                            return listExportResult;
                        }).collect(Collectors.toList());

                // 创建临时文件
                tempFile = FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);

                // 头的策略
                WriteCellStyle headWriteCellStyle = new WriteCellStyle();
                WriteFont headWriteFont = new WriteFont();
                headWriteFont.setFontHeightInPoints((short) 14);
                headWriteCellStyle.setWriteFont(headWriteFont);

                // 水平垂直居中
                headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
                headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

                // 内容的策略
                WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
                // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
                contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
                // 内容背景白色
                contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
                WriteFont contentWriteFont = new WriteFont();

                // 内容字体大小
                contentWriteFont.setFontHeightInPoints((short) 12);
                contentWriteCellStyle.setWriteFont(contentWriteFont);

                //设置边框样式,细实线
                contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
                contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
                contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
                contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);

                // 水平垂直居中
                contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
                contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

                // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
                HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle,
                        contentWriteCellStyle);

                // 写excel
                EasyExcel.write(tempFile.getPath(), UserTestResult.class)
                        // 自定义样式
                        .registerWriteHandler(horizontalCellStyleStrategy)
                        // 自动列宽
                        .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                        // 机构分组合并单元格
                        .registerWriteHandler(new CommonExcelCustomMergeStrategy(listResults.stream().map(UserTestResult::getName)
                                .collect(Collectors.toList()), 0))
                        // 设置第一行字体
                        .registerWriteHandler(new CellWriteHandler() {
                            @Override
                            public void afterCellDispose(CellWriteHandlerContext context) {
                                WriteCellData<?> cellData = context.getFirstCellData();
                                WriteCellStyle writeCellStyle = cellData.getOrCreateStyle();
                                Integer rowIndex = context.getRowIndex();
                                if(rowIndex == 0) {
                                    WriteFont headWriteFont = new WriteFont();
                                    headWriteFont.setFontName("宋体");
                                    headWriteFont.setBold(true);
                                    headWriteFont.setFontHeightInPoints((short) 16);
                                    writeCellStyle.setWriteFont(headWriteFont);
                                }
                            }
                        })
                        // 设置表头行高
                        .registerWriteHandler(new AbstractRowHeightStyleStrategy() {
                            @Override
                            protected void setHeadColumnHeight(Row row, int relativeRowIndex) {
                                if(relativeRowIndex == 0) {
                                    // 表头第一行
                                    row.setHeightInPoints(34);
                                } else {
                                    // 表头其他行
                                    row.setHeightInPoints(30);
                                }
                            }
                            @Override
                            protected void setContentColumnHeight(Row row, int relativeRowIndex) {
                                // 内容行
                                row.setHeightInPoints(20);
                            }
                        })
                        .sheet("人物信息表信息")
                        .doWrite(listResults);
                CommonDownloadUtil.download(tempFile, response);
            } catch (Exception e) {
                log.error(">>> 人物信息表导出异常:", e);
                CommonResponseUtil.renderError(response, "导出失败");
            } finally {
                FileUtil.del(tempFile);
            }
        }
}

这里只展示具体逻辑,common开头的公共类和工具类感兴趣的伙伴可以私信我获取~

3.4 Contorller

最后写一个简单的controller类即可:

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.modular.userTest.param.UserTestExportParam;
import com.modular.userTest.service.UserTestService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Auth lhd
 * Date 2023/6/21 10:17
 * Annotate
 */
@RestController
public class UserTestController {

    @Resource
    private UserTestService userTestService;

    @GetMapping(value="/list/export",produces=MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public void exportUser(UserTestExportParam listExportParam, HttpServletResponse response) throws IOException {
        userTestService.exportUserTestList(listExportParam, response);
    }
}

我们看看打印效果: 在这里插入图片描述

标签:Vue,SpringBoot,excel,private,alibaba,Ant,new,import,com
From: https://blog.51cto.com/TiMi/6548377

相关文章

  • springboot加切面日志
    packageorg.rest.util;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Target({ElementType.TYPE,ElementType.METHOD})@Retention(RetentionP......
  • 利用SpringBoot和javafx进行桌面开发
    原文合集地址如下,有需要的朋友可以关注本文地址合集地址众所周知,SpringBoot是一款强大的Javaweb开发程序,这得益于其构造了一个Spring容器,然后通过依赖注入和控制反转,维护起一套Java对象和实例的管理机制,方便开发者去使用。在web应用开发的应用中,Springboot在Java层应用非常广,同样的......
  • vue 解决 post请求下载文件,下载的文件损坏打不开,结果乱码
    axios.post('xxx',{responseType:'blob'//指定返回数据的格式为blob}).then(response=>{console.log(response);//把response打出来,看下图leturl=window.URL.createObjectURL(response.data);console.log(url)vara=document.cre......
  • 利用SpringBoot和javafx进行桌面开发
    原文合集地址如下,有需要的朋友可以关注本文地址合集地址众所周知,SpringBoot是一款强大的Javaweb开发程序,这得益于其构造了一个Spring容器,然后通过依赖注入和控制反转,维护起一套Java对象和实例的管理机制,方便开发者去使用。在web应用开发的应用中,Springboot在Java层应用非常广,......
  • Vuex教程
    Vuex使用场景:全局管理数据注意:vue2项目要安装vuex3版本,vue3项目要安装vuex4版本安装npminstallvuex@3--save建立以下目录结构/src /store -store.js创建vuexstorevuex中最关键的是store对象,这是vuex的核心。可以说,vuex这个插件其实就是一个store对象,每个vue......
  • SpringBoot用@Async实现异步调用
    @Async的使用1、在启动类中加上注解@EnableAsync启用异步 2、在使用异步的方法上加上注解@Async,自己写一个线程池,指定线程池。不建议使用默认的线程池。 在线程池应用中,参考阿里巴巴java开发规范:线程池不允许使用Executors去创建,不允许使用系统默认的线程池,推荐通过T......
  • elementplus vue 范围输入框
    <divclass="fv-rowmb-7"><labelclass="fs-6fw-semoboldmb-2">{{t("Numberofgroups")}}</label><el-form-itemprop="formInline.group"><el-inputcl......
  • Vue中的Ajax请求和Slot插槽的技术探究
    Ajax请求Ajax是一种异步的Web开发技术,用于在不刷新整个页面的情况下向服务器发送请求和接收响应。Vue提供了一种简单而强大的方法来处理Ajax请求。以下是在Vue中进行Ajax请求的基本步骤:安装Axios:Axios是一个流行的JavaScript库,用于进行Ajax请求。你可以使用npm或yarn等包管理......
  • springboot~stateless4j实现状态机
    状态机,包括了状态和动作,某个状态下,只能执行某些动作,如果动作不匹配,状态是不会进行变更了,这样就保护了我们状态字段的准备性,不能随意改变,必须按着我们设计的规则进行状态的轮转。Stateless实现的状态机Stateless:Stateless是一个简单且易于使用的状态机库,它提供了基本的状态转换......
  • vue-step2
    目录结构目录解析build:项目构建(webpack)相关代码config:配置目录,包括端口号等node_modules:npm加载的项目依赖模块src:assets:放置一些图片,如logocomponents:目录里面放一些组件文件,可以不用App.vue项目入口文件main.js项目的核心文件sta......