手把手教你Spring WebFlux导出数据到excel中

常用组件:

WorkbookFactory excel的文档对象

Sheet excel的表单

Row excel的行

Cell excel的格子单元

Font excel字体

样式:

CellStyle cell样式

实现步骤:
1.添加maven依赖

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.9</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.9</version>
</dependency>

2.编写Controller
使用spring webflux文件下载就没有之前基于servlet容器的javax.servlet.http.HttpServletResponse了,取而代之的是org.springframework.http.server.reactive.ServerHttpResponse。

   @GetMapping("/caterings/export")
    public Mono<Void> export(ServerHttpResponse response, Search search) throws IOException {
        return cateringManager.export(response, search);
    }

3.编写Manager

 public Mono<Void> export(ServerHttpResponse response, Search search)
            throws IOException {
        //spring webflux文件下载零拷贝(Zero-copy)
        ZeroCopyHttpOutputMessage zeroCopyResponse = (ZeroCopyHttpOutputMessage) response;
        //设置文件下载响应头
        response.getHeaders().set(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=cateringConsole.xlsx");
        response.getHeaders().setContentType(MediaType.APPLICATION_OCTET_STREAM);
        //获取数据
        return getCateringConsole(search).concatMap(s -> getStatistics(s)).collectList().flatMap(statistics -> {
            try {
                String relTarget = "/static/cateringConsole.xlsx";
                //声明输入流
                InputStream inputStream = null;
                //声明输出流
                OutputStream fout = null;
                //声明临时文件
                File targetFile = null;
                // getResourceAsStream不以’/'开头时默认是从此类所在的包下取资源,以’/'开头则是从ClassPath根下获取。其只是通过path构造一个绝对路径,最终还是由ClassLoader获取资源。
                inputStream = this.getClass().getResourceAsStream(relTarget);
                //创建临时文件(在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。)
                targetFile = File.createTempFile("cateringConsole", "");
                //excel的文档对象(WorkbookFactory)
                final Workbook wb = WorkbookFactory.create(inputStream);//WorkbookFactory可以读取xls格式或xlsx格式
                //获取该工作区的第一个sheet
                Sheet sheet = wb.getSheetAt(0);
                //创建样式类
                CellStyle cellStyle = wb.createCellStyle();
                // 设置自动换行
                cellStyle.setWrapText(true);
                // 水平居中
                cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
                // 垂直居中
                cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
                // 设置字体
                Font font = wb.createFont();
                font.setFontName("宋体");
                // 设置字体粗细
                font.setBoldweight(HSSFFont.DEFAULT_CHARSET);
                // 设置字体大小
                font.setFontHeightInPoints((short) 13);
                // 选择需要用到的字体格式
                cellStyle.setFont(font);
                // 设置边框
                cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); // 下边框
                cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);// 左边框
                cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);// 上边框
                cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);// 右边框
                //设置该工作区的第一个sheet名字
                wb.setSheetName(0, "统计");


                for (int i = 0; i < statistics.size(); i++) {
                    //创建第二行
                    Row row = sheet.createRow(i + 1);
                    //设置每行行高
                    row.setHeightInPoints(28);

                    //日期
                    Cell cell1 = row.createCell(0);
                    cell1.setCellValue(statistics.get(i).getDate());
                    cell1.setCellStyle(cellStyle);

                    //地区
                    Cell cell2 = row.createCell(1);
                    cell2.setCellValue(statistics.get(i).getPlaceName());
                    cell2.setCellStyle(cellStyle);

                    //早餐数
                    Cell cell3 = row.createCell(2);
                    cell3.setCellValue(statistics.get(i).getTotalBreakfast());
                    cell3.setCellStyle(cellStyle);

                    //中餐数
                    Cell cell4 = row.createCell(3);
                    cell4.setCellValue(statistics.get(i).getTotalLunch());
                    cell4.setCellStyle(cellStyle);

                    //晚餐数
                    Cell cell5 = row.createCell(4);
                    cell5.setCellValue(statistics.get(i).getTotalDinner());
                    cell5.setCellStyle(cellStyle);
                }
                //创建最后一行
                Row row = sheet.createRow(statistics.size() + 1);
                //设置每行行高
                row.setHeightInPoints(28);
                //创建合并单元格对象(CellRangeAddress:单元格合并函数)
                CellRangeAddress callRangeAddress = new CellRangeAddress(statistics.size() + 1, statistics.size() + 1, 0, 1);//起始行,结束行,起始列,结束列
                //加载合并单元格对象
                sheet.addMergedRegion(callRangeAddress);
                Long totalBreakfastSum = statistics.stream().mapToLong(Statistics::getTotalBreakfast).sum();
                Long totalLunchSum = statistics.stream().mapToLong(Statistics::getTotalLunch).sum();
                Long totalDinner = statistics.stream().mapToLong(Statistics::getTotalDinner).sum();


                Cell cell = row.createCell(0);
                cell.setCellValue("合计");
                cell.setCellStyle(cellStyle);

                //合计早餐数
                Cell cell0 = row.createCell(1);
                cell0.setCellValue("");
                cell0.setCellStyle(cellStyle);

                //合计午餐数
                Cell cell1 = row.createCell(2);
                cell1.setCellValue(totalBreakfastSum);
                cell1.setCellStyle(cellStyle);
                Cell cell2 = row.createCell(3);
                cell2.setCellValue(totalLunchSum);
                cell2.setCellStyle(cellStyle);

                //合计晚餐数
                Cell cell3 = row.createCell(4);
                cell3.setCellValue(totalDinner);
                cell3.setCellStyle(cellStyle);

                //将临时文件输出
                fout = new BufferedOutputStream(new FileOutputStream(targetFile));
                //写入工作区
                wb.write(fout);
                //这里将数据写入ServerHttpResponse
                return zeroCopyResponse.writeWith(targetFile, 0, targetFile.length());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
    }

4.测试
测试的话可以使用swagger或者postman,甚至你前端技术足够ok的话也可以写个简单的页面进行测试,我是用的是postman进行的测试,下面就是我测试的结果了:
在这里插入图片描述

在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 数据台是一个集管理和整合企业数据的平台,它可以为企业提供数据分析、决策支持、业务运营等方面的服务。搭建数据台有助于提高企业的数据治理能力、加速数据价值的释放,并支持企业实现数字化转型。 搭建数据台的过程可以通过以下步骤来实现: 1. 数据需求识别:首先,企业需要明确自己的数据需求,包括哪些数据需要被整合和管理,以及需要利用这些数据做出什么样的决策或支持什么业务需求。 2. 数据源接入:根据数据需求,企业需要将来自不同系统和渠道的数据源接入到数据。这可以通过建立数据连接、集成接口、ETL工具等方式实现。 3. 数据清洗和整合:接入的数据往往需要经过清洗和整合,以确保数据的准确性、一致性和完整性。通过数据清洗和整合,可以提高数据质量并消除数据冗余。 4. 数据存储和管理:在数据,企业需要建立合适的数据存储和管理机制,以确保数据的安全性和可访问性。常见的数据存储方式有关系型数据库、数据仓库、数据湖等。 5. 数据加工和分析:通过数据加工和分析,可以为企业提供丰富的数据洞察和决策支持。这可以通过使用数据挖掘、机器学习、人工智能等技术实现。 6. 数据可视化和报表:将分析结果以可视化的形式展示给用户,并生成数据报表,以帮助用户更好地理解和利用数据。 最后,企业可以通过提供数据台的PDF下载等方式,将搭建数据台的经验和指南分享给其他企业,以促进数据台在行业的普及和应用。这样,更多的企业可以借鉴和应用这些经验,加速自身的数字化转型和数据驱动业务发展的进程。 ### 回答2: 数据台是指企业利用先进的数据技术和平台,将分散的数据资源进行整合和集成,实现数据的全面管理和应用。搭建数据台有助于企业更好地理解和使用数据,提升决策效果和业务价值。 要搭建数据台,首先需要明确目标和需求。企业需要明确想要实现的具体目标,并根据业务需求确定所需要的数据资源,以及数据台的功能和特性。 接下来,需要选择适合企业需求的数据台平台。有许多不同的数据台平台可以选择,包括开源的平台和商业化的平台。企业可以根据自身技术实力、预算和需求等综合考虑,选择最适合的平台。 然后,需要进行数据的集成和整合。企业需要将分散存储在不同系统数据资源进行整合,建立数据集市或数据仓库。这需要清洗、清理和转换数据,确保数据的质量和一致性。 同时,还需要建立数据治理体系。数据台需要有明确的数据治理策略和规范,包括数据的标准化、存储和访问权限的管理等。这有助于提高数据的可信度和安全性。 最后,需要将数据台与企业的业务系统进行集成和应用。数据台可以为企业提供数据分析、数据挖掘和机器学习等功能,帮助企业更好地理解和应用数据,推动业务发展。 在搭建数据台的过程,企业可以参考一些实战经验和案例,了解其他企业在搭建数据台时遇到的问题和解决方法。同时,也可以寻求专业的培训或咨询支持,帮助企业顺利地搭建自己的数据台。 总之,搭建数据台需要明确目标、选择合适的平台、进行数据的集成和治理,最终与业务系统进行集成和应用。通过合理规划和实施,企业可以有效地搭建数据台,提升数据价值和业务效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值