杰瑞科技汇

Java如何生成Excel并实现下载?

Java 生成 Excel 并提供下载

在 Java 中生成 Excel 文件并提供下载有多种方式,以下是几种常用的实现方法:

Java如何生成Excel并实现下载?-图1
(图片来源网络,侵删)

使用 Apache POI

Apache POI 是最常用的 Java 操作 Excel 的库。

Maven 依赖

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.3</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.3</version>
</dependency>

示例代码(Servlet 环境)

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
public class ExcelDownloadServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        // 1. 创建工作簿
        Workbook workbook = new XSSFWorkbook();
        // 2. 创建工作表
        Sheet sheet = workbook.createSheet("用户数据");
        // 3. 创建标题行
        Row headerRow = sheet.createRow(0);
        headerRow.createCell(0).setCellValue("ID");
        headerRow.createCell(1).setCellValue("姓名");
        headerRow.createCell(2).setCellValue("年龄");
        // 4. 添加数据行
        Row dataRow1 = sheet.createRow(1);
        dataRow1.createCell(0).setCellValue(1);
        dataRow1.createCell(1).setCellValue("张三");
        dataRow1.createCell(2).setCellValue(25);
        Row dataRow2 = sheet.createRow(2);
        dataRow2.createCell(0).setCellValue(2);
        dataRow2.createCell(1).setCellValue("李四");
        dataRow2.createCell(2).setCellValue(30);
        // 5. 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-Disposition", "attachment; filename=user_data.xlsx");
        // 6. 写入输出流
        try (OutputStream out = response.getOutputStream()) {
            workbook.write(out);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

使用 EasyExcel

EasyExcel 是阿里巴巴开源的 Excel 处理工具,性能更好,内存占用更小。

Maven 依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.1.1</version>
</dependency>

示例代码

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class EasyExcelDownloadServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        // 1. 准备数据
        List<UserData> dataList = new ArrayList<>();
        dataList.add(new UserData(1, "张三", 25));
        dataList.add(new UserData(2, "李四", 30));
        // 2. 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-Disposition", "attachment; filename=user_data.xlsx");
        // 3. 写入Excel
        try (OutputStream out = response.getOutputStream()) {
            // 样式策略
            WriteCellStyle headWriteCellStyle = new WriteCellStyle();
            headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
            WriteFont headWriteFont = new WriteFont();
            headWriteFont.setFontHeightInPoints((short) 10);
            headWriteCellStyle.setWriteFont(headWriteFont);
            headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
            WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
            contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
            HorizontalCellStyleStrategy horizontalCellStyleStrategy = 
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
            EasyExcel.write(out, UserData.class)
                    .registerWriteHandler(horizontalCellStyleStrategy)
                    .sheet("用户数据")
                    .doWrite(dataList);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 数据模型类
    public static class UserData {
        private Integer id;
        private String name;
        private Integer age;
        // 构造方法、getter和setter省略...
    }
}

使用 JXL

JXL 是一个较老的 Java Excel 库,但仍然简单易用。

Maven 依赖

<dependency>
    <groupId>net.sourceforge.jexcelapi</groupId>
    <artifactId>jxl</artifactId>
    <version>2.6.12</version>
</dependency>

示例代码

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
public class JxlExcelDownloadServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        // 1. 创建工作簿
        try (OutputStream out = response.getOutputStream();
             WritableWorkbook workbook = Workbook.createWorkbook(out)) {
            // 2. 创建工作表
            WritableSheet sheet = workbook.createSheet("用户数据", 0);
            // 3. 添加标题
            sheet.addCell(new Label(0, 0, "ID"));
            sheet.addCell(new Label(1, 0, "姓名"));
            sheet.addCell(new Label(2, 0, "年龄"));
            // 4. 添加数据
            sheet.addCell(new Label(0, 1, "1"));
            sheet.addCell(new Label(1, 1, "张三"));
            sheet.addCell(new Label(2, 1, "25"));
            sheet.addCell(new Label(0, 2, "2"));
            sheet.addCell(new Label(1, 2, "李四"));
            sheet.addCell(new Label(2, 2, "30"));
            // 5. 设置响应头
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment; filename=user_data.xls");
            // 6. 写入工作簿
            workbook.write();
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Spring Boot 环境下的实现

在 Spring Boot 中,可以使用 @RestControllerResponseEntity 来实现:

Java如何生成Excel并实现下载?-图2
(图片来源网络,侵删)
import com.alibaba.excel.EasyExcel;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@RestController
public class ExcelController {
    @GetMapping("/download/excel")
    public void downloadExcel(HttpServletResponse response) throws IOException {
        // 准备数据
        List<UserData> dataList = new ArrayList<>();
        dataList.add(new UserData(1, "张三", 25));
        dataList.add(new UserData(2, "李四", 30));
        // 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", 
            "attachment;filename=user_data.xlsx");
        // 写入Excel
        EasyExcel.write(response.getOutputStream(), UserData.class)
                .sheet("用户数据")
                .doWrite(dataList);
    }
    public static class UserData {
        private Integer id;
        private String name;
        private Integer age;
        // 构造方法、getter和setter省略...
    }
}

注意事项

  1. 内存管理:对于大数据量,使用 EasyExcel 或 SXSSF (Apache POI 的大数据量处理方式) 避免内存溢出
  2. 文件名编码:中文文件名需要处理编码,可以使用 URLEncoder.encode() 进行编码
  3. 异常处理:确保在 finally 块中关闭资源
  4. 响应头:正确设置 Content-Type 和 Content-Disposition 头
  5. 线程安全:在 Web 应用中确保 Excel 处理的线程安全

方法可以根据项目需求和技术栈选择合适的实现方式。

Java如何生成Excel并实现下载?-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇