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

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

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

一、原理解析

1. Excel文件格式解析

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

2. 技術(shù)選型

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

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

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

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

1. 導(dǎo)入場(chǎng)景

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

2. 導(dǎo)出場(chǎng)景

  • 數(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í)體類(lèi) (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 = "用戶名長(zhǎng)度必須在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("部門(mén)")
    @NotBlank(message = "部門(mén)不能為空")
    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)證通過(guò)
    private Boolean valid = true;
}

4. 導(dǎo)入結(jié)果類(lèi) (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)聽(tīng)器 (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ù)庫(kù),然后清理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開(kāi)始,通常第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ù)庫(kù)
            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)聽(tīng)器
            UserExcelListener listener = new UserExcelListener(this);
            
            // 讀取Excel
            EasyExcel.read(file.getInputStream(), ImportUserDTO.class, listener)
                    .sheet()
                    .headRowNumber(1) // 跳過(guò)標(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");
            
            // 寫(xiě)入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);
            }
            
            // 檢查文件類(lèi)型
            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è)空模板或者帶說(shuō)明的模板
            excelService.exportUsers(response); // 暫時(shí)用導(dǎo)出方法,實(shí)際應(yīng)創(chuàng)建專(zhuān)門(mén)的模板
        } catch (Exception e) {
            log.error("下載模板失敗", e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }
}

9. 啟動(dòng)類(lèi) (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ù)庫(kù)配置
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建表語(yǔ)句

-- 創(chuàng)建數(shù)據(jù)庫(kù)
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 '部門(mén)',
    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ù)庫(kù)連接池
  • 調(diào)整批量提交大小
  • 使用多線程并行處理
  • 添加Redis緩存

2. 功能增強(qiáng)

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

3. 安全性考慮

  • 文件類(lèi)型驗(yàn)證
  • 文件大小限制
  • 病毒掃描
  • 訪問(wè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)論

湛江市| 会同县| 罗定市| 西盟| 黄大仙区| 疏勒县| 斗六市| 左权县| 阿坝县| 忻州市| 隆安县| 资源县| 泰安市| 舟曲县| 徐州市| 永泰县| 嘉兴市| 随州市| 双流县| 光泽县| 舞阳县| 靖江市| 灯塔市| 乌拉特前旗| 贵德县| 昭苏县| 永修县| 康马县| 灵宝市| 阿城市| 外汇| 石阡县| 扬州市| 阿拉尔市| 鱼台县| 莆田市| 上思县| 东乡| 夏邑县| 景泰县| 遂溪县|