返回

教程:用Ajax调用POI导出Excel到SpringMVC

前端

理解需求:导出Excel的场景

在企业应用开发过程中,用户有时需要从服务器获取数据并以Excel格式下载到本地。为了提供更好的用户体验,我们希望这种操作能够通过异步请求来完成,而无需刷新页面。

Ajax调用POI导出Excel的工作原理

首先了解下整个过程的基本架构:前端使用Ajax发起异步请求到后台的SpringMVC控制器;服务器端利用Apache POI库处理数据并生成Excel文件;最后将文件流直接通过HTTP响应返回给客户端,由浏览器负责下载。

环境搭建与依赖管理

在开始编码之前,请确保项目中已包含相关依赖。对于Maven项目,在pom.xml添加POI和Spring的相关依赖:

<dependencies>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.3</version>
    </dependency>
    <!-- Spring MVC相关依赖 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.10</version>
    </dependency>
</dependencies>

创建数据模型和控制器

定义数据模型类(可选)

如果导出的数据结构复杂,定义一个Java Bean作为数据载体是一个好习惯:

public class ExportData {
    private String name;
    private int age;

    // Getters and Setters 省略
}

控制器代码示例

控制器负责接收前端请求,并调用业务逻辑生成Excel文件。以下为一个简单例子,展示如何在SpringMVC中处理:

import org.apache.poi.ss.usermodel.*;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.List;

@Controller
public class ExcelExportController {

    @RequestMapping(value = "/export", method = RequestMethod.GET)
    public ResponseEntity<byte[]> exportExcel(HttpServletRequest request) throws Exception {
        Workbook workbook = new HSSFWorkbook();
        Sheet sheet = workbook.createSheet("Data");
        
        // 创建表头
        Row headerRow = sheet.createRow(0);
        Cell cell1 = headerRow.createCell(0);
        cell1.setCellValue("Name");
        Cell cell2 = headerRow.createCell(1);
        cell2.setCellValue("Age");

        // 假设有一个数据列表需要导出,实际应用中可以替换为数据库查询结果
        List<ExportData> dataList = new ArrayList<>();
        dataList.add(new ExportData("John", 30));
        dataList.add(new ExportData("Mary", 25));

        int rowNum = 1;
        for (ExportData data : dataList) {
            Row row = sheet.createRow(rowNum++);
            Cell cell = row.createCell(0);
            cell.setCellValue(data.getName());
            cell = row.createCell(1);
            cell.setCellValue(data.getAge());
        }

        // 将Workbook写入输出流
        ServletOutputStream out = request.getOutputStream();
        workbook.write(out);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType("application/octet-stream"));
        headers.setContentDispositionFormData("attachment", "exported_data.xls");

        return ResponseEntity.ok().headers(headers).body(workbook.getBytes());
    }
}

前端页面实现

前端部分通过JavaScript发送Ajax请求到后端,接收返回的Excel文件并下载。这里使用jQuery来简化代码:

<a href="javascript:void(0);" onclick="exportData()">导出数据</a>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
    function exportData() {
        $.ajax({
            url: '/export',
            method: 'GET',
            xhrFields: {
                responseType: 'blob'
            },
            success: function (data) {
                let url = window.URL.createObjectURL(new Blob([data]));
                let link = document.createElement('a');
                link.href = url;
                link.setAttribute('download', 'exported_data.xls');
                document.body.appendChild(link);
                link.click();
            }
        });
    }
</script>

安全性考虑

在生产环境中部署此类功能时,应注意几点安全问题:

  • 确保下载链接的安全性,避免未经授权的访问。
  • 限制用户可导出的数据量以防止性能问题或DoS攻击。
  • 对于敏感信息的导出,务必实施适当的加密措施。

以上内容提供了一个基本的实现方法。根据具体需求,可能需要进一步调整代码结构和逻辑,确保应用安全高效运行。