最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中大量數(shù)據(jù)Excel導(dǎo)入導(dǎo)出的完整實(shí)現(xiàn)過程

 更新時(shí)間:2026年02月25日 08:32:04   作者:鳴潮牛逼  
Java實(shí)現(xiàn)Excel導(dǎo)入導(dǎo)出是Java開發(fā)中常見的任務(wù),主要用于數(shù)據(jù)的批量處理和分析,尤其在數(shù)據(jù)分析、報(bào)表生成和數(shù)據(jù)備份等方面具有廣泛應(yīng)用,這篇文章主要介紹了Java中大量數(shù)據(jù)Excel導(dǎo)入導(dǎo)出的完整實(shí)現(xiàn)過程,需要的朋友可以參考下

一、原理解析

1. Excel文件格式解析

  • XLS格式:基于二進(jìn)制格式,使用Apache POI的HSSF組件處理
  • XLSX格式:基于XML的壓縮格式,使用Apache POI的XSSF組件處理

2. 技術(shù)選型

  • Apache POI:最常用的Java Excel處理庫
  • EasyExcel:阿里巴巴開源,適合大數(shù)據(jù)量處理,內(nèi)存占用低
  • JExcelAPI:輕量級(jí),但功能較少

3. 大數(shù)據(jù)量處理策略

  • 流式讀取:逐行處理,避免內(nèi)存溢出
  • 分批次處理:分頁讀取,批量入庫
  • 異步處理:后臺(tái)線程處理,不阻塞主線程

二、實(shí)際應(yīng)用場景

1. 導(dǎo)入場景

  • 用戶數(shù)據(jù)批量導(dǎo)入
  • 產(chǎn)品目錄更新
  • 訂單數(shù)據(jù)同步
  • 財(cái)務(wù)報(bào)表導(dǎo)入

2. 導(dǎo)出場景

  • 數(shù)據(jù)報(bào)表生成
  • 數(shù)據(jù)備份
  • 數(shù)據(jù)交換
  • 批量打印

三、完整實(shí)現(xiàn)方案

項(xiàng)目結(jié)構(gòu)

excel-demo/
├── pom.xml
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── example/
│   │   │           ├── ExcelApplication.java
│   │   │           ├── controller/
│   │   │           │   └── ExcelController.java
│   │   │           ├── service/
│   │   │           │   ├── ExcelService.java
│   │   │           │   └── impl/
│   │   │           │       └── ExcelServiceImpl.java
│   │   │           ├── dao/
│   │   │           │   └── UserDao.java
│   │   │           ├── entity/
│   │   │           │   └── User.java
│   │   │           ├── dto/
│   │   │           │   ├── ExcelImportResult.java
│   │   │           │   └── ImportUserDTO.java
│   │   │           └── listener/
│   │   │               └── UserExcelListener.java
│   │   └── resources/
│   │       └── application.properties

1. Maven依賴 (pom.xml)

<?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.example</groupId>
    <artifactId>excel-demo</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.10</version>
    </parent>
    
    <properties>
        <java.version>1.8</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!-- Apache POI -->
        <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>
        
        <!-- EasyExcel -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.3.2</version>
        </dependency>
        
        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- MySQL -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        
        <!-- MyBatis Plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>
        
        <!-- 驗(yàn)證依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2. 實(shí)體類 (User.java)

package com.example.entity;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;

import java.util.Date;

@Data
@TableName("t_user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    
    @TableField("user_name")
    private String userName;
    
    @TableField("email")
    private String email;
    
    @TableField("phone")
    private String phone;
    
    @TableField("age")
    private Integer age;
    
    @TableField("department")
    private String department;
    
    @TableField("salary")
    private Double salary;
    
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private Date createTime;
    
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
}

3. 導(dǎo)入DTO (ImportUserDTO.java)

package com.example.dto;

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

import javax.validation.constraints.*;

@Data
public class ImportUserDTO {
    
    @ExcelProperty("用戶名")
    @NotBlank(message = "用戶名不能為空")
    @Size(min = 2, max = 20, message = "用戶名長度必須在2-20之間")
    private String userName;
    
    @ExcelProperty("郵箱")
    @NotBlank(message = "郵箱不能為空")
    @Email(message = "郵箱格式不正確")
    private String email;
    
    @ExcelProperty("手機(jī)號(hào)")
    @NotBlank(message = "手機(jī)號(hào)不能為空")
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手機(jī)號(hào)格式不正確")
    private String phone;
    
    @ExcelProperty("年齡")
    @NotNull(message = "年齡不能為空")
    @Min(value = 18, message = "年齡必須大于等于18歲")
    @Max(value = 65, message = "年齡必須小于等于65歲")
    private Integer age;
    
    @ExcelProperty("部門")
    @NotBlank(message = "部門不能為空")
    private String department;
    
    @ExcelProperty("薪資")
    @NotNull(message = "薪資不能為空")
    @DecimalMin(value = "0.0", message = "薪資必須大于等于0")
    private Double salary;
    
    // 行號(hào),用于錯(cuò)誤定位
    private Integer rowIndex;
    
    // 導(dǎo)入結(jié)果信息
    private String errorMsg;
    
    // 是否驗(yàn)證通過
    private Boolean valid = true;
}

4. 導(dǎo)入結(jié)果類 (ExcelImportResult.java)

package com.example.dto;

import lombok.Data;

import java.util.List;

@Data
public class ExcelImportResult<T> {
    // 成功數(shù)量
    private int successCount;
    
    // 失敗數(shù)量
    private int failCount;
    
    // 總數(shù)量
    private int totalCount;
    
    // 失敗數(shù)據(jù)列表
    private List<T> failDataList;
    
    // 錯(cuò)誤文件下載路徑
    private String errorFileUrl;
    
    // 導(dǎo)入耗時(shí)(毫秒)
    private Long costTime;
    
    // 錯(cuò)誤信息匯總
    private String errorSummary;
    
    public ExcelImportResult() {
        this.costTime = 0L;
    }
    
    public void calculate() {
        this.totalCount = successCount + failCount;
    }
}

5. Excel監(jiān)聽器 (UserExcelListener.java)

package com.example.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.example.dto.ImportUserDTO;
import com.example.service.ExcelService;
import lombok.extern.slf4j.Slf4j;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Slf4j
public class UserExcelListener implements ReadListener<ImportUserDTO> {
    
    // 每隔1000條存儲(chǔ)數(shù)據(jù)庫,然后清理list,方便內(nèi)存回收
    private static final int BATCH_COUNT = 1000;
    
    // 緩存的數(shù)據(jù)
    private List<ImportUserDTO> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
    
    private final ExcelService excelService;
    
    // 驗(yàn)證器
    private final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
    
    // 錯(cuò)誤數(shù)據(jù)列表
    private final List<ImportUserDTO> errorDataList = new ArrayList<>();
    
    // 成功計(jì)數(shù)
    private int successCount = 0;
    
    public UserExcelListener(ExcelService excelService) {
        this.excelService = excelService;
    }
    
    @Override
    public void invoke(ImportUserDTO data, AnalysisContext context) {
        // 設(shè)置行號(hào)(從0開始,通常第0行是標(biāo)題)
        Integer rowIndex = context.readRowHolder().getRowIndex() + 1;
        data.setRowIndex(rowIndex);
        
        // 數(shù)據(jù)驗(yàn)證
        validateData(data);
        
        if (data.getValid()) {
            cachedDataList.add(data);
            // 達(dá)到BATCH_COUNT,存儲(chǔ)一次數(shù)據(jù)庫
            if (cachedDataList.size() >= BATCH_COUNT) {
                saveData();
                cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
            }
        } else {
            errorDataList.add(data);
        }
    }
    
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 處理最后一批數(shù)據(jù)
        if (!cachedDataList.isEmpty()) {
            saveData();
        }
        log.info("Excel解析完成,成功導(dǎo)入{}條數(shù)據(jù),失敗{}條數(shù)據(jù)", 
                successCount, errorDataList.size());
    }
    
    private void validateData(ImportUserDTO data) {
        Set<ConstraintViolation<ImportUserDTO>> violations = validator.validate(data);
        if (!violations.isEmpty()) {
            data.setValid(false);
            StringBuilder errorMsg = new StringBuilder();
            for (ConstraintViolation<ImportUserDTO> violation : violations) {
                errorMsg.append(violation.getMessage()).append("; ");
            }
            data.setErrorMsg(errorMsg.toString());
        }
    }
    
    private void saveData() {
        try {
            // 批量保存數(shù)據(jù)
            int batchSuccessCount = excelService.batchSaveUsers(cachedDataList);
            successCount += batchSuccessCount;
            log.info("批量保存{}條數(shù)據(jù)成功", batchSuccessCount);
        } catch (Exception e) {
            log.error("批量保存數(shù)據(jù)失敗", e);
            // 記錄失敗的數(shù)據(jù)
            for (ImportUserDTO data : cachedDataList) {
                data.setValid(false);
                data.setErrorMsg("系統(tǒng)錯(cuò)誤: " + e.getMessage());
                errorDataList.add(data);
            }
        }
    }
    
    public List<ImportUserDTO> getErrorDataList() {
        return errorDataList;
    }
    
    public int getSuccessCount() {
        return successCount;
    }
}

6. Service層 (ExcelService.java & ExcelServiceImpl.java)

package com.example.service;

import com.example.dto.ExcelImportResult;
import com.example.dto.ImportUserDTO;
import com.example.entity.User;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

public interface ExcelService {
    
    /**
     * 導(dǎo)入用戶數(shù)據(jù)
     */
    ExcelImportResult<ImportUserDTO> importUsers(MultipartFile file);
    
    /**
     * 批量保存用戶
     */
    int batchSaveUsers(List<ImportUserDTO> userList);
    
    /**
     * 導(dǎo)出用戶數(shù)據(jù)
     */
    void exportUsers(HttpServletResponse response);
    
    /**
     * 導(dǎo)出錯(cuò)誤數(shù)據(jù)
     */
    void exportErrorData(List<ImportUserDTO> errorDataList, HttpServletResponse response);
}
package com.example.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.example.dao.UserDao;
import com.example.dto.ExcelImportResult;
import com.example.dto.ImportUserDTO;
import com.example.entity.User;
import com.example.listener.UserExcelListener;
import com.example.service.ExcelService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;

@Service
@Slf4j
public class ExcelServiceImpl implements ExcelService {
    
    @Autowired
    private UserDao userDao;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ExcelImportResult<ImportUserDTO> importUsers(MultipartFile file) {
        long startTime = System.currentTimeMillis();
        ExcelImportResult<ImportUserDTO> result = new ExcelImportResult<>();
        
        try {
            // 創(chuàng)建監(jiān)聽器
            UserExcelListener listener = new UserExcelListener(this);
            
            // 讀取Excel
            EasyExcel.read(file.getInputStream(), ImportUserDTO.class, listener)
                    .sheet()
                    .headRowNumber(1) // 跳過標(biāo)題行
                    .doRead();
            
            // 設(shè)置結(jié)果
            result.setSuccessCount(listener.getSuccessCount());
            result.setFailCount(listener.getErrorDataList().size());
            result.setFailDataList(listener.getErrorDataList());
            result.calculate();
            
            // 如果有錯(cuò)誤數(shù)據(jù),生成錯(cuò)誤報(bào)告
            if (!listener.getErrorDataList().isEmpty()) {
                String errorSummary = generateErrorSummary(listener.getErrorDataList());
                result.setErrorSummary(errorSummary);
            }
            
        } catch (IOException e) {
            log.error("讀取Excel文件失敗", e);
            result.setErrorSummary("文件讀取失敗: " + e.getMessage());
        }
        
        long endTime = System.currentTimeMillis();
        result.setCostTime(endTime - startTime);
        
        return result;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchSaveUsers(List<ImportUserDTO> userList) {
        if (userList == null || userList.isEmpty()) {
            return 0;
        }
        
        List<User> users = new ArrayList<>();
        for (ImportUserDTO dto : userList) {
            User user = new User();
            BeanUtils.copyProperties(dto, user);
            user.setCreateTime(new Date());
            user.setUpdateTime(new Date());
            users.add(user);
        }
        
        // 批量插入
        int count = userDao.batchInsert(users);
        log.info("批量插入{}條用戶數(shù)據(jù)", count);
        return count;
    }
    
    @Override
    public void exportUsers(HttpServletResponse response) {
        try {
            // 查詢數(shù)據(jù)
            List<User> userList = userDao.selectList(new QueryWrapper<>());
            
            // 轉(zhuǎn)換為DTO
            List<ImportUserDTO> exportData = new ArrayList<>();
            for (User user : userList) {
                ImportUserDTO dto = new ImportUserDTO();
                BeanUtils.copyProperties(user, dto);
                exportData.add(dto);
            }
            
            // 設(shè)置響應(yīng)頭
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("用戶數(shù)據(jù)導(dǎo)出", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            
            // 寫入Excel
            EasyExcel.write(response.getOutputStream(), ImportUserDTO.class)
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 自動(dòng)列寬
                    .sheet("用戶數(shù)據(jù)")
                    .doWrite(exportData);
                    
        } catch (IOException e) {
            log.error("導(dǎo)出Excel失敗", e);
            throw new RuntimeException("導(dǎo)出失敗");
        }
    }
    
    @Override
    public void exportErrorData(List<ImportUserDTO> errorDataList, HttpServletResponse response) {
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("導(dǎo)入錯(cuò)誤數(shù)據(jù)", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            
            EasyExcel.write(response.getOutputStream(), ImportUserDTO.class)
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                    .sheet("錯(cuò)誤數(shù)據(jù)")
                    .doWrite(errorDataList);
                    
        } catch (IOException e) {
            log.error("導(dǎo)出錯(cuò)誤數(shù)據(jù)失敗", e);
            throw new RuntimeException("導(dǎo)出失敗");
        }
    }
    
    /**
     * 異步導(dǎo)入方法
     */
    @Async
    public CompletableFuture<ExcelImportResult<ImportUserDTO>> importUsersAsync(MultipartFile file) {
        return CompletableFuture.completedFuture(importUsers(file));
    }
    
    private String generateErrorSummary(List<ImportUserDTO> errorDataList) {
        StringBuilder summary = new StringBuilder();
        summary.append("共發(fā)現(xiàn)").append(errorDataList.size()).append("條錯(cuò)誤數(shù)據(jù):\n");
        
        for (ImportUserDTO data : errorDataList) {
            summary.append("第").append(data.getRowIndex())
                   .append("行: ").append(data.getErrorMsg()).append("\n");
        }
        
        return summary.toString();
    }
}

7. DAO層 (UserDao.java)

package com.example.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

@Mapper
public interface UserDao extends BaseMapper<User> {
    
    /**
     * 批量插入用戶
     */
    @Insert({
        "<script>",
        "INSERT INTO t_user(user_name, email, phone, age, department, salary, create_time, update_time) VALUES ",
        "<foreach collection='list' item='item' separator=','>",
        "(#{item.userName}, #{item.email}, #{item.phone}, #{item.age}, ",
        "#{item.department}, #{item.salary}, #{item.createTime}, #{item.updateTime})",
        "</foreach>",
        "</script>"
    })
    int batchInsert(@Param("list") List<User> userList);
}

8. Controller層 (ExcelController.java)

package com.example.controller;

import com.example.dto.ExcelImportResult;
import com.example.dto.ImportUserDTO;
import com.example.service.ExcelService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/excel")
@Api(tags = "Excel導(dǎo)入導(dǎo)出管理")
@Slf4j
public class ExcelController {
    
    @Autowired
    private ExcelService excelService;
    
    @PostMapping("/import/users")
    @ApiOperation("導(dǎo)入用戶數(shù)據(jù)")
    public ResponseEntity<Map<String, Object>> importUsers(
            @RequestParam("file") MultipartFile file) {
        
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 檢查文件
            if (file.isEmpty()) {
                result.put("code", 400);
                result.put("message", "文件不能為空");
                return ResponseEntity.badRequest().body(result);
            }
            
            // 檢查文件類型
            String fileName = file.getOriginalFilename();
            if (fileName == null || 
                (!fileName.toLowerCase().endsWith(".xls") && 
                 !fileName.toLowerCase().endsWith(".xlsx"))) {
                result.put("code", 400);
                result.put("message", "只支持Excel文件");
                return ResponseEntity.badRequest().body(result);
            }
            
            // 執(zhí)行導(dǎo)入
            ExcelImportResult<ImportUserDTO> importResult = excelService.importUsers(file);
            
            result.put("code", 200);
            result.put("message", "導(dǎo)入完成");
            result.put("data", importResult);
            
            return ResponseEntity.ok(result);
            
        } catch (Exception e) {
            log.error("導(dǎo)入用戶數(shù)據(jù)失敗", e);
            result.put("code", 500);
            result.put("message", "導(dǎo)入失敗: " + e.getMessage());
            return ResponseEntity.internalServerError().body(result);
        }
    }
    
    @GetMapping("/export/users")
    @ApiOperation("導(dǎo)出用戶數(shù)據(jù)")
    public void exportUsers(HttpServletResponse response) {
        try {
            excelService.exportUsers(response);
        } catch (Exception e) {
            log.error("導(dǎo)出用戶數(shù)據(jù)失敗", e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }
    
    @PostMapping("/export/errors")
    @ApiOperation("導(dǎo)出錯(cuò)誤數(shù)據(jù)")
    public void exportErrorData(
            @RequestBody ExcelImportResult<ImportUserDTO> importResult,
            HttpServletResponse response) {
        try {
            excelService.exportErrorData(importResult.getFailDataList(), response);
        } catch (Exception e) {
            log.error("導(dǎo)出錯(cuò)誤數(shù)據(jù)失敗", e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }
    
    @GetMapping("/template/download")
    @ApiOperation("下載導(dǎo)入模板")
    public void downloadTemplate(HttpServletResponse response) {
        try {
            // 這里可以提供一個(gè)空模板或者帶說明的模板
            excelService.exportUsers(response); // 暫時(shí)用導(dǎo)出方法,實(shí)際應(yīng)創(chuàng)建專門的模板
        } catch (Exception e) {
            log.error("下載模板失敗", e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }
}

9. 啟動(dòng)類 (ExcelApplication.java)

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync
public class ExcelApplication {
    public static void main(String[] args) {
        SpringApplication.run(ExcelApplication.class, args);
    }
}

10. 配置文件 (application.properties)

# 服務(wù)器配置
server.port=8080
server.servlet.context-path=/excel-demo

# 數(shù)據(jù)庫配置
spring.datasource.url=jdbc:mysql://localhost:3306/excel_demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# MyBatis配置
mybatis-plus.mapper-locations=classpath*:/mapper/**/*.xml
mybatis-plus.type-aliases-package=com.example.entity
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

# 上傳文件大小限制
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=100MB

# 異步線程池配置
spring.task.execution.pool.core-size=10
spring.task.execution.pool.max-size=20
spring.task.execution.pool.queue-capacity=500
spring.task.execution.thread-name-prefix=excel-async-

# 日志配置
logging.level.com.example=DEBUG

11. SQL建表語句

-- 創(chuàng)建數(shù)據(jù)庫
CREATE DATABASE IF NOT EXISTS excel_demo DEFAULT CHARACTER SET utf8mb4;

USE excel_demo;

-- 用戶表
CREATE TABLE IF NOT EXISTS t_user (
    id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主鍵ID',
    user_name VARCHAR(50) NOT NULL COMMENT '用戶名',
    email VARCHAR(100) NOT NULL COMMENT '郵箱',
    phone VARCHAR(20) NOT NULL COMMENT '手機(jī)號(hào)',
    age INT COMMENT '年齡',
    department VARCHAR(100) COMMENT '部門',
    salary DECIMAL(10,2) COMMENT '薪資',
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',
    update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時(shí)間',
    INDEX idx_user_name (user_name),
    INDEX idx_email (email),
    INDEX idx_create_time (create_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用戶表';

-- 導(dǎo)入日志表(可選)
CREATE TABLE IF NOT EXISTS t_import_log (
    id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主鍵ID',
    file_name VARCHAR(255) COMMENT '文件名',
    file_size BIGINT COMMENT '文件大小',
    total_count INT COMMENT '總記錄數(shù)',
    success_count INT COMMENT '成功數(shù)',
    fail_count INT COMMENT '失敗數(shù)',
    import_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '導(dǎo)入時(shí)間',
    operator VARCHAR(50) COMMENT '操作人',
    status TINYINT DEFAULT 1 COMMENT '狀態(tài):1-成功,0-失敗',
    error_message TEXT COMMENT '錯(cuò)誤信息'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='導(dǎo)入日志表';

四、使用示例

1. 啟動(dòng)應(yīng)用

mvn spring-boot:run

2. 導(dǎo)入Excel

  • 使用Postman或前端上傳Excel文件
  • 文件格式要求:包含userName, email, phone, age, department, salary列
  • 接口地址:POST http://localhost:8080/excel-demo/api/excel/import/users

3. 導(dǎo)出Excel

  • 接口地址:GET http://localhost:8080/excel-demo/api/excel/export/users

五、優(yōu)化建議

1. 性能優(yōu)化

  • 使用數(shù)據(jù)庫連接池
  • 調(diào)整批量提交大小
  • 使用多線程并行處理
  • 添加Redis緩存

2. 功能增強(qiáng)

  • 支持多種Excel格式
  • 添加數(shù)據(jù)清洗功能
  • 支持模板自定義
  • 添加導(dǎo)入進(jìn)度查詢

3. 安全性考慮

  • 文件類型驗(yàn)證
  • 文件大小限制
  • 病毒掃描
  • 訪問權(quán)限控制

六、注意事項(xiàng)

  1. 內(nèi)存管理:大數(shù)據(jù)量導(dǎo)入時(shí),注意JVM內(nèi)存設(shè)置
  2. 事務(wù)控制:批量導(dǎo)入要考慮事務(wù)邊界
  3. 異常處理:完善的異常處理和日志記錄
  4. 數(shù)據(jù)驗(yàn)證:前端和后端雙重驗(yàn)證
  5. 用戶體驗(yàn):提供進(jìn)度反饋和錯(cuò)誤報(bào)告

到此這篇關(guān)于Java中大量數(shù)據(jù)Excel導(dǎo)入導(dǎo)出的文章就介紹到這了,更多相關(guān)Java大量數(shù)據(jù)Excel導(dǎo)入導(dǎo)出內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

乌拉特中旗| 略阳县| 屯门区| 饶阳县| 日喀则市| 北辰区| 抚顺县| 南靖县| 湟中县| 抚州市| 邹平县| 昌吉市| 桂林市| 新密市| 阜宁县| 葵青区| 武城县| 龙南县| 黄骅市| 阳山县| 山阴县| 西平县| 静乐县| 竹溪县| 宜君县| 鄱阳县| 河北区| 宿州市| 华宁县| 邵东县| 岗巴县| 禄劝| 巩义市| 洛川县| 陵川县| 霍山县| 罗定市| 潼关县| 西乌珠穆沁旗| 历史| 兖州市|