Springboot使用Apache POI实现导入导出和解析Excel

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: Springboot使用Apache POI实现导入导出和解析Excel

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站点击跳转浏览。


1准备pom文件


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.miyo</groupId>
    <artifactId>miyo-file-server</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.8</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--热部署配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
<!--        &lt;!&ndash; mybatis-spring-boot-starter &ndash;&gt;-->
<!--        <dependency>-->
<!--            <groupId>org.mybatis.spring.boot</groupId>-->
<!--            <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!--            <version>2.1.1</version>-->
<!--        </dependency>-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>mysql</groupId>-->
<!--            <artifactId>mysql-connector-java</artifactId>-->
<!--            <scope>runtime</scope>-->
<!--        </dependency>-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2 在controller里面有生成Excel,解析Excel方法

首先先用



这个方法,导出一个Excel,然后将文件放到



这个位置之后就可以根据前端传来的数值进行修改模板中字段了。


package com.miyo.controller;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Font;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;
/**
 * @author xiaoli.he
 * @date 2022/5/20
 */
@Controller
public class TemplateController {
  /**
   * 根据模板修改下载对应的Excel
   *
   * @param response excel
   * @param templateCode code
   * @param includeFields 选中的字段
   * @throws Exception null
   */
  @SuppressWarnings("resource")
  @RequestMapping("/download")
  @ResponseBody
  public void download(
      HttpServletResponse response, String templateCode, @RequestBody List<String> includeFields)
      throws Exception {
    // 测试
    int length = templateCode.length();
    System.out.println(length);
    // 判断得到那些值
    // 模板文件放在resources中的download包中
    String filePath =
        Objects.requireNonNull(TemplateController.class.getClassLoader().getResource("download"))
                .getPath()
            + "/template.xls";
    FileInputStream fileInputStream = new FileInputStream(filePath);
    BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
    POIFSFileSystem fileSystem = new POIFSFileSystem(bufferedInputStream);
    HSSFWorkbook workbook = new HSSFWorkbook(fileSystem);
    HSSFSheet sheet = workbook.getSheet("Sheet1");
    // 得到第一行
    HSSFRow row = sheet.getRow(0);
    // 得到最后一列
    short lastCellNum = row.getLastCellNum();
    // 判断那些列需要采用
    for (int j = 0; j < lastCellNum; j++) {
      String cellValue = row.getCell(j).getStringCellValue();
      HSSFCell cell = row.getCell(j);
      // 没有则从模板中移除
      if (!includeFields.contains(cellValue)) {
        row.removeCell(cell);
      }
    }
    bufferedInputStream.close();
    // 输出Excel文件
    OutputStream outputStream = response.getOutputStream();
    response.reset();
    response.setContentType("application/vnd.ms-excel");
    response.setHeader("Content-disposition", "attachment;filename=template.xls");
    workbook.write(outputStream);
    outputStream.flush();
    outputStream.close();
  }
  /**
   * 解析Excel
   *
   * @param file file
   * @throws Exception null
   */
  @SuppressWarnings("resource")
  @RequestMapping("/parse")
  @ResponseBody
  public void parse(@RequestParam("file") MultipartFile file) throws Exception {
    InputStream inputStream = file.getInputStream();
    BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
    POIFSFileSystem fileSystem = new POIFSFileSystem(bufferedInputStream);
    HSSFWorkbook workbook = new HSSFWorkbook(fileSystem);
    HSSFSheet sheet = workbook.getSheetAt(0);
    // 得到行数
    int lastRowNum = sheet.getLastRowNum();
    // 解析并且封装到一个list
    List<Map<String, String>> listMaps = new ArrayList<>();
    // 得到第一行作为表头
    HSSFRow row1 = sheet.getRow(0);
    int lastCellNum = row1.getLastCellNum();
    String[] arr = new String[lastCellNum];
    // 存入数组中
    for (int t = 0; t < lastCellNum; t++) {
      HSSFCell cell = row1.getCell(t);
      String cellValue = cell.getStringCellValue();
      arr[t] = cellValue;
    }
    for (int i = 1; i <= lastRowNum; i++) {
      // 每一行数据对应一个map
      Map<String, String> map = new HashMap<>(16);
      HSSFRow row = sheet.getRow(i);
      // 得到有几列
      int num = row.getLastCellNum();
      // 遍历每一行的单元格
      for (int j = 0; j < num; j++) {
        HSSFCell cell = row.getCell(j);
        // 设置类型为String
        cell.setCellType(org.apache.poi.ss.usermodel.Cell.CELL_TYPE_STRING);
        String cellValue = cell.getStringCellValue();
        // 把表头和里面的值对应
        map.put(arr[j], cellValue);
      }
      listMaps.add(map);
    }
    System.out.println(listMaps);
  }
  /**
   * 生成Excel
   *
   * @param response Excel
   * @throws Exception null
   */
  @SuppressWarnings("resource")
  @RequestMapping("/exportExcel")
  public void exportExcel(HttpServletResponse response) throws Exception {
    // 创建一个excel的文档对象
    HSSFWorkbook workbook = new HSSFWorkbook();
    // 创建excel的表单
    HSSFSheet sheet = workbook.createSheet("Sheet1");
    // cell样式
    HSSFCellStyle cellStyle = workbook.createCellStyle();
    // 设置水平和垂直居中
    cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
    cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
    // 生成一个字体
    Font font = workbook.createFont();
    font.setFontHeightInPoints((short) 9);
    // 设置字体的颜色
    font.setColor(HSSFColor.BLUE.index);
    // 设置字体加粗
    font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
    cellStyle.setFont(font);
    // 创建一个行
    HSSFRow row = sheet.createRow(0);
    // 设计表头
    String[] tableHeaders = {
      "公司", "毛利率", "净现比", "管理费用率", "销售费用率", "预付账款周转率", "应收账款周转率", "应付账款周转率", "其他应收款占总资产比", "其他应付应收比"
    };
    // 创建表头
    for (int i = 0; i < tableHeaders.length; i++) {
      // 如果用了添加表头
      // 创建单元格并设置单元格内容
      HSSFCell cell = row.createCell(i);
      // 表头数组
      cell.setCellValue(tableHeaders[i]);
      // 赋予格式
      cell.setCellStyle(cellStyle);
    }
    // 输出Excel文件
    OutputStream outputStream = response.getOutputStream();
    response.reset();
    response.setContentType("application/vnd.ms-excel");
    response.setHeader("Content-disposition", "attachment;filename=template.xls");
    workbook.write(outputStream);
    outputStream.flush();
    outputStream.close();
  }
}

3,之后用postman测试成功

相关文章
|
1月前
|
并行计算 Java 数据处理
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
150 0
|
1月前
|
存储 缓存 算法
分布式锁服务深度解析:以Apache Flink的Checkpointing机制为例
【10月更文挑战第7天】在分布式系统中,多个进程或节点可能需要同时访问和操作共享资源。为了确保数据的一致性和系统的稳定性,我们需要一种机制来协调这些进程或节点的访问,避免并发冲突和竞态条件。分布式锁服务正是为此而生的一种解决方案。它通过在网络环境中实现锁机制,确保同一时间只有一个进程或节点能够访问和操作共享资源。
63 3
|
1月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
162 2
|
18天前
|
消息中间件 存储 负载均衡
Apache Kafka核心概念解析:生产者、消费者与Broker
【10月更文挑战第24天】在数字化转型的大潮中,数据的实时处理能力成为了企业竞争力的重要组成部分。Apache Kafka 作为一款高性能的消息队列系统,在这一领域占据了重要地位。通过使用 Kafka,企业可以构建出高效的数据管道,实现数据的快速传输和处理。今天,我将从个人的角度出发,深入解析 Kafka 的三大核心组件——生产者、消费者与 Broker,希望能够帮助大家建立起对 Kafka 内部机制的基本理解。
49 2
|
1月前
|
easyexcel Java UED
SpringBoot中大量数据导出方案:使用EasyExcel并行导出多个excel文件并压缩zip后下载
在SpringBoot环境中,为了优化大量数据的Excel导出体验,可采用异步方式处理。具体做法是将数据拆分后利用`CompletableFuture`与`ThreadPoolTaskExecutor`并行导出,并使用EasyExcel生成多个Excel文件,最终将其压缩成ZIP文件供下载。此方案提升了导出效率,改善了用户体验。代码示例展示了如何实现这一过程,包括多线程处理、模板导出及资源清理等关键步骤。
|
1月前
|
数据处理 Python
Python 高级技巧:深入解析读取 Excel 文件的多种方法
在数据分析中,从 Excel 文件读取数据是常见需求。本文介绍了使用 Python 的三个库:`pandas`、`openpyxl` 和 `xlrd` 来高效处理 Excel 文件的方法。`pandas` 提供了简洁的接口,而 `openpyxl` 和 `xlrd` 则针对不同版本的 Excel 文件格式提供了详细的数据读取和处理功能。此外,还介绍了如何处理复杂格式(如合并单元格)和进行性能优化(如分块读取)。通过这些技巧,可以轻松应对各种 Excel 数据处理任务。
168 16
|
1月前
|
前端开发 JavaScript
💥【exceljs】纯前端如何实现Excel导出下载和上传解析?
本文介绍了用于处理Excel文件的库——ExcelJS,相较于SheetJS,ExcelJS支持更高级的样式自定义且易于使用。表格对比显示,ExcelJS在样式设置、内存效率及流式操作方面更具优势。主要适用于Node.js环境,也支持浏览器端使用。文中详细展示了如何利用ExcelJS实现前端的Excel导出下载和上传解析功能,并提供了示例代码。此外,还提供了在线调试的仓库链接和运行命令,方便读者实践。
286 5
|
2月前
|
存储 缓存 Java
在Spring Boot中使用缓存的技术解析
通过利用Spring Boot中的缓存支持,开发者可以轻松地实现高效和可扩展的缓存策略,进而提升应用的性能和用户体验。Spring Boot的声明式缓存抽象和对多种缓存技术的支持,使得集成和使用缓存变得前所未有的简单。无论是在开发新应用还是优化现有应用,合理地使用缓存都是提高性能的有效手段。
38 1
|
1月前
|
前端开发 JavaScript Java
【SpringBoot系列】视图解析器的搭建与开发
【SpringBoot系列】视图解析器的搭建与开发
23 0
|
1月前
|
数据采集 存储 JavaScript
自动化数据处理:使用Selenium与Excel打造的数据爬取管道
本文介绍了一种使用Selenium和Excel结合代理IP技术从WIPO品牌数据库(branddb.wipo.int)自动化爬取专利信息的方法。通过Selenium模拟用户操作,处理JavaScript动态加载页面,利用代理IP避免IP封禁,确保数据爬取稳定性和隐私性。爬取的数据将存储在Excel中,便于后续分析。此外,文章还详细介绍了Selenium的基本设置、代理IP配置及使用技巧,并探讨了未来可能采用的更多防反爬策略,以提升爬虫效率和稳定性。