1. Vấn đề
2. Giải pháp
2.1 Lavel Excel
2.2 Bài toán đặt ra
Mình đang cần xuất 1 bản excel các đơn hàng và merge cột order_id đối với những dòng có trùng order_id
Đây là mảng orders của mình:
Array (
[0] => Array
(
[order_id] => 1374282003
[status] => 1
[mark] => Casio
[model] => W-81
[price] => 10.00
)
[1] => Array
(
[order_id] => 1374282003
[status] => 1
[mark] => Casio
[model] => W-81
[price] => 10.00
)
[2] => Array
(
[order_id] => 1374282573
[status] => 1
[mark] => Casio
[model] => W-81
[price] => 10.00
)
[3] => Array
(
[order_id] => 1374282573
[status] => 1
[mark] => Casio
[model] => W-81
[price] => 10.00
)
[4] => Array
(
[order_id] => 1374282573
[status] => 1
[mark] => Casio
[model] => W-81
[price] => 10.00
)
)
Đây là mong muốn phần excel được in ra dưới dạng như này mình sẽ - "trình bày dưới dạng html"
<table>
<tr>
<td>Order</td>
<td>Product</td>
<td>Price</td>
<td>Status</td>
</tr>
<tr>
<td rowspan="2">1374282003</td>
<td>Casio</td>
<td>10</td>
<td>1</td>
</tr>
<tr>
<td>Casio</td>
<td>10</td>
<td>1</td>
</tr>
<tr>
<td rowspan="3">1374282573</td>
<td>Casio</td>
<td>10</td>
<td>1</td>
</tr>
<tr>
<td>Casio</td>
<td>10</td>
<td>1</td>
</tr>
<tr>
<td>Casio</td>
<td>10</td>
<td>1</td>
</tr>
</table>
2.3 Code như thế nào?
Oke! chúng ta có lẽ đến phần này là hiểu vấn đề bài toán cần làm gì rồi. Giờ bắt tay vào code thôi, Let's do it!
Đầu tiên ta cần khai báo 1 mảng rỗng mới, mục đích chính việc này là ta sẽ gom nhóm các phần tử trùng order_id vào mảng mới này đồng thời đếm được số phần tử trùng order_id luôn. Số đếm được ta sẽ đặt là biến $rowspan và chỉ gán vào phần tử đầu tiên của mảng mới là thôi. Oke mình giải thích ở trên có thể sẽ khiến nhiều bạn chưa hình dùng ra được nên mình sẽ để code ở dưới để các bạn có thể hiểu rõ ý mình hơn.
$orders = [
0 => [
'order_id'=> '1374282003',
'status'=> 1,
'mark'=> 'Casio',
'model'=> 'W-81',
'price'=> 10.00,
],
1=> [
'order_id'=> '1374282003',
'status'=> 1,
'mark'=> 'Casio',
'model'=> 'W-81',
'price'=> 10.00,
],
2=> [
'order_id'=> '1374282573',
'status'=> 1,
'mark'=> 'Casio',
'model'=> 'W-81',
'price'=> '10.00',
],
3=> [
'order_id'=> '1374282573',
'status'=> 1,
'mark'=> 'Casio',
'model'=> 'W-81',
'price'=> 10.00,
],
4=> [
'order_id'=> '1374282573',
'status'=> 1,
'mark'=> 'Casio',
'model'=> 'W-81',
'price'=> 10.00,
],
];
$periods = [];
// handle rowspan
foreach($orders as $key => $period) {
$data = $period->toArray();
$data['rowspan'] = empty($data['order_id']) ? 1 : 0;
$periods[$data['order_id']][] = $data;
if (!empty($data['order_id'])) {
$periods[$data['order_id']][0]['rowspan'] = count($periods[$data['order_id']]);
}
}
Bạn thấy đó code phía bên trên không hề có thuật toán phức tạp nào cả, cũng không cao siêu gì. Mọi thứ đều rất cơ bản Và đây là kết quả của đoạn code trên:
Giờ đoạn mảng mới đã đúng mong muốn rồi thì chỉ cần đổ ra blade view thôi. Đoạn này thì đơn giản hơn rồi, chỉ cần check biến rowspan > 1 thì sẽ thêm thuộc tính rowspan còn ngược lại mình đổ data ra như bình thường.
<tbody>
@foreach($periods as $period)
@foreach($period as $row)
<tr style="text-align: center; vertical-align: middle">
@if ($row['rowspan'] > 0)
<td @if($row['rowspan'] > 1) rowspan="{{ $row['rowspan'] }}" @endif>{{ $row['order_id'] }}</td>
@endif
<td>{{ $row['mark'] . $row['model'] }}</td>
<td>{{ $row['price'] }}</td>
<td>{{ $row['status'] }}</td>
</tr>
@endforeach
@endforeach
</tbody>