Xử lý Nhập Xuất Excel Nhiều Sheet Dễ Dàng Bằng EasyPoi

Trong quá trình phát triển ứng dụng Java, việc xử lý các file Excel thường yêu cầu nhiều mã nguồn boilerplate nếu sử dụng Apache POI thuần túy. EasyPoi ra đời nhằm giải quyết vấn đề này thông qua cơ chế annotation, giúp việc đọc và ghi dữ liệu trở nên ngắn gọn và dễ bảo trì hơn, đặc biệt là khi làm việc với nhiều sheet trong cùng một file.

1. Cấu hình thư viện

Đầu tiên, cần thêm dependency của EasyPoi vào file cấu hình dự án. Phiên bản ổn định thường được sử dụng là 4.2.0 trở lên.

<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-spring-boot-starter</artifactId>
    <version>4.2.0</version>
</dependency>

2. Định nghĩa Entity映射

Sử dụng annotation @Excel để đánh dấu các trường trong class Java tương ứng với cột trong Excel. Dưới đây là ví dụ về hai class dùng để lưu trữ dữ liệu kịch bản kiểm thử và cấu hình đường dẫn.

@Data
public class TestScenarioRecord {
    @Excel(name = "Hướng kiểm tra (0: Ngược, 1: Xuôi)", orderNum = "1", width = 20)
    private String directionFlag;
    
    @Excel(name = "ID phiên truy cập", orderNum = "2", width = 20)
    private String accessId;
    
    @Excel(name = "Tài khoản đăng nhập", orderNum = "3", width = 20)
    private String username;
    
    @Excel(name = "Mật khẩu", orderNum = "4", width = 20)
    private String password;
    
    @Excel(name = "Thông báo mong đợi", orderNum = "5", width = 40)
    private String expectedMessage;
    
    @Excel(name = "Kết quả thực tế", orderNum = "6", width = 40)
    private String actualResult;
    
    @Excel(name = "Đường dẫn API", orderNum = "7", width = 40)
    private String apiPath;
}
@Data
public class ApiEndpointInfo {
    @Excel(name = "Mã định danh", orderNum = "1", width = 20)
    private String configId;
    
    @Excel(name = "Phương thức请求", orderNum = "2", width = 20)
    private String requestType;
    
    @Excel(name = "Địa chỉ URL", orderNum = "3", width = 40)
    private String targetUrl;
}

3. Triển khai Utility nhập dữ liệu

Để hỗ trợ đọc dữ liệu từ nhiều sheet, cần cấu hình đối tượng ImportParams. Phương thức dưới đây cho phép chỉ định index của sheet cần đọc cùng với số dòng tiêu đề.

public class ExcelHandlerUtil {

    /**
     * Đọc dữ liệu từ file Excel dựa trên index của sheet
     * @param fileSource File Excel đầu vào
     * @param sheetIndex Vị trí sheet cần đọc
     * @param titleRow Số dòng tiêu đề lớn
     * @param headerRow Số dòng header cột
     * @param clazz Class entity映射
     * @return Danh sách đối tượng dữ liệu
     */
    public static <T> List<T> loadSheetData(File fileSource, int sheetIndex, 
                                             int titleRow, int headerRow, Class<T> clazz) {
        ImportParams importConfig = new ImportParams();
        importConfig.setStartSheetIndex(sheetIndex);
        importConfig.setTitleRows(titleRow);
        importConfig.setHeadRows(headerRow);
        
        List<T> resultData = null;
        try {
            resultData = ExcelImportUtil.importExcel(fileSource, clazz, importConfig);
        } catch (NoSuchElementException ex) {
            throw new RuntimeException("File Excel không hợp lệ hoặc không tìm thấy sheet");
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException("Có lỗi xảy ra trong quá trình đọc Excel");
        }
        return resultData;
    }
}

4. Triển khai Utility xuất nhiều sheet

Việc xuất file nhiều sheet đòi hỏi việc đóng gói dữ liệu vào các Map riêng biệt cho từng sheet, sau đó gộp vào một danh sách để EasyPoi xử lý. Phương thức sau sẽ tạo ra file Excel chứa nhiều sheet dựa trên danh sách dữ liệu đầu vào.

public static String writeMultiSheetExcel(List<?> scenarioData, List<?> endpointData) {
    Workbook workbook = null;
    try {
        // Cấu hình cho Sheet 1
        ExportParams sheet1Config = new ExportParams();
        sheet1Config.setSheetName("Kịch bản kiểm thử");
        sheet1Config.setTitle("Báo cáo kết quả Login");
        
        Map<String, Object> sheet1Map = new HashMap<>();
        sheet1Map.put("title", sheet1Config);
        sheet1Map.put("entity", TestScenarioRecord.class);
        sheet1Map.put("data", scenarioData);

        // Cấu hình cho Sheet 2
        ExportParams sheet2Config = new ExportParams();
        sheet2Config.setSheetName("Cấu hình URL");
        sheet2Config.setTitle("Danh sách API");
        
        Map<String, Object> sheet2Map = new HashMap<>();
        sheet2Map.put("title", sheet2Config);
        sheet2Map.put("entity", ApiEndpointInfo.class);
        sheet2Map.put("data", endpointData);

        // Tổng hợp các sheet
        List<Map<String, Object>> sheetsCollection = new ArrayList<>();
        sheetsCollection.add(sheet1Map);
        sheetsCollection.add(sheet2Map);

        // Tạo workbook
        workbook = ExcelExportUtil.exportExcel(sheetsCollection, ExcelType.HSSF);
        
        // Ghi file ra disk
        String outputPath = System.getProperty("user.dir") + "/output/result_test.xlsx";
        FileOutputStream fos = new FileOutputStream(outputPath);
        workbook.write(fos);
        fos.close();
        
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (workbook != null) {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return "Hoàn tất xuất file";
}

Với cách tổ chức mã nguồn như trên, việc quản lý các file Excel phức tạp nhiều sheet trở nên linh hoạt hơn, dễ dàng mở rộng khi cần thêm các loại dữ liệu khác vào các sheet mới mà không cần thay đổi nhiều logic xử lý cốt lõi.

Thẻ: easypoi java-excel spring-boot-starter multi-sheet-export data-import

Đăng vào ngày 17 tháng 05 lúc 20:24