[JAVA - Excel] Tăng hiệu suất x lần import/export với cách truyền thống: CỰU CHIẾN BINH ĐI QUA GIÔNG BÃO CÔNG NGHỆ

Nội dung bài viết

Video học lập trình mỗi ngày

Đầu tiên chúng ta sẽ xem những trường hợp sau của các anh em trong nhóm Link Discords thảo luận:

Tiếp, xem tụi nó bắt đầu combat trong đó tui cũng chém cho lên TAY :v

OK xem như đã nắm được kịch bản với 1.000.000 rows và khoảng 50M. Bắt tay vào..

Cải thiện hiếu suất export và import trong excel

Ngôn ngữ nào ví dụ như JAVA, GO, NODEJS, NESTJS cũng có thể giải quyết bài toán export và import trong excel. Quan trọng là giải quyết vấn đề, bạn dùng gạch hay đá cũng có thể xấy được nhà. Quan trọng là phù hợp nhất với tình huống đó.

Ở đây tôi sẽ cải thiện hiệu suất với ngôn ngữ JAVA, vì sao JAVA lại tốt cho hoàn cảnh này. Vì Multiple Thread. Nếu anh em chưa cảm nhận được sức mạnh của nó thì tôi có một series Multiple Thread - Từ Thread, ThreadPool, ThreadLocal và đến TRÙM Virtual Thread lịch sử như thế nào hãy ghé nó nếu bạn có thời gian.

NHIỆM VỤ CHÍNH đó là chúng ta phải cải thiện từ 2 phút theo cách thông thường, chúng ta phải giảm xuống 10 seconds, sau đó sẽ cải thiện tiếp theo cho từng version.

Chú ý: Không có version nào tốt, chỉ có version này tốt hơn trước mà thôi...

Chuẩn bị export và import trong excel

Để kịch bản đúng như thực tế thì tôi đã tạo sẵn bạn không cần làm gì chỉ cần lấy [Source Excel JAVA] về trong đó có một file user.xlsx với 1.000.000 rows và ~50Mb.

Sau đó TỐT NHẤT hãy tự code và hiểu từng quy trình thực tế của khách hàng như thế nào. Ví dụ, đề cho phép khách hàng download/export về bạn viết cho tôi một func như sau:

public void exportUserFile(HttpServletResponse response) throws IOException {
    log.info("func-> exportUserFile ");
    InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("templates/user.xlsx");
    response.setHeader("Content-disposition", "attachment;fileName=user.xlsx");
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
    OutputStream outputStream = response.getOutputStream();
    byte[] bytes = new byte[2048];
    int len;
    while((len = inputStream.read(bytes)) != -1){ //Đọc dữ liệu vào buffer, trả về số byte đọc được (hoặc -1 nếu hết file)

        outputStream.write(bytes,0,len);
    }
    // push and send for client
    outputStream.flush();
    // CHÚ Ys Anh em nhớ đóng khi done, chứ để mất memory của hệt hống..
    outputStream.close();
    inputStream.close();
}

Bạn không cần đọc nhiều, chỉ cần đọc những comment là ở đó đa số là những line quan trọng. Và kết quả nó như thế này -> nghĩa là client có thể tải về cho việc (import/export) cho một chương trình.

Về domain/entity thì như sau:

@Data
@ColumnWidth(30) // length column
public class User {

    @ExcelProperty("id") // map header
    private Integer id;
    @ExcelProperty("usr_name")
    private String usr_name;
    @ExcelProperty("usr_phone")
    private String usr_phone;
    @ExcelProperty("usr_address")
    private String usr_address;
}

Rất đơn giản đúng không, ngoài ra vì sao tôi lại sử dụng Mybatis-Plus vì đây cũng là một phần quan trọng không kém để hỗ trợ cải thiện hiệu suất khi đưa vào triển khai. Tôi đã có một bài viết nói về Nếu bạn chưa biết tí gì về Mybatis-Plus bài viết này của bạn, nó rấy đầy đủ

Export và import trong excel - Bạn sẽ gặp những điều gì trước tiên.

Một lập trình viên nên hiểu về bản chất vấn đề trước khi giải quyết nó. Vậy vấn đề ở đây mà tôi đã gặp, không biết bạn còn những vấn đề gì nữa không có thể comment thêm:

  1. Data mà lớn thì việc tôi thấy rõ nhất đó là Export và import gây tràn memmory, kém hiệu quả.

  2. Khi Export qua file excel chúng ta không thể làm việc với từng row như cách thông thường loop... Bỏ đi/.

  3. Tương tự khi import thì cũng không thể từng row được, đừng sử dụng cách index loop.

  4. Nếu bạn dùng JPA hay Mybatis để hoạt động với batch thì cũng không ăn thua.

  5. Hãy xem xét xls, hay là xlsx. Và một Sheet hay nhiều Sheet? câu này tôi để cho các bạn hỏi AI...

  6. Dữ liệu 1 triệu trong data mà bạn chơi kiểu select * from user thì thế này là dở rồi.

Hãy xem tôi lấy dữ liệu từng LÔ trong 13 triệu MYSQL nhanh như chớp, bất kể sử dụng LIMIT. Bạn xem bài này: TRUY VẤN MYSQL SỬ DỤNG LIMIT VỚI HÀNG CHỤC TRIỆU DỮ LIỆU TỪ 7S còn 1S

Tiếp là, tôi sẽ lên phương án giải quyết chúng...

Nếu bạn không muốn code vì level đã đủ để đọc code thì có thể lấy code tại đây, đương nhiên đây mới là sự chuẩn bị.

TUY NHIÊN đây là bước khởi đầu. Hãy chuẩn bị. Tiến lên... CHƠI KHÔNG HỐI THÚC NHA ANH EM.

Bài post giới thiệu, tôi sẽ push code lên sau, anh em sẽ được thông báo SỚM. thx...

Có thể bạn đã bị missing