Laravel Excel 中关于中文表头导致的数据读取问题

问题描述#

待处理的 Excel 文件表头如下:
Laravel Excel 中关于中文表头导致的数据读取问题
特征:表头全部是中文
导入代码:
Excel::import(new ReportsImport(), $event->report_file_name, 'public');
导入一直失败,dd 打印后发现:

array:1 [ // app/Imports/ReportsImport.php:21
  "" => "丁莉"
]

缺少数据,读了第一行的最后一个单元格。

解决方案#

注:下面部分来自 ChatGpt
在 Laravel Excel 中,headingRowFormatter 的值参数可以设置为 “none”、”slug” 或 “custom”,用于指定要应用于表头行的格式化方式。

  1. “none”: 当值设置为 “none” 时,不会应用任何特殊的格式化,表头行将保持原样,不进行任何修改。
  2. “slug”: 当值设置为 “slug” 时,表头行的文本将被转换为 slug 格式。Slug 是一种将文本转换为 URL 友好格式的方法,通常用于生成 URL 或标识符。例如,”Product Name” 可能被转换为 “product-name”。这种格式化方式可以使表头行更易于处理和使用。
  3. “custom”: 当值设置为 “custom” 时,您可以提供自定义的格式化逻辑。您可以通过传递一个闭包函数来自定义表头行的格式。闭包函数接受两个参数:$query$value。其中,$query 是 Excel 表格对象,$value 是当前处理的表头单元格的值。您可以在闭包函数中根据需要对表头行进行自定义的格式化。
    以下是示例代码,展示了如何使用不同的格式化方式:
->headingRowFormatter('none') // 不进行任何格式化
->headingRowFormatter('slug') // 将表头行转换为 slug 格式
->headingRowFormatter(function ($query, $value) {
    // 自定义格式化逻辑
    // $query 是 Excel 表格对象,$value 是表头单元格的值
    // 在此处编写您的自定义格式化逻辑
})

根据您的需求选择适当的格式化方式,并根据实际情况编写自定义的格式化逻辑。这样可以确保表头行以期望的方式进行格式化和处理。


所以生成了 Laravel Excel 的配置文件:
php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider" --tag=config
打开后,将 heading_row->formatter 默认的 slug 改为 none:

/*
        |--------------------------------------------------------------------------
        | Heading Row Formatter
        |--------------------------------------------------------------------------
        |
        | Configure the heading row formatter.
        | Available options: none|slug|custom
        |
        */
        'heading_row' => [
            'formatter' => 'none',
        ],

问题解决:

array:9 [ // app/Imports/ReportsImport.php:21
  "序号" => 1
  "归属" => "巴拉巴拉"
  "车牌号" => "巴拉巴拉"
  "姓名" => "巴拉巴拉"
  "保费" => '巴拉巴拉'
  "险种组合" => "巴拉巴拉"
  "上次保养时间" => "巴拉巴拉"
  "一年内保养次数" => "巴拉巴拉"
  "经办人" => "巴拉巴拉"
]

简单查看源码发现 Str::slug($value, '_') 这段代码处理中文后返回 ""

// vendor/maatwebsite/excel/src/Imports/HeadingRowFormatter.php
protected static function callFormatter($value, $key=null)
{
    static::$formatter = static::$formatter ??                         config('excel.imports.heading_row.formatter', self::FORMATTER_SLUG);

    // Call custom formatter
    if (isset(static::$customFormatters[static::$formatter])) {
        $formatter = static::$customFormatters[static::$formatter];

        return $formatter($value, $key);
    }

    if (empty($value)) {
        return $key;
    }

    if (static::$formatter === self::FORMATTER_SLUG) {
        return Str::slug($value, '_');
    }

    // No formatter (FORMATTER_NONE)
    return $value;
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。