[PHP Excel] PHP - Một vài notes khi làm việc với excel,csv file

Tổng hợp lại một số libraries và kinh nghiệm khi làm việc với excel, csv file nào!

1. Some libraries

1.1. PhpSpreadsheet

PhpSpreadsheet is a library written in pure PHP and providing a set of classes that allow you to read from and to write to different spreadsheet file formats, like Excel and LibreOffice Calc.

  • Library này hỗ trợ file đa dạng
  • Cung cấp khả năng load file mẫu, điền dữ liệu bằng cách fill dữ liệu vào các cell khá đơn giản

1.2. Maatwebsite/excel

  • Link github: https://github.com/Maatwebsite/Laravel-Excel
  • Package chuyên về xử lý file excel và CSV
  • Hỗ trợ import, export dưới dữ liệu collection, array, blade view (hãy nhớ blade view là dưới dạng bảng nhé)
  • Chưa biết các export file từ file template (chắc có đó)
  • Định dạng các cột, hàng theo ý và có thể mở rộng các phương thức dưới dạng marco (không phải script marco trong file excel nhé mà là khả năng mở rộng phương thức): https://docs.laravel-excel.com/3.1/exports/extending.html

2. Download stream file CSV, Excel

  • Nếu bạn làm việc và cần export file CSV với rất nhiều dữ liệu (có thể lớn hơn 100k bản ghi). Hãy xem xét cách tạo stream để download file (không cần package nào nhé :D)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    <?php
    use Symfony\Component\HttpFoundation\StreamedResponse;

    Route::get('export', function(){
    $response = new StreamedResponse(function(){
    // Open output stream
    $handle = fopen('php://output', 'w');

    // Add CSV headers
    fputcsv($handle, [
    'id',
    'name',
    'email'
    ]);

    // Get all users
    foreach (User::all() as $user) {
    // Add a new row with data
    fputcsv($handle, [
    $user->id,
    $user->name,
    $user->email
    ]);
    }

    // Close the output stream
    fclose($handle);
    }, 200, [
    'Content-Type' => 'text/csv',
    'Content-Disposition' => 'attachment; filename="export.csv"',
    ]);

    return $response;
    });
    ?>
    Nguồn: https://medium.com/@barryvdh/streaming-large-csv-files-with-laravel-chunked-queries-4158e484a5a2

Note: Có thể kết hợp với chunk để làm việc hiệu quả hơn :D

3. Download file dưới dạng AJAX

Đôi khi để làm cho ứng dụng trở bên trải nghiệm tốt hơn, sẽ hiện loading khi download file. Lúc đó bạn cần sử dụng AJAX để thực hiện download file.

Ý tưởng sẽ là như sau:

  • PHP sẽ vẫn trả về dữ liệu file download dưới dạng stream như trên (vẫn set header là file csv như phần 2)
  • Bên Javascript gọi AJAX và sẽ nhận được file này dưới dạng nhị phân. Sau đó nó tạo một đối tượng với tên là Blob, tạo thẻ a để click download file và sau đó xóa nó đi
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Download POST Request</title>
    </head>
    <body>
    Enter a text and click the button: <input type="text" id="content" value="Text for the generated pdf">
    <button id="download">Send AJAX Request and download file</button>

    <script>
    document.getElementById('download').addEventListener('click', function () {
    var content = document.getElementById('content').value;
    var request = new XMLHttpRequest();
    request.open('POST', '../server/', true);
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    request.responseType = 'blob';

    request.onload = function() {
    // Only handle status code 200
    if(request.status === 200) {
    // Try to find out the filename from the content disposition `filename` value
    var disposition = request.getResponseHeader('content-disposition');
    var matches = /"([^"]*)"/.exec(disposition);
    var filename = (matches != null && matches[1] ? matches[1] : 'file.pdf');

    // The actual download
    var blob = new Blob([request.response], { type: 'application/pdf' });
    var link = document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    link.download = filename;

    document.body.appendChild(link);

    link.click();

    document.body.removeChild(link);
    }

    // some error handling should be done here...
    };

    request.send('content=' + content);
    });
    </script>
    </body>
    </html>

    Trong lúc gọi AJAX đó có thể thêm các ảnh gif loading cho ứng dụng của bạn tốt hơn, và khi download xong, tắt nó đi. Thật tuyệt vời phải không nào :D

Nguồn: https://nehalist.io/downloading-files-from-post-requests/

4. Macro trong file .xlsm

  • Nếu file excel của bạn có kèm macro, hãy load nó và lưu nó dưới dạng .xlsm
  • Marco gán cho 1 ảnh thì sau khi export sẽ không được tự động gán (nguyên nhân chưa rõ). Do đó không nên để macro gán cho 1 ảnh, thay vào đó hãy để ảnh đó là 1 cái button thì sẽ hoạt động @@

[PHP Excel] PHP - Một vài notes khi làm việc với excel,csv file

http://yoursite.com/2019/12/29/PHP-Excel-PHP-Mot-vai-notes-khi-lam-viec-voi-excel-csv-file/

Author

Ming

Posted on

2019-12-29

Updated on

2021-04-10

Licensed under

Comments