将自定义列添加到laravel excel

时间:2018-04-13 05:34:04

标签: php excel laravel laravel-excel

我正在使用maatwebsite/excel,我想知道在将数据导出为CSV时是否可以添加自定义列?

解释

我已成功导出products数据,但我的产品还有其他选项未存储在我的产品表中,例如:specification

我的规范存储在两个名为specifications的不同表中,其中父项如CPUsubscpecifications,其中子项的存储方式如下:Core i5

我用来存储孩子的id和产品ID的另一个表,以便将每个产品与他们的子规范相关联。

声音完成了吗? :) here i provide ugly map to get the logic:)

screen 1

现在,我尝试做的是:

在我的csv文件中添加额外的列,并包含每种产品的所有规格。

样品:

sample

这是我当前的导出功能

public function export(Request $request) {
      $input = $request->except('_token');
      foreach ($input['cb'] as $key => $value) {
        if ($value== 'on') {
          $getRealInput[$key] = $input['defaultname'][$key];
        }
      }

      $products = Product::select($getRealInput)->get();


      Excel::create('products', function($excel) use($products, $request) {
        $excel->sheet('sheet 1', function($sheet) use($products, $request){

          $input = $request->except('_token');
          foreach ($input['cb'] as $key => $value) {
            if ($value== 'on') {
              $getCustomInput[$key] = $input['customname'][$key];
            }
          }

          $sheet->fromArray($products, null, 'A1', false, false);
          $sheet->row(1, $getCustomInput);
        });
      })->export('csv');
      return redirect()->back();
    }

问题

  1. 可能吗?
  2. 如果是,根据我上面的功能,我该怎么做?
  3. 提前致谢。

    更新1

    我已将此代码添加到我的功能

    $allRows = array();
      $data = array();
      foreach($products as $product){
      $specs = $product->subspecifications;
      foreach($specs as $spec){
        $data[] = $spec->specification->title;
        $data[] = $spec->title;
      }
    }
    array_push($allRows , $data);
    

    并改变了这一行:

    $sheet->fromArray($products, null, 'A1', false, false);
    

    $sheet->fromArray($allRows, null, 'A1', false, false);
    

    现在这就是我所拥有的:

    screen3

    这是我目前的全部功能:

    public function export(Request $request) {
          $input = $request->except('_token');
          foreach ($input['cb'] as $key => $value) {
            if ($value== 'on') {
              $getRealInput[$key] = $input['defaultname'][$key];
            }
          }
    
          $products = Product::select($getRealInput)->get();
    
    
          Excel::create('products', function($excel) use($products, $request) {
            $excel->sheet('sheet 1', function($sheet) use($products, $request){
    
              $input = $request->except('_token');
              foreach ($input['cb'] as $key => $value) {
                if ($value== 'on') {
                  $getCustomInput[$key] = $input['customname'][$key];
                }
              }
    
    
              // test code of adding subspacifications
              $allRows = array();
              $data = array();
              foreach($products as $product){
                  $specs = $product->subspecifications;
                  foreach($specs as $spec){
                        $data[] = $spec->specification->title;
                        $data[] = $spec->title;
                  }
              }
              array_push($allRows , $data);
              $sheet->fromArray($allRows, null, 'A1', false, false);
              //
              // $sheet->fromArray($products, null, 'A1', false, false);
              $sheet->row(1, $getCustomInput);
            });
          })->export('csv');
          return redirect()->back();
        }
    

    更新2

    今晚我很好地玩了我的代码,最后:)我得到了我需要的东西,这是如何:

    //codes...
    
    // Here is you custom columnn logic goes
              foreach($products as $product){
                $specifications = DB::table('products')
                ->where('products.id', $product->id)
                ->join('product_subspecification', 'product_subspecification.product_id', '=', 'products.id')
                ->join('subspecifications', 'subspecifications.id', '=', 'product_subspecification.subspecification_id')
                ->select('subspecifications.title')
                ->pluck('title');
    
                $product['specifications'] = rtrim($specifications,',');
              }
              //
    
    
              $sheet->fromArray($products, null, 'A1', false, false);
              $sheet->row(1, $getCustomInput);
    
    //... rest of the codes
    

    这将给我我的产品规格,但有3个小问题:

    1. 我没有标题为CSV文件中的规范
    2. 没有规格的产品显示[]而不是
    3. 符合规格的产品也会使用[]""
    4. 来涵盖这些产品

      在这里,我提供了截图以便更好地理解:

      screen5

4 个答案:

答案 0 :(得分:2)

您需要通过循环浏览产品来准备自定义列规范。这是你的修复,

public function export(Request $request) {

  $headers[] = [
                'Id',
                'Title',
                'Specifications',
            ];


  $input = $request->except('_token');
  foreach ($input['cb'] as $key => $value) {
    if ($value== 'on') {
      $getRealInput[$key] = $input['defaultname'][$key];
    }
  }

  $products = Product::select($getRealInput)->with('subspecifications')->get()->toArray();

  Excel::create('products', function($excel) use($headers,$products, $request) {
    $excel->sheet('sheet 1', function($sheet) use($headers,$products, $request){

      $input = $request->except('_token');
      foreach ($input['cb'] as $key => $value) {
        if ($value== 'on') {
          $getCustomInput[$key] = $input['customname'][$key];
        }
      }
      // Here is you custom columnn logic goes
          foreach($products as $product){
            $specs = "";
            $specifications = DB::table('products')
            ->where('products.id', $product->id)
            ->join('product_subspecification', 'product_subspecification.product_id', '=', 'products.id')
            ->join('subspecifications', 'subspecifications.id', '=', 'product_subspecification.subspecification_id')
            ->select('subspecifications.title')
            ->pluck('title');
            foreach($specifications as $spec){
              $specs = $specs .','.$spec;
            }
            $product['specifications'] = ltrim($specs,',');
          }
          //
      $mergedProducts = array_merge($headers, $products);
      $sheet->fromArray($mergedProducts, null, 'A1', false, false);
      $sheet->row(1, $getCustomInput);
    });
  })->export('csv');
  return redirect()->back();
}

<强>更新

根据您的工作表图像,我可以假设您只有三列Id,标题和规格,您可以根据从DB获得的列更改标题数组。

答案 1 :(得分:0)

是的,可能。 为行创建数组即。 data = array(); 将单元格数据推送到数组

你可以使用eloquent或join来获取关系数据,这里我在内部循环中获取。

更新功能如下:

我尝试与您的数据结构匹配

  public function export(Request $request) {
  $input = $request->except('_token');
  foreach ($input['cb'] as $key => $value) {
    if ($value== 'on') {
      $getRealInput[$key] = $input['defaultname'][$key];
    }
  }

  $products = Product::select($getRealInput)->get();


  Excel::create('products', function($excel) use($products, $request) {
    $excel->sheet('sheet 1', function($sheet) use($products, $request){


      // test code of adding subspacifications
      $allRows = array();
      array_push($allRows , ['id', 'title', 'specifications']); // Added title row
      $data = array();
      foreach($products as $product){
          $data[] = $product->id;    // Added product fields 
          $data[] = $product->title;
          $specs = $product->subspecifications;
          $spec_details = "";
          foreach($specs as $spec){                    
                $spec_details .= $spec->specification->title.':'. $spec->title. ' '; // appended specification:subspecification 
          }
          $data[] = $spec_details;
      }
      array_push($allRows , $data);
      $sheet->fromArray($allRows, null, 'A1', false, false);
      //
      // $sheet->fromArray($products, null, 'A1', false, false);
      //$sheet->row(1, $getCustomInput);   // commented
    });
  })->export('csv');
  return redirect()->back();
}

答案 2 :(得分:0)

  1. 我没有标题为CSV文件中的规范
  2. 要解决此问题,您可以定义标头并使用use array_merge()。对于I.E。

    $headers[] = [
                    'Title',
                    'Specifications',
                ];
    $products= array_merge($headers, $products);
    
    1. 没有规格的产品显示[]而不是
    2. 带有规格的产品也包含[]和“”
    3. 对于第2点和第3点,您可以使用implode()删除[]

      $product['specifications'] = implode(',', $specifications);
      

      希望这有帮助

答案 3 :(得分:0)

对我有用。非常简单

sencha generate app -ext MyApp /path/to/my-app