PhpSpreadsheet 如何导出 html 和子 headers?
PhpSpreadsheet how to export html with sub headers?
参考:https://github.com/PHPOffice/PhpSpreadsheet/issues/1608
预期的行为是什么?
没有事件
当前的行为是什么?
重现的步骤是什么?
问题是基于 Maatwebsite/Laravel-Excel
内部使用 PhpSpreadsheet
https://github.com/Maatwebsite/Laravel-Excel/issues/2784
<table style="width:100%" border="1">
<thead>
<tr>
// ...
<th style="text-align: center;" colspan="4">{{ __('Items') }}</th>
// ...
</tr>
<tr>
// ...
</tr>
</thead>
@foreach ($models->cursor() as $model)
<tbody>
<tr>
// ...
<td colspan="4">
<table style="width:100%">
@foreach ($model->relation as $item)
<tr>
// ...
</tr>
@endforeach
</table>
</td>
// ...
</tr>
</tbody>
@endforeach
</table>
// this works perfectly with single headers, but not with sub ones
public function registerEvents(): array
{
return [
AfterSheet::class => function (AfterSheet $event) {
$sheet = $event->sheet->getDelegate();
$sheet->getRowDimension(1)->setRowHeight(30);
$header = $sheet->getStyle('A1:' . $sheet->getHighestDataColumn() . '1');
$header->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER);
$header->getFont()->setBold(true);
$header->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('00000000');
$header->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
$other = $sheet->getStyle('A2:' . $sheet->getHighestDataColumn() . $sheet->getHighestRow());
$other->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP);
foreach ([$header, $other] as $item) {
$item->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_LEFT);
$item->getAlignment()->setWrapText(true);
}
},
];
}
感谢任何帮助,如果您需要更多信息,请询问。
您现在遇到的bug与您使用的库无关。
您正在为包含您需要显示的所有内容的母版 table 中的每个关系项使用 HTML table。因此它不能很好地工作。并非所有网络浏览器都支持格式错误的 HTML 文档,并且它们的支持因一个版本而异。
写得恰到好处HTML:使用DIVs元素构建智能可视化网页,只显示TABLEs元素内部的关系,不会像我们这里看到的那样被部分隐藏或显示错误。
因此,要构建您的 HTML,如果您使用 Bootstrap 作为示例,您可以为 headers 使用一行,每个项目一行。对于每个关系项,您可以将它们放在一个table中,它们将正确显示。
headers 或 <thead>
内的 <tr>
是有效的 HTML,应该可以与 PhpSpreadsheet/Laravel-Excel 一起正常工作。然而,multiple <tbody>
isn't valid/legal according to the HTML spec, and nested tables aren't supported by Laravel-Excel.
正如我在评论中提到的,我们一直在我们的应用程序中使用 Laravel-Excel,它使用非常相似的布局,并且在头部多行的情况下工作正常。所以真正的问题在于多个或嵌套 body。我建议遵循approach we've used。您可以使用适当的 rowspan
和 colspan
实现相同的布局(我们正在计算它)。
编辑:
根据您的要求,这里是 HTML with sample data 中的一个示例,根据您的布局,下面是带循环的 blade 视图。
<table border="1">
<thead>
<tr>
<th rowspan="2">Client Name</th>
<th rowspan="2">Total</th>
<th colspan="4">{{ __('Items') }}</th>
<th rowspan="2">Creation Date</th>
</tr>
<tr>
<th>Title</th>
<th>Price</th>
<th>Quantity</th>
<th>Total</th>
</tr>
</thead>
<tbody>
@foreach($customers as $customer)
@php
$count = count($customer->items);
$i = 0;
@endphp
@foreach($customer->items as $item)
<tr>
@if($i == 0)
<td rowspan="{{ $count }}">{{ $customer->name }}</td>
<td rowspan="{{ $count }}">{{ $customer->total }}</td>
@endif
<td>{{ $item->title }}</td>
<td>{{ $item->price }}</td>
<td>{{ $item->qty }}</td>
<td>{{ $item->total }}</td>
@if($i == 0)
<td rowspan="{{ $count }}">{{ $customer->date }}</td>
@endif
</tr>
@php
$i++;
@endphp
@endforeach
@endforeach
</tbody>
</table>
参考:https://github.com/PHPOffice/PhpSpreadsheet/issues/1608
预期的行为是什么?
没有事件
当前的行为是什么?
重现的步骤是什么?
问题是基于 Maatwebsite/Laravel-Excel
内部使用 PhpSpreadsheet
https://github.com/Maatwebsite/Laravel-Excel/issues/2784
<table style="width:100%" border="1">
<thead>
<tr>
// ...
<th style="text-align: center;" colspan="4">{{ __('Items') }}</th>
// ...
</tr>
<tr>
// ...
</tr>
</thead>
@foreach ($models->cursor() as $model)
<tbody>
<tr>
// ...
<td colspan="4">
<table style="width:100%">
@foreach ($model->relation as $item)
<tr>
// ...
</tr>
@endforeach
</table>
</td>
// ...
</tr>
</tbody>
@endforeach
</table>
// this works perfectly with single headers, but not with sub ones
public function registerEvents(): array
{
return [
AfterSheet::class => function (AfterSheet $event) {
$sheet = $event->sheet->getDelegate();
$sheet->getRowDimension(1)->setRowHeight(30);
$header = $sheet->getStyle('A1:' . $sheet->getHighestDataColumn() . '1');
$header->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER);
$header->getFont()->setBold(true);
$header->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)->getStartColor()->setARGB('00000000');
$header->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
$other = $sheet->getStyle('A2:' . $sheet->getHighestDataColumn() . $sheet->getHighestRow());
$other->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_TOP);
foreach ([$header, $other] as $item) {
$item->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_LEFT);
$item->getAlignment()->setWrapText(true);
}
},
];
}
感谢任何帮助,如果您需要更多信息,请询问。
您现在遇到的bug与您使用的库无关。
您正在为包含您需要显示的所有内容的母版 table 中的每个关系项使用 HTML table。因此它不能很好地工作。并非所有网络浏览器都支持格式错误的 HTML 文档,并且它们的支持因一个版本而异。
写得恰到好处HTML:使用DIVs元素构建智能可视化网页,只显示TABLEs元素内部的关系,不会像我们这里看到的那样被部分隐藏或显示错误。
因此,要构建您的 HTML,如果您使用 Bootstrap 作为示例,您可以为 headers 使用一行,每个项目一行。对于每个关系项,您可以将它们放在一个table中,它们将正确显示。
headers 或 <thead>
内的 <tr>
是有效的 HTML,应该可以与 PhpSpreadsheet/Laravel-Excel 一起正常工作。然而,multiple <tbody>
isn't valid/legal according to the HTML spec, and nested tables aren't supported by Laravel-Excel.
正如我在评论中提到的,我们一直在我们的应用程序中使用 Laravel-Excel,它使用非常相似的布局,并且在头部多行的情况下工作正常。所以真正的问题在于多个或嵌套 body。我建议遵循approach we've used。您可以使用适当的 rowspan
和 colspan
实现相同的布局(我们正在计算它)。
编辑:
根据您的要求,这里是 HTML with sample data 中的一个示例,根据您的布局,下面是带循环的 blade 视图。
<table border="1">
<thead>
<tr>
<th rowspan="2">Client Name</th>
<th rowspan="2">Total</th>
<th colspan="4">{{ __('Items') }}</th>
<th rowspan="2">Creation Date</th>
</tr>
<tr>
<th>Title</th>
<th>Price</th>
<th>Quantity</th>
<th>Total</th>
</tr>
</thead>
<tbody>
@foreach($customers as $customer)
@php
$count = count($customer->items);
$i = 0;
@endphp
@foreach($customer->items as $item)
<tr>
@if($i == 0)
<td rowspan="{{ $count }}">{{ $customer->name }}</td>
<td rowspan="{{ $count }}">{{ $customer->total }}</td>
@endif
<td>{{ $item->title }}</td>
<td>{{ $item->price }}</td>
<td>{{ $item->qty }}</td>
<td>{{ $item->total }}</td>
@if($i == 0)
<td rowspan="{{ $count }}">{{ $customer->date }}</td>
@endif
</tr>
@php
$i++;
@endphp
@endforeach
@endforeach
</tbody>
</table>