3

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

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

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

4

1 回答 1

1

有几种方法可以解决这个问题。默认情况下,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 Ba​​ker。我不知道文件是否被上传,或者你是否从本地文件系统中获取它,所以我以文件系统选项为例:

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 模型都受到 Mass Assignment 保护。查看文档以查看您是否要设置属性fillableguarded(注意提到的安全含义)。我注意到有时在某些要导入的文件0 => nullitems数组中有一个字段CellCollection(显然是一个空列),因此您也可以将其称为

$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 本身中实现了一种更简单快捷的方法来进行这样的映射,很抱歉在这种情况下浪费了你的时间。

于 2016-03-01T23:53:29.377 回答