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";
        }
    }

}
相关推荐
虫小宝1 小时前
企业微信API接口的Java SDK封装:可复用、可测试的工具类设计方法
java·开发语言·企业微信
路多辛2 小时前
JSONC-带注释的 JSON 详解
开发语言·json
阳光九叶草LXGZXJ2 小时前
达梦数据库-学习-43-定时备份模式和删除备份(Python+Crontab)
linux·运维·开发语言·数据库·python·学习
Grassto2 小时前
9 Go Module 依赖图是如何构建的?源码解析
开发语言·后端·golang·go module
软件开发技术深度爱好者2 小时前
JavaScript的p5.js库使用详解(上)
开发语言·javascript
独自破碎E2 小时前
包含min函数的栈
android·java·开发语言·leetcode
沛沛老爹2 小时前
基于Spring Retry实现的退避重试机制
java·开发语言·后端·spring·架构
wregjru2 小时前
【C++】2.9异常处理
开发语言·c++·算法
古城小栈2 小时前
Rust unsafe 一文全功能解析
开发语言·后端·rust