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

这篇具有很好参考价值的文章主要介绍了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);
    }
}

我们看看打印效果:
SpringBoot + Ant Design Vue实现数据导出功能文章来源地址https://www.toymoban.com/news/detail-495614.html

到了这里,关于SpringBoot + Ant Design Vue实现数据导出功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ant design pro集成阿里低代码引擎lowcode-engine,并实现与数据库结合实现低代码模块的创建、设计、发布等功能

    阿里低代码引擎是一款为低代码平台开发者提供的,具备强大定制扩展能力的低代码设计器研发框架。 本文主要介绍如何在ant design pro项目中集成阿里低代码引擎lowcode-engine。 根据官方文档,已有项目要集成低代码引擎,至少需要三步,以下我们以ant desigin pro5项目为例,来集

    2024年02月22日
    浏览(52)
  • SpringBoot+Vue 实现图片验证码功能需求

    文章底部有个人公众号: 热爱技术的小郑 。主要分享开发知识、有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 写过验证码保存到Redis中的需求开发、也写过验证码调用第三方接口直接发送到手机的需求开

    2024年02月14日
    浏览(35)
  • 前端实现真实可动态变化进度条,axios+ Ant Design Vue实现.

    最近有一个新需求,要求在前端实现真实的进度条展示,我首先想到了  Ant Design Vue的upload组件, 在antd官网里upload组件不仅有上传功能,并且还附带了 Progress 进度条组件, 还拥有上传成功和失败的两种状态的区分,可以说是十分贴心了,如图  但是很可惜这个组件上传文件的话,你要

    2024年02月09日
    浏览(32)
  • Ant Design Vue Table 嵌套子表格的数据刷新方法

    父子组件各自负责,在table中嵌套了子表格后,首次加载表格时,父组件会实例化子组件并传递参数,折叠后再次展开时,只会传递参数,子组件的数据刷新就属于子表格了。如 @@@code template #expandedRowRender=\\\"{ record }\\\" originIndex style= \\\"margin-left: 55px; margin-right: 50px; background-color:

    2024年02月09日
    浏览(35)
  • Ant Design Vue实现表格双击编辑、添加新行、文字提示

    早上刚上班,产品就朝我工位走了过来,一看大事不好,肯定又是来提需求的! 产品:做一个表格,要实现双击编辑的功能 我:做不了 产品:老板提的 我:好的,可以做 老板提的不能做也滴做😂 申明:项目基于Vue+Ant Design实现 想要实现双击编辑单元格,先开发一个简单的

    2024年02月11日
    浏览(47)
  • vue3 + Ant Design 实现双表头表格(横向表头+纵向表头)

     一、要实现的效果( 纵向固定表头的表格,横向表头数量动态化 ) 二、这是后台返回的数据格式(以企业为数组,每个企业里有个站点数组pointFactors)   三、代码实现步骤   (1)定义纵向固定表头 (2)动态生成横向表头( 从接口获取数据 )   (3)循环原始数据,生

    2024年02月04日
    浏览(50)
  • Ant-Design-Pro-V5: ProTable前端导出excel表格。

    Prtable表格中根据搜索条件实现excel表格导出。 代码展示: index.jsx 数据字典格式返回: 以 teacherTypeObj 为例 向services.js中 lecturerExportExcel 方法中传入的格式为: services.js中 lecturerExportExcel 导出方法: utils 中 paramsFilter 方法:过滤无用参数

    2024年02月09日
    浏览(44)
  • 【ant-design-vue】实现table的拖拽排序(拖拽行和伸缩列):

    1.效果: 拖拽前: 拖拽后: 2.实现: 3.出现的问题: 4.初始拖拽版本: 5.相关知识:

    2024年02月12日
    浏览(40)
  • vue3+ant design vue+ts实战【ant-design-vue组件库引入】

    🔥🔥更多内容见Ant Design Vue官方文档 🔥点击复习vue3【watch检测/监听】相关内容 👏👏👏一个好项目的编写不仅需要完美的逻辑,以及相应的技术,同时也需要一个 设计规范的高质量UI组件库 。👏👏👏本期文章将会详细讲解 Ant Design of Vue 组件库的 安装、使用、引入 。

    2024年02月02日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包