java使用阿里的easyExcel解决把excel每行的数据转成excel表格格式数据并打包成ZIP下载

转成

创建excel行数据对应Vo实体

java 复制代码
package com.example.demo;

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

@Data
public class Demo2 {

    @ExcelProperty("代码")
    private String zddm;

    @ExcelProperty("不动产单元代码")
    private String bdcdydm;

    @ExcelProperty("名称")
    private String mc;

    @ExcelProperty("负责人姓名")
    private String fzrxm;

    @ExcelProperty("负责人地址")
    private String fzrdz;

    @ExcelProperty("联系电话")
    private String lxdh;

    @ExcelProperty("证件号")
    private String zjh;

    @ExcelProperty("承包方(代表)姓名或名称")
    private String cbf;

    @ExcelProperty("身份证号码")
    private String sfzhm;

}

package com.example.demo;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

创建excel表格模版

使用easyExcel读取excel行数据 写入excel表格模版文件

java 复制代码
@RestController
@RequestMapping("/excel")
public class DemoController2 {

    private static String zipFileName = "调查表.zip";

    private static String fileName = "调查表";

    private static String teplateFileName = "static/template2.xlsx";



    @PostMapping("/upload2")
    public ResponseEntity<Resource> upload(@ModelAttribute MultipartFile file, HttpServletRequest request, HttpServletResponse response) {
        try {
            // 验证文件
            if (file == null || file.isEmpty()) {
                throw new IllegalArgumentException("上传文件不能为空");
            }

            System.out.println("开始处理上传文件,文件名: " + file.getOriginalFilename());
            System.out.println("文件大小: " + file.getSize() + " bytes");

            // 读取上传的Excel文件
            List<Demo2> rows = EasyExcel.read(file.getInputStream())
                    .head(Demo2.class)
                    .sheet()
                    .headRowNumber(1)
                    .autoTrim(true)
                    .doReadSync();

            System.out.println("成功读取数据行数: " + rows.size());

            if (rows.isEmpty()) {
                throw new IllegalArgumentException("上传文件中没有数据");
            }

            // 创建临时zip文件
            File tempZipFile = File.createTempFile("林木调查表", ".zip");
            System.out.println("创建临时zip文件: " + tempZipFile.getAbsolutePath());

            try (FileOutputStream fos = new FileOutputStream(tempZipFile);
                 ZipOutputStream zos = new ZipOutputStream(fos)) {

                // 加载模板文件
                ClassPathResource templateResource = new ClassPathResource(teplateFileName);
                System.out.println("模板文件路径: " + templateResource.getPath());

                if (!templateResource.exists()) {
                    throw new FileNotFoundException("模板文件不存在: "+teplateFileName);
                }

                System.out.println("模板文件存在,开始处理数据...");

                for (int i = 0; i < rows.size(); i++) {
                    Demo2 demo = rows.get(i);
                    System.out.println("\n=== 开始处理第 " + (i + 1) + " 条数据 ===");
                    processSingleDemo(demo, i, templateResource, zos);
                }

                System.out.println("所有数据处理完成,开始打包...");
            }

            System.out.println("Zip文件创建成功,大小: " + tempZipFile.length() + " bytes");

            String encodedFileName = encodeFileName(zipFileName, request);

            // 创建返回资源
            InputStreamResource resource = new InputStreamResource(new FileInputStream(tempZipFile)) {
                @Override
                public String getFilename() {
                    return "forest_survey.zip"; // 英文备用名
                }

                @Override
                public InputStream getInputStream() throws IOException {
                    return new FileInputStream(tempZipFile);
                }
            };

            // 设置响应头 - 使用RFC 5987标准
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_TYPE, "application/zip");
            headers.add(HttpHeaders.CONTENT_DISPOSITION,
                    "attachment; filename="+encodedFileName+"; filename*=UTF-8''");

            return ResponseEntity.ok()
                    .headers(headers)
                    .contentLength(tempZipFile.length())
                    .body(resource);

        } catch (Exception e) {
            System.err.println("处理文件时发生错误: " + e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("处理文件时发生错误: " + e.getMessage(), e);
        }
    }

    /**
     * 处理单个Demo对象
     */
    private void processSingleDemo(Demo2 demo, int index, ClassPathResource templateResource,
                                   ZipOutputStream zos) throws IOException {
        File tempExcelFile = null;
        try {
            tempExcelFile = File.createTempFile("temp_excel", ".xlsx");

            // 使用模板填充数据
            try (InputStream templateStream = templateResource.getInputStream();
                 FileOutputStream excelFos = new FileOutputStream(tempExcelFile)) {

                ExcelWriter excelWriter = EasyExcel.write(excelFos)
                        .withTemplate(templateStream)
                        .build();

                WriteSheet writeSheet = EasyExcel.writerSheet().build();
                excelWriter.fill(demo, writeSheet);
                excelWriter.finish();
            }

            // 添加到zip
            String fileName = generateFileName(demo, index);
            zos.putNextEntry(new ZipEntry(fileName));
            Files.copy(tempExcelFile.toPath(), zos);
            zos.closeEntry();

        } finally {
            // 清理临时文件
            if (tempExcelFile != null && tempExcelFile.exists()) {
                tempExcelFile.delete();
            }
        }
    }

    /**
     * 生成文件名
     */
    private String generateFileName(Demo2 demo, int index) {
        StringBuilder fileNamee = new StringBuilder(fileName);
        // 优先使用宗地代码
        if (demo.getZddm() != null && !demo.getZddm().trim().isEmpty()) {
            fileNamee.append("_").append(demo.getZddm().trim());
        }else {
            fileNamee.append("_").append(index + 1);
        }
        fileNamee.append(".xlsx");
        return fileNamee.toString();
    }

    /**
     * 编码文件名,解决中文乱码问题
     */
    private String encodeFileName(String fileName, HttpServletRequest request) {
        try {
            String userAgent = request.getHeader("User-Agent");
            String encodedFileName;

            if (userAgent != null) {
                userAgent = userAgent.toLowerCase();

                if (userAgent.contains("msie") || userAgent.contains("trident")) {
                    // IE浏览器
                    encodedFileName = URLEncoder.encode(fileName, "UTF-8");
                } else if (userAgent.contains("firefox")) {
                    // Firefox浏览器
                    encodedFileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
                } else {
                    // Chrome/Safari等现代浏览器
                    encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
                }
            } else {
                // 默认处理
                encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
            }
            return encodedFileName;
        } catch (UnsupportedEncodingException e) {
            // 编码失败时返回安全的英文文件名
            return "forest_survey.zip";
        }
    }

}
相关推荐
mftang9 分钟前
Python 字符串拼接成字节详解
开发语言·python
jasligea30 分钟前
构建个人智能助手
开发语言·python·自然语言处理
kokunka34 分钟前
【源码+注释】纯C++小游戏开发之射击小球游戏
开发语言·c++·游戏
C雨后彩虹38 分钟前
CAS与其他并发方案的对比及面试常见问题
java·面试·cas·同步·异步·
云栖梦泽1 小时前
易语言开发从入门到精通:补充篇·网络编程进阶+实用爬虫开发·API集成·代理IP配置·异步请求·防封禁优化
开发语言
java1234_小锋2 小时前
Java高频面试题:SpringBoot为什么要禁止循环依赖?
java·开发语言·面试
铅笔侠_小龙虾2 小时前
Flutter Demo
开发语言·javascript·flutter
2501_944525542 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 账户详情页面
android·java·开发语言·前端·javascript·flutter
计算机学姐2 小时前
基于SpringBoot的电影点评交流平台【协同过滤推荐算法+数据可视化统计】
java·vue.js·spring boot·spring·信息可视化·echarts·推荐算法
福大大架构师每日一题2 小时前
ComfyUI v0.11.1正式发布:新增开发者专属节点支持、API节点强化、Python 3.14兼容性更新等全方位优化!
开发语言·python