导入标题与数据库字段不同的 Excel 文档 - Laravel 5.2


Importing an excel document with headers different from database fields - Laravel 5.2

尝试导入带有自定义标题(即人类可读)的 excel 电子表格,并将其与 excel 导入的数据库字段匹配。

示例:列标题为:区域(例如北美)
数据库列标题为:region_code

知道如何使用maatwebsite/excel包和Eloquent模型来做到这一点吗?

有几种方法可以解决这个问题。默认情况下,maatwerk-excel包会将标头转换为 slug。

注意:默认情况下,这些属性将转换为 slug。您可以在配置 excel::import.heading 中更改默认值。可用的选项有:true|false|slugged|ascii|numeric|hashed|trans|original

当 excel::import.to_ascii 设置为 true 时,True 和 slugged 也将转换为 ASCII。您也可以在配置中更改默认分隔符。

您将能够按 slug 对行进行寻址,因此Region将变得region .您可以查看是否有适合您的设置。

循环、映射和保存

复杂性取决于您是否有多个工作表,您可以遍历所有内容并将其保存在每个字段的 Eloquent 模型上,方法是将其映射到 Mark Baker 在您的问题评论中提到的。我不知道文件是否已上传,或者您是否从本地文件系统中获取它,因此我以文件系统选项为例:

Excel::load(storage_path('app/public/excel-import.xlsx'), function($reader) {
    $results = $reader->get();
    foreach($results as $result) {
        // Your model namespace here
        $model = new 'App'ImportItem();
        $model->region_code = $result->region;
        $model->numeric_code = $result->code;
        $model->testfield = $result->test_field;
        $model->save();
    }
});

当您有很多包含大量字段的 Excel 文件时,这并不容易维护,但如果它们很少并且不容易更改,这可能是一个解决方案。

批量分配

另一种选择是更改 excel 中的所有标题(如果这是一个选项),然后通过将上面显示的foreach内容替换为以下内容来批量分配模型:

$model = App'ImportItem::create($result->toArray()); 

但请注意,默认情况下,所有 Eloquent 模型都受到批量分配保护。查看文档以查看是要设置属性fillable还是guarded(请注意提到的安全隐患)。我注意到有时在某些要导入的文件(显然是空列)的CellCollectionitems数组中有一个字段0 => null,所以你也可以像这样称呼它

$reader->ignoreEmpty()->get()

但请记住,它可能会在其他空白字段上产生不需要的结果,因此您也可以以另一种方式剥离它。

现在,如果您不想重命名 Excel 中的所有列,您也可以在模型中定义突变器,但我认为在这种情况下也不合适。举个例子:

class ImportItem extends Model
{
    protected $table = 'importitems';
    protected $fillable = [
        'region_code',
    ];
    /* 
     * If you have a field region in the Mass Assignment
     * and a field region_code in your database.
     */
    public function setRegionAttribute($value)
    {
        $this->attributes['region_code'] = $value;
    }
    // Same for each attribute! Ugh what a mess!

也许我白白写了所有这些,并且有一种更简单、更快捷的方法实现到包和/或 Laravel本身进行这样的映射,很抱歉在这种情况下浪费您的时间。