Java导出图片到excel

news2024/11/26 2:38:18

1、例如你有这样一个集合,具体结合你的业务场景
 

@Data
public class Student {
    /**
     * 姓名
     */
    private String xh;
    /**
     * 学号
     */
    private String xm;
    /**
     * 照片
     */
    private byte[] zp;
}

2、相关代码

    @RequestMapping(value = "/quereImgByPkid/{pkid}",method = RequestMethod.GET)
    public  void  test(@PathVariable("pkid") String pkid, HttpServletResponse response){
        try {
            // 业务代码
            List<Student> students = xscnsService.queryImgByPkidAndType(pkid);
            // 设置响应头
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=students.xlsx");

            try (OutputStream outputStream = response.getOutputStream();
                 Workbook workbook = new XSSFWorkbook()) {

                Sheet sheet = workbook.createSheet("Student Data");

                // 创建表头
                Row header = sheet.createRow(0);
                header.createCell(0).setCellValue("学号");
                header.createCell(1).setCellValue("姓名");
                header.createCell(2).setCellValue("照片");

                int rowIndex = 1;
                for (Student student : students) {
                    Row row = sheet.createRow(rowIndex++);

                    // 设置行高(行高设置为100点)
                    row.setHeightInPoints(100);

                    row.createCell(0).setCellValue(student.getXh());
                    row.createCell(1).setCellValue(student.getXm());

                    // 插入照片
                    int pictureIdx = workbook.addPicture(student.getZp(), Workbook.PICTURE_TYPE_JPEG);
                    CreationHelper helper = workbook.getCreationHelper();
                    Drawing<?> drawing = sheet.createDrawingPatriarch();
                    ClientAnchor anchor = helper.createClientAnchor();
                    anchor.setCol1(2); // 照片列
                    anchor.setRow1(rowIndex - 1); // 当前行

                    // 将图片大小调整为单元格大小
                    anchor.setCol2(3); // 结束列
                    anchor.setRow2(rowIndex); // 结束行
                    Picture pict = drawing.createPicture(anchor, pictureIdx);
                    // 不调用resize,让图片完全适应单元格
                }

                // 将数据写入到响应输出流中
                workbook.write(outputStream);
                outputStream.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

3、访问接口得以下载,如下

4、拓展(实战代码)

    @GetMapping("/exportFjPf")
    public void exportFjPf(@RequestParam String uuid, HttpServletResponse response) {
        wsjcService.exportFjPf(uuid,response);
    }
    @Override
    public void exportFjPf(String uuid, HttpServletResponse response) {
        //1、获取缓存的数据
        Object obj = NHRedisUtils.getRedisResult(uuid);
        if (obj == null) {
            throw new NHWarmingException("导出Excel失败,请稍后再试");
        }
        Map<String, Object> map = (Map<String, Object>) obj;
        List<Map<String, Object>> list = (List<Map<String, Object>>) map.get("list");
        // 文件名字,防止乱码
        String fileName = "房间评分信息.xlsx";

        // 针对不同的浏览器进行文件名编码
        String encodedFileName = null;
        try {
            encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }

        response.setContentType("application/octet-stream");

        // 对于不同的浏览器设置不同的 Content-Disposition 头
        String headerValue = String.format("attachment; filename=\"%s\"; filename*=UTF-8''%s", encodedFileName, encodedFileName);
        response.setHeader("Content-Disposition", headerValue);

        try (OutputStream outputStream = response.getOutputStream(); Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("房间评分信息");
            // 设置统一的列宽(比如统一设置为20个字符宽度)
            int columnWidth = 20 * 256;
            // 创建一个单元格样式,设置居中对齐
            CellStyle cellStyle = workbook.createCellStyle();
            // 水平居中
            cellStyle.setAlignment(HorizontalAlignment.CENTER); 
            // 垂直居中
            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            // 创建一个标题单元格样式,设置居中对齐和加粗字体
            CellStyle headerStyle = workbook.createCellStyle();
            headerStyle.setAlignment(HorizontalAlignment.CENTER);
            headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);

            // 设置字体加粗
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerStyle.setFont(headerFont);
            // 创建表头字段
            String[] headers = {"序号", "校区", "楼栋","楼层","房间","学院","专业","班级","所属年级","所属辅导员","评分","评分等级","评分人","评分时间","评语","上传图片"};
            // 对应的字段
            String[] column = {"ROW_ID", "XQMC", "LDMC","LCMC","FJ","BMMC","ZYMC","BJMC","SSNJ","FDY","PF","PFDJMC","PFR","PFSJ","PY"};
            // 创建表头
            Row headerRow = sheet.createRow(0);
            for (int i = 0; i < headers.length; i++) {
                headerRow.setHeightInPoints(30);
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
                // 设置每一列的宽度
                sheet.setColumnWidth(i, columnWidth);
            }

            int rowIndex = 1;
            for (Map<String,Object> item : list) {
                Row row = sheet.createRow(rowIndex++);
                for (int i = 0; i < column.length; i++) {
                    // 设置行高 100点
                    row.setHeightInPoints(100);
                    Cell cell = row.createCell(i);
                    cell.setCellValue(getStrByObject(item.get(column[i])));
                    cell.setCellStyle(cellStyle);
                }
                List<byte []> pictureList =  getPicture(item.get("SCTP"));
                for (int i = 0; i < pictureList.size(); i++) {
                    sheet.setColumnWidth(column.length + i,columnWidth);
                    // 插入照片
                    int pictureIdx = workbook.addPicture(pictureList.get(i), Workbook.PICTURE_TYPE_JPEG);
                    CreationHelper helper = workbook.getCreationHelper();
                    Drawing<?> drawing = sheet.createDrawingPatriarch();
                    ClientAnchor anchor = helper.createClientAnchor();
                    anchor.setCol1(column.length + i); // 照片列
                    anchor.setRow1(rowIndex - 1); // 当前行

                    // 将图片大小调整为单元格大小
                    anchor.setCol2(column.length + i + 1); // 结束列
                    anchor.setRow2(rowIndex); // 结束行
                    Picture pict = drawing.createPicture(anchor, pictureIdx);
                    //不调用resize,让图片完全适应单元格
                }
            }

            // 将数据写入到响应输出流中
            workbook.write(outputStream);
            outputStream.flush();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    private List<byte[]> getPicture(Object sctp) {
        List<byte[]> bytes = new ArrayList<>();
        String strByObject = getStrByObject(sctp);
        if(strByObject == null){
            return bytes;
        }
        // 开始远程调用
        Object fjDetail = dynamicServiceFeignClient.getDetailed(strByObject);
        // 调用日志
        logger.warn("附件主表req:{},rep:{}", strByObject, fjDetail);
        List<Map<String, Object>> maps = new ArrayList<>();
        if (fjDetail != null) {
            Map map = (Map) fjDetail;
            Object data = map.get("data");
            maps = (List<Map<String, Object>>) data;
        }
        List<String> uuids = maps.stream().map(a -> (String) a.get("uuid")).collect(Collectors.toList());
        for (int i = 0; i < uuids.size(); i++) {
            // 开始调用详细附件明细
            Response fileMessage = docrepoServiceFeignClient.getFileInfo(uuids.get(i), "admin", "admin");
            // 打印日志
            logger.warn("根据uuid拿到资源req:{},resp:{}", uuids.get(i), fileMessage);
            if (fileMessage == null || fileMessage.status() != 200) {
                continue;
            }
            // 拿到文件流
            try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()){
                InputStream imageStream = fileMessage.body().asInputStream();
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = imageStream.read(buffer)) != -1) {
                    byteArrayOutputStream.write(buffer, 0, bytesRead);
                }
                byte[] imageBytes = byteArrayOutputStream.toByteArray();
                bytes.add(imageBytes);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return bytes;
    }

    private String getStrByObject(Object str){
        if(str != null){
            return str.toString();
        }
        return null;
    }

结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2100573.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据分享】地级市-国际互联网用户数(2001-2019年)

数据介绍 在当今数字化时代&#xff0c;互联网已经成为人们生活中不可或缺的一部分。今天&#xff0c;我们为大家带来一份极具价值的数据资源 —— 地级市 - 国际互联网用户数&#xff08;2001 - 2019 年&#xff09;。 这份涵盖了近二十年的数据&#xff0c;清晰地展现了各地…

Google上架:PAD的三种分发模式之install-time分发(减小包体上架,适用于包体大于150MB,小于1.15GB的包体)

近期技术服务在升级,抽空写一下关于上架部分的难点,今天来讲一下关于包体过大解决办法中的PAD分发(install-time分发)模式,希望能给好兄弟们带来帮助。 注意!!!这个方法适用于包体大于150MB,小于1.7GB这个区间的包体,不在这个区间的小伙伴可以跳过这个文章,直接私聊…

华为 HCIP-Datacom H12-821 题库 (6)

有需要题库的可以看主页置顶 V群仅进行学习交流 1.转发表中 FLAG 字段中B 的含义是&#xff1f; A、可用路由 B、静态路由 C、黑洞路由 D、网关路由 答案&#xff1a;C 解析&#xff1a; 可用路由用U 表示&#xff0c;静态路由用 S 表示&#xff0c;黑洞路由用 B 表示&#x…

交叉编译 mpfr

文章目录 交叉编译 mpfr1 概述2 源码下载3 交叉编译 交叉编译 mpfr 1 概述 MPFR&#xff08;Multiple Precision Floating-Point Reliable&#xff09;是一个用于高精度浮点数计算的开源库&#xff0c;它提供了高精度的浮点数运算和函数库&#xff0c;适用于需要处理大数或高精…

有哪些开学必备好物推荐?2024年盘点推荐五款高性价比数码好物!

新的学期&#xff0c;新的开始。在 2024 年开学季&#xff0c;为了让同学们更好地投入学习和生活&#xff0c;拥有更便捷、高效的体验&#xff0c;我精心测评盘点并推荐五款高性价比数码好物。这些数码好物不仅能满足学习需求&#xff0c;还能为课余生活增添乐趣&#xff0c;是…

35~750kV 变电站无人值守与集中监控的智能运维模式

1、引言 电力行业的快速发展和电网规模的持续扩张&#xff0c;使得传统的变电站运维模式日渐不能满足现代电网对于安全性、可靠性和效率的更高要求。因此&#xff0c;向无人值守与集中监控过渡&#xff0c;已经逐渐成为了整个行业发展的主旋律。 2、关键技术支撑 2.1 自动化监…

CAE小白入门:HyperMesh的使用和帮助

1.1.3 启动 HyperMesh (1) On PC • 从起始菜单&#xff0c;选择 All Programs >Altair HyperWorks (version) > HyperMesh Desktop。 • 右击上述程序创建软件启动快捷方式&#xff0c;点击快捷方式。 (2) On UNIX • 在命令窗口点击 <install directory>/sc…

提升RAG检索回答质量: Shortwave的 4 大优化指南

这篇文章就针对 RAG 检索这个问题提供一些思路, 以 Shortwave 这家 AI 邮件助手公司的设计思路作为案例,真的很难有公司把产品详细技术机制公布出来 本文在01 部分还针对"微调和 RAG,到底选哪个? " , " 有了支持超长上下文窗口的 LLM,是否还需要 RAG"进行…

城市数字化转型中的机遇:中小型企业产品选型指南

随着城市数字化转型的浪潮席卷全球&#xff0c;中小型企业正面临着前所未有的机遇与挑战。如何精准选型&#xff0c;以最小的成本实现最大的效益&#xff0c;成为众多中小型企业关注的焦点。作为一款低代码开发平台&#xff0c;百数为中小型企业提供了一个高效、便捷、低成本的…

Aigtek功率放大器的参数是什么意思

功率放大器是电子电路中的一种重要组件&#xff0c;用于增加输入信号的幅度&#xff0c;以便驱动负载&#xff0c;如扬声器或天线。在设计和使用功率放大器时&#xff0c;有许多关键参数需要考虑&#xff0c;这些参数影响着功率放大器的性能和适用性。下面将详细介绍功率放大器…

视频合并怎么操作?这篇文章告诉你

当你手头有多个片段&#xff0c;想要将它们巧妙地拼接在一起&#xff0c;形成一个完整的故事时&#xff0c;你会怎么做呢&#xff1f; 手动逐帧调整&#xff1f;这显然是个耗时且复杂的过程。幸好&#xff0c;现在有许多优秀的视频合并模板软件可以帮助你轻松实现这一目标。 …

Power Automate向Power Apps传Table数据

Flow返回查询的数据表并返回Apps 场景介绍代码开发Power Automate开发数据库Power Automate调用存储过程 Power Apps开发代码开发 测试 场景介绍 我们通常会使用Flow 查询数据表然后Apps端将表中的数据显示出来&#xff0c;我们怎么来传呢&#xff0c;它自带的response for Po…

Arduino library for proteus 下载 安装 测试

Arduino library include: https://drive.google.com/uc?exportdownload&id1P4VtXaomJ4lwcGJOZwR_25oeon9Zzvwb 第一步&#xff1a; 也可从我的共享网盘当中下载&#xff1a; 第2步&#xff1a;解压文件&#xff1a; 第3步&#xff1a; copy lib and idx 到对应的…

Qt多媒体播放软件

1、项目背景 1.1、技术背景 随着数字媒体的普及&#xff0c;用户对于多媒体播放软件的需求日益增长。Qt作为一个功能强大且跨平台的应用程序开发框架&#xff0c;提供了一套完整的工具和库来支持多媒体内容的处理。Qt Multimedia模块特别为音频和视频播放、录制以及其他相关任…

B树和B+树总结

B树&#xff08;B-Tree&#xff09;和B树&#xff08;B Tree&#xff09;是两种广泛应用于数据库和文件系统中的自平衡树结构&#xff0c;主要用于存储和检索大量有序数据。它们都是多叉树&#xff0c;即每个节点可以有多个子节点&#xff0c;与二叉树不同。下面是对这两种树的…

每日刷题(图论)

P1119 灾后重建 P1119 灾后重建 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 思路 看数据范围知道需要用到Floyd算法&#xff0c;但是道路是不能直接用的&#xff0c;需要等到连接道路的两个村庄重建好才可以使用&#xff0c;所以这需要按照时间依次加入中转点&#xff0c…

并行数模转换器分辨率的扩展

在并行DAC中存在的一个普遍问题是随着DAC分辨率的提高需要的面积也越来越大。此外&#xff0c;MSB元件值与LSB元件值之比也在增大。我们知道元件的匹配精度随着元件和元件的比值的增大而降低&#xff0c;因此&#xff0c;本节将分析几种能够在元件比和分辨率之间进行权衡的方法…

基于LSTM-AutoEncoder的室内空气质量时间序列数据异常检测

基于LSTM-AutoEncoder的室内空气质量时间序列数据异常检测 LSTM-Autoencoder-Based Anomaly Detection for Indoor Air Quality Time-Series Data DOI: 10.1109/JSEN.2022.3230361 摘要——室内空气质量&#xff08;IAQ&#xff09;数据的异常检测已成为研究的重要领域&…

【SQL】跳过记录筛选第二名

目录 语法 需求 示例 分析 代码 语法 SELECT DISTINCT column1, column2, ... SELECT DISTINCT 语句用于返回唯一不同的值。SELECT DISTINCT 后面跟着想要获取唯一值的列名&#xff0c;列名之间用逗号分隔。当从数据库表中查询数据时&#xff0c;如果表中某列包含重复的…

星坤DDR5 SMT RDIMM金手指连接器:云端存储与高性能计算的未来

在当今数字化时代&#xff0c;数据的快速增长和处理需求对电子元器件提出了更高的要求。星坤电子以其创新的DDR5 SMT RDIMM【X9413 X9414 series】金手指连接器&#xff0c;为云端存储设备、伺服器、电源供应设备、通讯设备、工控主机以及3C电子产品等领域提供了卓越的连接解决…