laravel - 导出视图时带有 CSS 的 Laravel Excel 样式不起作用
问题描述
我正在尝试使用 laravel Excel 3.1 导出视图。导出工作时,我无法对其进行样式设置。
我的 laravel 导出看起来像:
<?php
namespace App\Exports;
use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\FromView;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Concerns\RegistersEventListeners;
use Maatwebsite\Excel\Events\AfterSheet;
class MatrixExcelExport implements FromView, WithEvents
{
use RegistersEventListeners;
protected $data, $selected_data, $am_lists_only, $categories_list, $amenities_list, $affordable_list, $unit_type_list, $highlights_list, $non_unit;
public function __construct($data, $selected_data, $am_lists_only, $categories_list, $amenities_list, $affordable_list, $unit_type_list, $highlights_list, $non_unit)
{
$this->data = $data;
$this->selected_data = $selected_data;
$this->am_lists_only = $am_lists_only;
$this->categories_list = $categories_list;
$this->amenities_list = $amenities_list;
$this->affordable_list = $affordable_list;
$this->unit_type_list = $unit_type_list;
$this->highlights_list = $highlights_list;
$this->non_unit = $non_unit;
}
public function view(): View
{
return view('admin.matrix._excel', [
'data' => $this->data,
'selected_data' => $this->selected_data,
'am_lists_only' => $this->am_lists_only,
'categories' => $this->categories_list,
'amenities' => $this->amenities_list,
'affordables' => $this->affordable_list,
'unit_types' => $this->unit_type_list,
'highlights' => $this->highlights_list,
'non_unit' => $this->non_unit
]);
}
}
我的_excel
样子是这样的:
<?php
$impact = 0;
$negativeChanges = 0;
$positiveChanges = 0;
?>
<style>
.strikethroughCell{
text-decoration: line-through !important;
}
.table-text-center th,
.table-text-center td{
text-align: center !important;
}
.text-added{
color: #3ec10d;
font-weight: bold;
}
.text-updated{
color: #1843f5 !important;
font-weight: bold;
}
</style>
<table class="table-text-center">
<thead>
<tr>
<th rowspan="2">Bldg</th>
<th rowspan="2">Unit</th>
<th rowspan="2">Floor</th>
<th rowspan="2">Stack</th>
@foreach($selected_data as $k => $v)
<th colspan="{{count($v['amenities'])}}">
{{$v['category_name']}}
</th>
@endforeach
</tr>
<tr>
@foreach($am_lists_only as $ak => $av)
<th title="{{ $av }}">
<?php
if (strlen($av) > 15){
$av = substr($av, 0, 12) . '...';
}
?>
{{ $av }}
</th>
@endforeach
</tr>
</thead>
<tbody>
@foreach($data as $k => $v)
<?php
if(count($v) == 0){
continue;
}
$unit_cell_status = '';
$unit_note_class = '';
$avail_status = '';
if(trim($v[0]->unit_note) != ''){
$unit_note_class = 'unit_note';
}
if(isset($v[0]->avail_status)){
$avail_status = str_replace(' ','-',strtolower($v[0]->avail_status));
if(!in_array($avail_status,$highlights)){
$avail_status = '';
}
}
$unit_type_id = NULL;
if(!empty($v[0]->unit_type_id)){
$unit_type_id = $v[0]->unit_type_id;
}
$unit_type_class = (in_array($unit_type_id, $unit_types))?"td-unit-type":"";
?>
<tr id="ur_{{$v[0]->unit_id}}">
<td data-search="{{ $v[0]->building_number }}">{{ $v[0]->building_number }}</td>
<td data-search="{{ $v[0]->unit_id }}" data-unitid="{{$v[0]->unit_id}}" id="unitCell_{{$v[0]->unit_id}}" class="td-unit {{ $unit_note_class }} {{ $avail_status }} {{ $unit_type_class }}" xonclick="editUnit(1, {{ $v[0]->unit_id }}, {{ $v[0]->building_id }}); return false;">{{ $v[0]->unit_number }}</td>
<td data-search="{{ $v[0]->floor }}">{{ $v[0]->floor }}</td>
<td data-search="{{ $v[0]->stack }}">{{ $v[0]->stack }}</td>
@foreach($am_lists_only as $ak => $av)
<?php
$amenity_val = "";
$deleted_class = "";
$negativeClass = "";
$affordable = false;
$text_class = '';
$strikethrough_class = '';
foreach($v as $vk => $vv){
if($ak == $vv->amenity_id){
if( (isset($categories[0]) && $categories[0] === "-1") || !empty(in_array($vv->category_id, $categories)) || !empty(in_array($vv->amenity_id, $amenities))) {
if(empty($vv->uav_deleted_at)){
$impact += $vv->amenity_value;
if($vv->av_status == 2){
$text_class = 'text-updated';
if($unit_cell_status == ''){
$unit_cell_status = $text_class;
}
if($vv->initial_amenity_value != $vv->amenity_value){
$diff = $vv->amenity_value - $vv->initial_amenity_value ;
if($diff > 0){
$positiveChanges += $diff;
}else{
$negativeChanges += abs($diff);
}
}
}
if($vv->uav_status == 1){
$text_class = 'text-added';
$unit_cell_status = $text_class;
if($vv->amenity_value != 0){
if($vv->amenity_value > 0){
$positiveChanges += abs($vv->amenity_value);
}else{
$negativeChanges += abs($vv->amenity_value);
}
}
}
}else{
$deleted_class = "td-deleted";
if($vv->amenity_value != 0){
if($vv->amenity_value > 0){
$negativeChanges += abs($vv->amenity_value);
}else{
$positiveChanges += abs($vv->amenity_value);
}
}
$strikethrough_class = 'strikethroughCell';
}
$show_sum = true;
if($affordable == false && in_array($vv->amenity_id, $affordables) && empty($vv->uav_deleted_at)){
$affordable = true;
}
$amenity_val = $vv->amenity_value;
if($amenity_val < 0){
$amenity_val = "(".abs($amenity_val).")";
$negativeClass = 'text-negative';
}
if($deleted_class != ""){
$amenity_val = "<del>".$amenity_val."</del>";
}
}else{
if(empty($vv->uav_deleted_at)){
if($vv->av_status == 2){
if($vv->initial_amenity_value != $vv->amenity_value){
$diff = $vv->amenity_value - $vv->initial_amenity_value ;
if($diff > 0){
$positiveChanges += $diff;
}else{
$negativeChanges += abs($diff);
}
}
}
if($vv->uav_status == 1){
if($vv->amenity_value != 0){
if($vv->amenity_value > 0){
$positiveChanges += abs($vv->amenity_value);
}else{
$negativeChanges += abs($vv->amenity_value);
}
}
}
}else{
if($vv->amenity_value != 0){
if($vv->amenity_value > 0){
$negativeChanges += abs($vv->amenity_value);
}else{
$positiveChanges += abs($vv->amenity_value);
}
}
}
}
}
}
// $str = ['<del>','</del>'];
// $rplc =['-','-'];
// $search_val = str_replace($str,$rplc,$amenity_val);
?>
<td data-am_id="{{$ak}}" class="{{$strikethrough_class}} {{($affordable == true)?'affordable-unit':''}} {{$deleted_class}} {{$negativeClass}} {{ $text_class }}">
{!! $amenity_val !!}
</td>
@endforeach
</tr>
@endforeach
</tbody>
</table>
好吧,我想将所有单元格的文本居中,并希望在td
具有类的文本中添加删除线strikethroughCell
更新:
看起来我可以使用内联 CSS 更改字体颜色,但我还没有找到解决line-through
CSS 的方法。
更新 2
完全切换到数组方法。
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromArray;
use DB;
use Maatwebsite\Excel\Concerns\RegistersEventListeners;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithStrictNullComparison;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;
class MatrixExport implements FromArray, WithHeadings, WithStrictNullComparison, WithEvents
{
use RegistersEventListeners;
protected $data, $selected_data, $am_lists_only, $categories_list, $amenities_list, $affordable_list, $unit_type_list, $highlights_list, $non_unit;
static $negativeClassArr, $deletedClassArr, $addedClassArr, $updatedClassArr, $mergeCellsArr;
public function __construct($data, $selected_data, $am_lists_only, $categories_list, $amenities_list, $affordable_list, $unit_type_list, $highlights_list, $non_unit, $negativeClassArr = [], $deletedClassArr = [], $addedClassArr = [], $updatedClassArr = [], $mergeCellsArr = [])
{
$this->data = $data;
$this->selected_data = $selected_data;
$this->am_lists_only = $am_lists_only;
$this->categories_list = $categories_list;
$this->amenities_list = $amenities_list;
$this->affordable_list = $affordable_list;
$this->unit_type_list = $unit_type_list;
$this->highlights_list = $highlights_list;
$this->non_unit = $non_unit;
// $this->negativeClassArr = $negativeClassArr;
// $this->deletedClassArr = $deletedClassArr;
// $this->addedClassArr = $addedClassArr;
// $this->updatedClassArr = $updatedClassArr;
// $this->mergeCellsArr = $mergeCellsArr;
self::$negativeClassArr = $negativeClassArr;
self::$deletedClassArr = $deletedClassArr;
self::$addedClassArr = $addedClassArr;
self::$updatedClassArr = $updatedClassArr;
self::$mergeCellsArr = $mergeCellsArr;
}
public function array(): array
{
$ex_data = $item = [];
$impact = 0;
$negativeChanges = 0;
$positiveChanges = 0;
self::$negativeClassArr = self::$deletedClassArr = [];
$row = 3;
foreach($this->data as $k => $v){
if(count($v) == 0){
continue;
}
$unit_cell_status = '';
$item = [
'Bldg' => $v[0]->building_number,
'Unit' => $v[0]->unit_number,
'Floor' => $v[0]->floor,
'Stack' => $v[0]->stack
];
$col = 5;
foreach ($this->am_lists_only as $ak => $av) {
$colName = $this->getNameFromNumber($col);
$amenity_val = "";
$deleted_class = "";
$negativeClass = "";
$affordable = false;
$text_class = '';
$font_color = '#000000';
$font_weight = 'normal';
$strikethrough_class = '';
foreach($v as $vk => $vv){
if($ak == $vv->amenity_id){
if( (isset($this->categories_list[0]) && $this->categories_list[0] === "-1") || !empty(in_array($vv->category_id, $this->categories_list)) || !empty(in_array($vv->amenity_id, $amenities))) {
if(empty($vv->uav_deleted_at)){
$impact += $vv->amenity_value;
if($vv->av_status == 2 && $vv->uav_status == 0){
$text_class = 'text-updated';
// $font_color = '#1843f5';
// $font_weight = 'bold';
if($vv->initial_amenity_value != $vv->amenity_value){
$diff = $vv->amenity_value - $vv->initial_amenity_value ;
if($diff > 0){
$positiveChanges += $diff;
}else{
$negativeChanges += abs($diff);
}
}
}
if($vv->uav_status == 1){
$text_class = 'text-added';
// $font_color = '#3ec10d';
// $font_weight = 'bold';
if($vv->amenity_value != 0){
if($vv->amenity_value > 0){
$positiveChanges += abs($vv->amenity_value);
}else{
$negativeChanges += abs($vv->amenity_value);
}
}
}
if($text_class === "text-added"){
self::$addedClassArr[] = $colName.$row;
}
if($text_class === "text-updated"){
self::$updatedClassArr[] = $colName.$row;
}
}else{
$deleted_class = "td-deleted";
if($vv->amenity_value != 0){
if($vv->amenity_value > 0){
$negativeChanges += abs($vv->amenity_value);
}else{
$positiveChanges += abs($vv->amenity_value);
}
}
// $strikethrough_arr[] = 'strikethroughCell';
}
$show_sum = true;
if($affordable == false && in_array($vv->amenity_id, $this->affordable_list) && empty($vv->uav_deleted_at)){
$affordable = true;
}
$amenity_val = $vv->amenity_value;
if($amenity_val < 0){
$amenity_val = "(".abs($amenity_val).")";
// $negativeClass = 'text-negative';
// $font_color = '#dc3545';
self::$negativeClassArr[] = $colName.$row;
}
if($deleted_class != ""){
self::$deletedClassArr[] = $colName.$row;
// $amenity_val = "<del>".$amenity_val."</del>";
}
}
}
}
//$col 4
$item[$av] = $amenity_val;
$col++;
}
$ex_data[] = $item;
$row++;
}
return $ex_data;
}
public function headings(): array
{
$commonn_header_arr = ['Bldg', 'Unit', 'Floor', 'Stack'];
$this->selected_data;
$cat_header = [];
$col = 5;
$row = 1;
foreach($this->selected_data as $v){
// pe($this->selected_data);
// $cat_header = $v['category_name'];
$cnt = count($v['amenities']);
for($i=0; $i<$cnt; $i++){
$cat_header[] = $v['category_name'];
}
if($cnt > 1){
$colNameStart = self::getNameFromNumber($col).$row;
$col = $col + $cnt - 1;
$colNameEnd = self::getNameFromNumber($col).$row;
self::$mergeCellsArr[] = $colNameStart.':'.$colNameEnd;
}
$col += 1;
}
$first_row_header = array_merge($commonn_header_arr, $cat_header);
$second_row_header = array_merge($commonn_header_arr, $this->am_lists_only);
// return $second_row_header;
// pe(self::$mergeCellsArr);
return [
$first_row_header,
$second_row_header
];
}
public function getNameFromNumber($num) {
$numeric = ($num - 1) % 26;
$letter = chr(65 + $numeric);
$num2 = intval(($num - 1) / 26);
if ($num2 > 0) {
return self::getNameFromNumber($num2) . $letter;
} else {
return $letter;
}
}
// public function styles(Worksheet $sheet)
// {
// return [
// // Style the first row as bold text.
// 1 => ['font' => ['bold' => true]],
//
// // Styling a specific cell by coordinate.
// 'B2' => ['font' => ['italic' => true]],
//
// // Styling an entire column.
// 'C' => ['font' => ['size' => 16]],
// ];
// }
public static function afterSheet(AfterSheet $event)
{
$negativeStyle = [
'fill' => array(
'color' => array('rgb' => 'dc3545')
)
];
// Create Style Arrays
$addedStyle = [
'font' => [
'bold' => true,
'color' => array('rgb' => '3ec10d')
]
];
$updatedStyle = [
'font' => [
'bold' => true,
'color' => array('rgb' => '1843f5')
]
];
$negativeStyle = [
'font' => [
'bold' => true,
'color' => array('rgb' => 'dc3545')
]
];
$strikethrough = [
'font' => ['strikethrough' => true],
];
// Get Worksheet
$active_sheet = $event->sheet->getDelegate();
// Apply Style Arrays
// $active_sheet->getParent()->getDefaultStyle()->applyFromArray($default_font_style);
$q = $event->sheet;
foreach(self::$mergeCellsArr as $v){
$q->mergeCells($v);
}
foreach(self::$negativeClassArr as $v){
$active_sheet->getStyle($v)->applyFromArray($negativeStyle);
}
foreach(self::$addedClassArr as $v){
$active_sheet->getStyle($v)->applyFromArray($addedStyle);
}
foreach(self::$updatedClassArr as $v){
$active_sheet->getStyle($v)->applyFromArray($updatedStyle);
}
foreach(self::$deletedClassArr as $d){
$active_sheet->getStyle($d)->getFont()->setStrikethrough(true);
}
}
}
解决方案
正如我所评论的,对于更复杂的样式,您需要使用 PhpSpreadsheet 的样式方法。有关phpspreadsheet 文档的更多信息。
我这样做的方式是使用事件来获取底层的 phpspreadsheet 类。
use Maatwebsite\Excel\Concerns\FromView;
use Maatwebsite\Excel\Concerns\RegistersEventListeners;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;
class MatrixExcelExport implements FromView, WithEvents
{
use RegistersEventListeners;
public function __construct(...) { ... }
public function view(): View
{
return view('admin.matrix._excel', [...]);
}
public static function afterSheet(AfterSheet $event)
{
// Create Style Arrays
$default_font_style = [
'font' => ['name' => 'Arial', 'size' => 10]
];
$strikethrough = [
'font' => ['strikethrough' => true],
];
// Get Worksheet
$active_sheet = $event->sheet->getDelegate();
// Apply Style Arrays
$active_sheet->getParent()->getDefaultStyle()->applyFromArray($default_font_style);
// strikethrough group of cells (A10 to B12)
$active_sheet->getStyle('A10:B12')->applyFromArray($strikethrough);
// or
$active_sheet->getStyle('A10:B12')->getFont()->setStrikethrough(true);
// single cell
$active_sheet->getStyle('A13')->getFont()->setStrikethrough(true);
}
}
或者你也可以按照laravel excel 的样式指南
WithStyles 关注点允许对列、单元格和行进行样式设置。当您想让标题行加粗时,这可能很有用。
namespace App\Exports; use Maatwebsite\Excel\Concerns\WithStyles; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class InvoicesExport implements WithStyles { public function styles(Worksheet $sheet) { return [ // Style the first row as bold text. 1 => ['font' => ['bold' => true]], // Styling a specific cell by coordinate. 'B2' => ['font' => ['italic' => true]], // Styling an entire column. 'C' => ['font' => ['size' => 16]], ]; } }
关于样式数组的内容,请参考 PhpSpreadsheet 文档(opens new window)
如果您更喜欢样式单元格的流利语法,您可以按如下方式进行:
namespace App\Exports; use Maatwebsite\Excel\Concerns\WithStyles; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class InvoicesExport implements WithStyles { public function styles(Worksheet $sheet) { $sheet->getStyle('B2')->getFont()->setBold(true); } }
推荐阅读
- javascript - 添加 require 关键字会破坏 vanilla JavaScript 函数
- algorithm - 中位数算法的中位数 - 选择哪个元素作为每组的中位数
- java - JGraphT:用另一个子树替换有向无环图中的子树
- java - JavaFxPorts - javafx.platform 未定义
- react-native - 打开键盘时出现标题故障
- android - Admob 广告未在 Android 应用程序中显示
- python - 如何使用 to_dict() 将 pandas DataFrame 转换为列表字典?
- apache - Apache access.log 对 ip hits 进行排序并自定义输出结果
- ios - 即使仍在从 Cloud Firestore 加载数据,方法也会继续
- colors - 给定原色,如何根据材料设计指南决定 OnPrimary 颜色是什么?