web-dev-qa-db-fra.com

ajouter une colonne personnalisée à laravel excel

J'utilise maatwebsite/Excel , je souhaite savoir s'il est possible d'ajouter une colonne personnalisée lorsque j'exporte mes données au format CSV ou non.

Explication

J'exporte avec succès mes données products, mais mes produits ont une autre option qui n'est pas stockée dans la table des produits, telle que: specification.

mes spécifications sont stockées dans 2 tables différentes nommées specifications où parent est comme CPU et subscpecifications où child sont stockés comme suit: Core i5.

une autre table que j’utilise pour stocker les identifiants de l’enfant et des produits afin de relier chaque produit à leurs sous-spécifications.

Cela semble complet, non? :) here i provide ugly map to get the logic :)

 screen 1

Maintenant, ce que j'essaie de faire, c'est:

Ajouter une colonne supplémentaire à mon fichier csv et inclure toutes les spécifications de chaque produit.

échantillon:

 sample

Codes

voici ma fonction d'exportation actuelle

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();
    }

Des questions

  1. Est-ce possible?
  2. Si oui, Base sur ma fonction ci-dessus, comment puis-je le faire?

Merci d'avance.

MISE À JOUR 1

J'ai ajouté ce code à ma fonction

$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);

et changé cette ligne:

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

à 

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

maintenant voici ce que j'ai

 screen3

voici ma fonction complète actuellement:

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();
    }

MISE À JOUR 2

Et bien ce soir, j'ai beaucoup joué avec mes codes et FINALEMENT :) J'ai eu ce qu'il me fallait, voici comment:

//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

Cela me donnera les spécifications de mes produits, mais il y a 3 petits problèmes:

  1. Je n'ai pas d'en-tête pour mes spécifications en fichier CSV
  2. Les produits sans spécification affichent [] au lieu de rien
  3. les produits avec spécification les couvre également avec [] et ""

Ici, j'ai fourni une capture d'écran pour une meilleure compréhension:

 screen5

5
mafortis

Vous devez préparer des colonnes personnalisées Spécifications en parcourant les produits en boucle. Voici votre solution,

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();
}

Mettre à jour

Selon votre image de feuille, je peux supposer que vous n’avez que trois colonnes Id, Title et Specifications, vous pouvez modifier le tableau d’en-tête en fonction des colonnes que vous obtenez de DB. 

2
Faraz Irfan
  1. Je n'ai pas d'en-tête pour mes spécifications en fichier CSV

Pour résoudre le problème, vous pouvez définir un en-tête et utiliser la fonction array_merge(). Pour I.E.

$headers[] = [
                'Title',
                'Specifications',
            ];
$products= array_merge($headers, $products);
  1. Des produits sans spécification montre [] au lieu de rien
  2. les produits avec spécification les couvre également avec [] et ""

Pour les 2ème et 3ème points, vous pouvez utiliser implode() pour vous débarrasser de []

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

J'espère que cela t'aides

0
Bhavin Solanki

Ça marche pour moi. très simple 

// Headings//
$headers[] = ['Id', 'Name'];

// 2 Rows //
$data[0] = ['1', 'John'];
$data[1] = ['2', 'Roger'];

Excel::create('report', function($Excel) use($headers, $data) {

    $Excel->sheet('sheet 1', function($sheet) use($headers, $data){
        $merged_records = array_merge($headers, $data);
        $sheet->fromArray($merged_records, null, 'A1', false, false);
    });
})->export('csv');
0
Umar Tariq

Oui, c'est possible. Crée un tableau pour la ligne, par exemple. data = array(); Transférer les données de cellule dans un tableau

vous pouvez récupérer les données de relation en utilisant eloquent ou join aussi, ici je vais chercher la boucle intérieure.

Fonction mise à jour comme ci-dessous:

J'ai essayé de correspondre à votre structure de données

  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();
}
0
Sharad Kale