SpringBoot+Ant Design Vue实现数据导出功能方式
作者:timi先生
这篇文章主要介绍了SpringBoot+Ant Design Vue实现数据导出功能方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
一、需求
- 以xlsx格式导出所选表格中的内容
- 要求进行分级
- 设置表头颜色。
二、前端代码实现
2.1 显示实现
首先我们需要添加一个用于到导出的按钮上去,像这样的:
<a-button @click="exportBatchlistVerify">批量导出</a-button>
至于它放哪里,是什么样式可以根据自己的需求决定。
2.2 代码逻辑
按钮有了,下来我们开始实现这个按钮的功能。
导出数据确定。
表格设置: 表头添加以下代码
<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); } } }
这里只展示具体逻辑
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); } }
我们看看打印效果:
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。