springboot导出数据到excel模板,使用hutool导出数据到指定excel,java写入数据到excel模板

news2024/11/18 20:30:07

最近遇到一个需求,需要从数据库查询数据,写入到对应的excel导入模板中。再把导出的数据进行修改,上传。
我们项目用的是easyExcel,一顿百度搜索,不得其法。
主要是要把数据填充到指定单元格中,跟平时用到的导出不一样。项目中也没有引入其它poi。

后来忽然想起来,项目中集成的有hutool,可以用hutool的导入导出功能,先把excel导入模板读取出来,再给excel模板加工数据,最后再导出。

然后又开始了百度之旅~

终于在Two thousand years later~

写一个样例:
excel导入模板长这样:(随便画得)
第一个sheet页
第二个sheet页
第三个sheet页

想要的效果大概是这样:
稍微写了一点点数据,根据业务,自己完善。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码:

关于hutool版本,和导入导出所需依赖,可参考我篇文章。hutool导入导出,java使用hutool导入导出,hutool导出多级标题复杂表头,hutool大数据量导出

因为我这个项目是springboot的,所以我把excel模板放在了这里。方便读取。

在这里插入图片描述

 package com.demo.controller;

import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@Api(tags = "控制类")
@RequestMapping("/user")
public class UserController {

    @GetMapping("/download")
    public void download(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //添加测试数据
        List<Map<String,String>> list1 = new ArrayList<>();
        Map<String, String> map = new HashMap<>();
        map.put("q1","moveNo");
        map.put("q2","moveNo");
        map.put("q3","78");
        map.put("q4","moveNo");
        map.put("q5","moveNo");
        map.put("q6","moveNo");
        map.put("q7","moveNo");
        Map<String, String> map1 = new HashMap<>();
        map1.put("q5","moveNo");
        map1.put("q6","moveNo");
        map1.put("q7","moveNo");
        list1.add(map);
        list1.add(map1);


        //添加测试数据
        List<Map<String,Object>> printVoList = new ArrayList<>();
        Map<String, Object> hashMap = new HashMap<>();
        hashMap.put("COL1","123");
        hashMap.put("COL2","234");
        hashMap.put("COL3","345");
        hashMap.put("COL4","456");
        Map<String, Object> hashMap1 = new HashMap<>();
        hashMap1.put("COL1","哈");
        hashMap1.put("COL2","吧");
        hashMap1.put("COL3","吗");
        printVoList.add(hashMap);
        printVoList.add(hashMap1);


        //获取文件输入流
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("123.xlsx");

        //设置返回
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("我测试的", "utf-8") + ".xlsx");
        OutputStream out = response.getOutputStream();

        if (inputStream == null){
            throw new RuntimeException("文件未找到!");
        }

        //获取工作簿
        Workbook workbook = new XSSFWorkbook(inputStream);

        //获取创建工作簿的第一页
        Sheet sheet=workbook.getSheetAt(0);
        //给指定的sheet命名
//        workbook.setSheetName(0,"dataSheet");
        //获取当前工作簿的行数
//        int totalRows=sheet.getPhysicalNumberOfRows();
        //****遍历模板sheet,根据当中的设定进行赋值****
        int newRowIndex = 3;//起始行 从第4行开始
        for (int i=0;i<list1.size();i++) {
            Row row = sheet.createRow(newRowIndex++);
            int column = row.getLastCellNum();
            int j = 0;
            (row.getCell(j)!=null?row.getCell(j):row.createCell(j)).setCellValue(list1.get(i).get("q1"));
            j++;(row.getCell(j)!=null?row.getCell(j):row.createCell(j) ).setCellValue(list1.get(i).get("q2"));
            j++;(row.getCell(j)!=null?row.getCell(j):row.createCell(j) ).setCellValue(list1.get(i).get("q3"));
            j++;(row.getCell(j)!=null?row.getCell(j):row.createCell(j) ).setCellValue(list1.get(i).get("q4"));
            j++;(row.getCell(j)!=null?row.getCell(j):row.createCell(j) ).setCellValue(list1.get(i).get("q5"));
            j++;(row.getCell(j)!=null?row.getCell(j):row.createCell(j) ).setCellValue(list1.get(i).get("q6"));
            j++;(row.getCell(j)!=null?row.getCell(j):row.createCell(j) ).setCellValue(list1.get(i).get("q7"));
        }


        //获取创建工作簿的第2页
        Sheet sheet1=workbook.getSheetAt(1);
        //获取当前工作簿的行数
        int totalRows=sheet1.getPhysicalNumberOfRows();
        for (int i = 0;i<totalRows;i++){
            Row row = sheet1.getRow(i);
            if (row == null) continue;
            System.out.println(row.getRowNum() + JSONUtil.toJsonStr(row));;
        }
        sheet1.getRow(4).getCell(3).setCellValue("1");
        sheet1.getRow(5).getCell(3).setCellValue("1");
        //获取创建工作簿的第3页
        Sheet sheet2=workbook.getSheetAt(2);
        System.out.println("================");
        for (int i = 0;i<sheet2.getPhysicalNumberOfRows();i++){
            Row row = sheet2.getRow(i);
            if (row == null) continue;
            System.out.println(row.getRowNum() + JSONUtil.toJsonStr(row));;
        }
        //获取当前工作簿的行数
//        int totalRows2=sheet1.getPhysicalNumberOfRows();

        sheet2.getRow(2).getCell(3).setCellValue("1");
        sheet2.getRow(3).getCell(3).setCellValue("3");
        sheet2.getRow(5).getCell(3).setCellValue("111");
        sheet2.getRow(5).getCell(5).setCellValue("3333");
        sheet2.getRow(11).getCell(3).setCellValue("3333");
        sheet2.getRow(11).getCell(5).setCellValue("3333");
        /*int newRowIndex = 3;//起始行 从第4行开始
        //获取模板对应的数据表字段的值
        Row dataRow=sheet.getRow(newRowIndex++);
        //获得该行对应的字段的数量
        int columnNum=dataRow.getPhysicalNumberOfCells();

        //将结果集渲染到当前sheet当中
        for (Map<String,Object> pageData:printVoList) {
            sheet.shiftRows(newRowIndex, totalRows + 1, 1); //在startRow和endRow之间的行移动一行
            Row newRow = sheet.createRow(newRowIndex++);
            //创建需要插入的目标行,该值需要在每次完成一行记录值插入后重新归0
            int cellIndex = 0;

            //ic此处为cells数组的结果集的字段的位置
            for (int i = 1; i <= columnNum; i++) {
                //从pageData当中取出目标单元格需要的值
                String cellContent = pageData.get("COL"+i) != null ? String.valueOf(pageData.get("COL"+i)) : "";
                //设置目标单元格的位置和类型
                Cell cell = newRow.createCell(cellIndex++, Cell.CELL_TYPE_STRING);
                //设置目标单元格的值
                cell.setCellValue(cellContent);
            }
        }*/
        workbook.write(out);
        out.flush();
        out.close();

    }

}

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

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

相关文章

【操作工具】IDEA的properties文件变为灰色的解决办法

背景 赋值了一份properties文件放到项目下面&#xff0c;但是里面的key都是灰色的 解决方案 去掉下面3后面对应的勾 去掉之后

《Linux C编程实战》笔记:信号的发送

信号的发送主要由函数kill、raise、sigqueue、alarm、setitimer以及abort来完成 kill函数 kill函数用来发送信号给指定的进程。 #include<sys/types.h> #include<signal.h> int kill(pid_t pid,int sig); 该函数的行为与第一个参数pid有关&#xff0c;第二个参…

幻兽帕鲁安装和开服教学

《幻兽帕鲁》游戏热度异常火爆&#xff0c;很多玩家想下载《幻兽帕鲁》和朋友玩&#xff0c;但不知道在哪里能够下载到&#xff0c;下面请看《幻兽帕鲁》下载安装教学&#xff0c;希望能够帮助大家。 幻兽帕鲁》目前仅在PC上的Steam平台发售&#xff0c;可以登录Steam搜索“幻…

Unity 解决异步分发方案

很多程序&#xff0c;包括游戏、小程序、一些AR、VR的程序&#xff0c;因为客户端体量太大&#xff0c;更新频繁都涉及到远程热更新的问题&#xff0c;解决这类问题的思路基本上是客户端解决主要功能&#xff0c;资源类放置在服务器。 下面记录下&#xff1a; 1.CDN或者云轻量…

AI嵌入式K210项目(18)-卷积人工神经网络硬件加速器 KPU

文章目录 前言一、K210的KPU二、实验过程总结 前言 K210内置了丰富的加速器&#xff0c;包括神经网络处理器 (KPU)&#xff0c;AES(高级加密加速器)&#xff0c;APU 麦克风阵列语音数据加速计算处理器&#xff0c;现场可编程 IO 阵列 (FPIOA)&#xff0c;数字摄像头接口 (DVP)…

源码篇--Redis 五种数据类型

文章目录 前言一、 字符串类型&#xff1a;1.1 字符串的编码格式&#xff1a;1.1.1 raw 编码格式:1.1.2 empstr编码格式:1.1.3 int 编码格式:1.1.4 字符串存储结构展示: 二、 list类型&#xff1a;2.1 List 底层数据支持&#xff1a;2.2 List 源码实现&#xff1a;2.3 List 结构…

水经微图系列产品新功能盘点!

水经微图&#xff0c;简称“微图”。 我们曾在直播中分享过微图APP苹果版的功能&#xff0c;本周四晚19:30我们将在另一个视频号分享盘点微图APP安卓版的详细功能&#xff0c;以及Web版近期上线的新功能功能。 微图APP安卓版 我们在《水经微图安卓版APP正式上线》一文中&…

ABAP SQL CDSView Entity中使用正则RegEx表达式(Regular Expressions)

1. 正则表达式测试程序 DEMO_REGEXDEMO_REGEX_TOY 2. ABAP SQL & CDSView Entity支持正则语法的场景 SQL函数语法作用执行逻辑返回类型CDS View EntitiesABAP SQLLIKE_REGEXPRLIKE_REGEXPR( PCRE pcre, VALUE sql_exp1[, CASE_SENSIT…

Unity Mask合批情况验证

1.首先是两个Mask完全重合的情况下 每张图片使用的image都来自同一个图集 发现彼此之间是没有合批的&#xff0c;但是每个Mask内部是实现了合批的 经过计算此种情况的visiableList&#xff1a;mask1&#xff0c;IM1&#xff0c;IM2&#xff0c;mask2&#xff0c;IM3&#xf…

Centos7 两种方式安装 MySQL5.7 步骤 yum 、本地 tar 文件

一、使用 yum 源方式安装 1、卸载系统自带 mariadb MariaDB Server 是最流行的开源 关系型数据库 之一。它由 MySQL 的原始开发者制作&#xff0c;并保证保持开源。 在 CentOS 7 中默认安装有 MariaDB 可忽略&#xff0c;安装完成之后可以直接覆盖掉 MariaDB。 查看并卸载系统…

如何在阿里云提交使用工单

有时候大家在使用阿里云的服务时候&#xff0c;可能会遇到一些问题&#xff0c;或许是云服务器如何升级了如何改套餐啊之类的&#xff0c;亦或者是域名ICP备案啊看进度啊等等问题&#xff0c;遇到问题怎么办不要慌。我们可以使用阿里云的工单系统&#xff0c;阿里云工单系统可以…

虚拟机网络配置及Moba工具的使用

A、设置IP和网关 1、设置IP [roothadoop00 ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0 &#xff08;修改如下标红内容&#xff0c;没有的就添加&#xff09; DEVICEeth0 HWADDR08:00:27:BD:9D:B5 #不用改 TYPEEthernet UUID53e4e4b6-9724-43ab-9da7-68792e611031…

Confluence6+mysql5.7破j安装避坑详细记录

目录 一、前言 二、下载与安装 1、版本和安装环境 2、安装数据库 3、配置数据库 4、安装confluence 三、Pj confluence 1、选择语言和产品安装 2、Pj 3、上传mysql驱动 4、重启Confluence服务继续安装 四、Confluence重启卸载方法 重启方法 方法一 方法二 卸载…

acwing 动态规划dp 0 1背包问题

前言 hello小伙伴们&#xff0c;最近由于个人放假原因颓废了一段时间很长时间没有更新CSDN的内容了&#xff0c;唉&#xff0c;毕竟懂得都懂寒暑假静下心来学习的难度远比在学校里大的多。 但是&#xff0c;也不是毫无办法克服&#xff0c;今天我来了我们当地的一家自习室来学习…

《WebKit 技术内幕》学习之四(3): 资源加载和网络栈

3. 网络栈 3.1 WebKit的网络设施 WebKit的资源加载其实是交由各个移植来实现的&#xff0c;所以WebCore其实并没有什么特别的基础设施&#xff0c;每个移植的网络实现是非常不一样的。 从WebKit的代码结构中可以看出&#xff0c;网络部分代码的确比较少的&#xff0c;它们都在…

Mybatis 全局配置文件(三)

文章目录 第一章&#xff1a;概述第二章&#xff1a;properties (了解)第三章&#xff1a;settings第四章&#xff1a;typeAliases (别名处理器)第五章&#xff1a;typeHandlers (类型处理器)第六章&#xff1a;plugins(插件)第七章&#xff1a;environments (环境)第八章&…

k8s-基础知识(Service,NodePort,CusterIP,NameSpace,资源限制)

Node Node 是 Pod 真正运行的主机&#xff0c;可以是物理机&#xff0c;也可以是虚拟机。 Annotations 原文链接 Annotations 是 key/value 形式附加于对象的注解。不同于 Labels 用于标志和选择对象&#xff0c;Annotations 则是用来记录一些附加信息&#xff0c;用来辅助应…

深入理解JS语法与变量

深入理解JS语法与变量 前言初识JavaScriptJavaScript的语言风格和特性 JavaScript的书写位置认识输出语句学会处理报错REPL 环境 变量定义变量改变变量变量的合法命名变量的默认值变量的常见错误等号表示赋值同时声明多个变量 变量声明提升注意事项 结语 前言 在现代Web开发中…

Vue构建项目断点调试过程问题总结

Vue构建项目断点调试过程问题总结 问题背景 前端开发过程中&#xff0c;碰到问题时需要debug&#xff0c;快速分析和解决问题。一般除了console.log的方式打印日志外&#xff0c;更方便直观的方式就是打断点debug。本文对vue项目debug过程可能碰到的问题进行总结&#xff0c;…

Kafka(二)原理详解

一 、kafka核心总控制器&#xff08;Controller&#xff09; 在Kafka集群中会有一个或者多个broker&#xff0c;其中有一个broker会被选举为控制器&#xff08;Kafka Controller&#xff09;&#xff0c;它负责管理整个集群中所有分区和副本的状态。 作用&#xff1a;leader副…