You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将ModelAndView对象转换为byte[]数组,提取Excel作为邮件附件

解决方案

你自定义的ExcelGenerator本质是Spring的View接口实现类,Excel生成逻辑全部封装在视图渲染方法中,ModelAndView仅存储视图实例和数据模型,本身不持有渲染后的文件字节流,所以不需要从ModelAndView中提取数据,直接复用ExcelGenerator的生成逻辑即可拿到字节数组,有两种可选实现方案:

方案1:直接模拟视图渲染流程生成字节数组(无需修改原有代码,快速实现)

借助Spring测试包的Mock响应对象模拟Web请求的渲染流程,直接拿到输出的字节数组:

import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;

// 构造和原有接口完全一致的Model参数
Map<String, Object> model = new HashMap<>();
Map<String, List> multipleList = new HashMap<>();
multipleList.put("test1 sheet", DataGenerator.generatePopulatedObjects(ExportClassExample.class, 10));
multipleList.put("test2 sheet", DataGenerator.generatePopulatedObjects(IdExportClassExample.class, 10));
multipleList.put("test3 sheet", DataGenerator.generatePopulatedObjects(ExportClassExample.class, 100));
model.put(ExcelGenerator.MULTIPLE_DATA_LIST, multipleList);

// 模拟渲染流程获取字节数组
MockHttpServletRequest mockRequest = new MockHttpServletRequest();
MockHttpServletResponse mockResponse = new MockHttpServletResponse();
new ExcelGenerator().render(model, mockRequest, mockResponse);
byte[] excelBytes = mockResponse.getContentAsByteArray();

拿到excelBytes后即可直接构造邮件附件,示例如下:

import javax.mail.util.ByteArrayDataSource;
import javax.mail.internet.MimeBodyPart;

// 构造附件
ByteArrayDataSource dataSource = new ByteArrayDataSource(excelBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
MimeBodyPart attachmentPart = new MimeBodyPart();
attachmentPart.setDataHandler(new DataHandler(dataSource));
attachmentPart.setFileName("多列表数据导出.xlsx");

如果不想引入spring-test依赖,可直接使用ByteArrayOutputStream对接ExcelGenerator的写入逻辑,参考方案2。

方案2:抽取公共生成方法(解耦性更强,推荐长期使用)

将ExcelGenerator中Excel生成的核心逻辑抽取为独立公共方法,同时兼容Web请求响应和字节数组生成场景:

  1. 修改ExcelGenerator代码:
public class ExcelGenerator extends AbstractView {
    public static final String MULTIPLE_DATA_LIST = "multipleDataList";

    // 抽取公共Excel生成方法,接收数据模型和输出流
    public void generateExcel(Map<String, Object> model, OutputStream outputStream) throws IOException {
        // 将原有render方法中生成Excel、写入输出流的核心逻辑迁移到此处
    }

    @Override
    protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 原有响应头设置逻辑保留
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-Disposition", "attachment;filename=export.xlsx");
        // 调用公共方法生成Excel
        generateExcel(model, response.getOutputStream());
    }
}
  1. 生成字节数组直接调用公共方法即可:
ByteArrayOutputStream out = new ByteArrayOutputStream();
new ExcelGenerator().generateExcel(model, out);
byte[] excelBytes = out.toByteArray();

内容的提问来源于stack exchange,提问作者Marius Pop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 22:57:04