PhpSpreadsheet如何导出带有子标题的HTML? 预期的行为是什么?没有事件当前行为是什么?要复制的步骤是什么?

问题描述

ref:https://github.com/PHPOffice/PhpSpreadsheet/issues/1608

预期的行为是什么?

html

没有事件

enter image description here

当前行为是什么?

html

要复制的步骤是什么?

此问题基于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);
                }
            },];
    }

感谢您的帮助,如果您需要更多信息,请询问。

解决方法

Sub标题或<tr>中的<thead>是有效的HTML,应与PhpSpreadsheet / Laravel-Excel配合使用。但是,请根据multiple <tbody> isn't valid/legalHTML spec分别使用nested tables aren't supported by Laravel-Excel

正如我在评论中提到的那样,我们一直在应用程序中使用Laravel-Excel,该应用程序使用非常相似的布局,并且在头中有多行时工作得很好。因此,真正的问题是多个或嵌套的主体。我建议遵循approach we've used。您可以使用适当的rowspancolspan来获得相同的布局(我们正在为此进行计算)。

编辑:

根据要求,这是HTML with sample data中根据您的布局的示例,下面是带有循环的刀片视图。

<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>
,

您现在面临的错误与您正在使用的库无关。

您正在为包含您需要显示的所有内容的主表中的每个关系项使用HTML表。因此,它不能很好地工作。并非所有的网络浏览器都支持格式错误的HTML文档,并且从一个版本到另一个版本,它们的支持差异很大。

编写正确的HTML:使用DIVs元素构建一个智能的可视化网页,并仅显示TABLEs元素内部的关系,因此我们不会在这里看到它们的部分隐藏或显示错误。

因此,为了构造HTML,如果以Bootstrap为例,则可以使用一行作为标题,每项一行。对于每个关系项,您可以将它们放在表格中,它们将正确显示。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...