Laravel-excel: الكيفية: حفظ ملفات csv / xls باستخدام ajax فقط

تم إنشاؤها على ١٤ يوليو ٢٠١٦  ·  12تعليقات  ·  مصدر: Maatwebsite/Laravel-Excel

اهلا ياجماعة،

لقد رأيت أن البعض منا يحاول تقديم ملف من طلب أياكس. بعد بعض البحث ، لم أجد أي حل واضح للقيام بذلك. بعد تعديل بعضها ، نجحت في تصدير بيانات csv و xls من طلب Ajax. الشيء هو أن التلاعب يختلف إذا كان نوع الملف هو xls ، بسبب الترميز ، لذلك هناك القليل من التعديلات.

تأتي البيانات من استعلام Eloquent نموذجي ، محوّلًا إلى Array:

بي أتش بي

if(!empty(Input::get('exportType'))) { //i use a custom get parameter here
            $dd = Excel::create('testFileName', function($excel) use ($data) {
                $excel->sheet('testSheetName', function($sheet) use ($data) {
                    $sheet->fromArray($data->get()->toArray());
                });
                $excel->setTitle($filename);
                $excel->setLastModifiedBy(Carbon::now()->toDayDateTimeString()); //updated has Carbon::now() only now throw exception on vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5.php l847 strlen()
            });

            //tweak for serving XLS file from ajax (or go trough download() Excel method for csv files)
            if(Input::get('exportType') == 'xls') {
                $dd = $dd->string();
                $response =  array(
                    'filename' => 'testFileName', //as we serve a custom response, HTTP header for filename is not setted by Excel. From the JS, you need to retrieve this value if type is XLS to set filename
                    'file' => "data:application/vnd.ms-excel;base64,".base64_encode($dd)
                );
                return response()->success($response); //do a json encode
            } else {
                //direct use of Excel download method for non-xls files - xls files need special JS treatment
                $dd->download(Input::get('exportType')); //not XLS, so CSV (didnt tried xlsx, pdf is blank but not sure it's related to this)
            }
            die; //prevent malformed binary data stream, not sure if needed
        }

شبيبة

$.ajax({
      cache: false,
      url: url, //GET route 
      responseType: 'ArrayBuffer', //not sure if needed
      data:  exportParam, //exportType parameter here
      success: function (data, textStatus, request) {

//you could need to decode json here, my app do it automaticly, use a try catch cause csv are not jsoned

        //already json decoded? custom return from controller so format is xls
        if(jQuery.isPlainObject(data)) {
          data = data.data; //because my return data have a 'data' parameter with the content
        }

        //V1 - http://stackoverflow.com/questions/35378081/laravel-excel-using-with-ajax-is-not-working-properly
        //+V3 - http://stackoverflow.com/questions/27701981/phpexcel-download-using-ajax-call
        var filename = "";
        var disposition = request.getResponseHeader('Content-Disposition');
        if (disposition && disposition.indexOf('attachment') !== -1) {
          var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
          var matches = filenameRegex.exec(disposition);
          if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
        }
        if(!jQuery.isPlainObject(data)) { //is CSV - we use blob
           var type = request.getResponseHeader('Content-Type');
           var blob = new Blob([data], { type: type ,endings:'native'});
           var URL = window.URL || window.webkitURL;
           var downloadUrl = URL.createObjectURL(blob);
        }
        var a = document.createElement("a");
        a.href = jQuery.isPlainObject(data) ? data.file : downloadUrl; 
        a.download = jQuery.isPlainObject(data) ? data.filename : filename;
        document.body.appendChild(a);
        a.click();
        a.remove();
      },
      error: function (ajaxContext) {
        toastr.error('Export error: '+ajaxContext.responseText);
      }
    });

ملاحظة: هذه ليست مشكلة

التعليق الأكثر فائدة

كنت بحاجة إلى إرجاع xlsx من ajax ، لذلك قمت بالتعديل مرة أخرى قليلاً وهذا ما انتهى بي الأمر:

بي أتش بي
البيانات $ هي استعلام Eloquent تم تحويله إلى Array.

$myFile= Excel::create("filename", function($excel) use($data) {
   $excel->setTitle('title');
   $excel->sheet('sheet 1', function($sheet) use($data) {
     $sheet->fromArray($data, null, 'A1', true, true);
   });
});

$myFile = $myFile->string('xlsx'); //change xlsx for the format you want, default is xls
$response =  array(
   'name' => "filename", //no extention needed
   'file' => "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,".base64_encode($myFile) //mime type of used format
);
return response()->json($response);

شبيبة

$.ajax({
      cache: false,
      url: url, //GET route 
      data:  params, //your parameters data here
      success: function (response, textStatus, request) {
        var a = document.createElement("a");
        a.href = response.file; 
        a.download = response.name;
        document.body.appendChild(a);
        a.click();
        a.remove();
      },
      error: function (ajaxContext) {
        toastr.error('Export error: '+ajaxContext.responseText);
      }
    });

ال 12 كومينتر

شكرًا جزيلاً ، إنه يعمل جيدًا لملف CSV ولكن ليس xls ،

كنت بحاجة إلى إرجاع xlsx من ajax ، لذلك قمت بالتعديل مرة أخرى قليلاً وهذا ما انتهى بي الأمر:

بي أتش بي
البيانات $ هي استعلام Eloquent تم تحويله إلى Array.

$myFile= Excel::create("filename", function($excel) use($data) {
   $excel->setTitle('title');
   $excel->sheet('sheet 1', function($sheet) use($data) {
     $sheet->fromArray($data, null, 'A1', true, true);
   });
});

$myFile = $myFile->string('xlsx'); //change xlsx for the format you want, default is xls
$response =  array(
   'name' => "filename", //no extention needed
   'file' => "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,".base64_encode($myFile) //mime type of used format
);
return response()->json($response);

شبيبة

$.ajax({
      cache: false,
      url: url, //GET route 
      data:  params, //your parameters data here
      success: function (response, textStatus, request) {
        var a = document.createElement("a");
        a.href = response.file; 
        a.download = response.name;
        document.body.appendChild(a);
        a.click();
        a.remove();
      },
      error: function (ajaxContext) {
        toastr.error('Export error: '+ajaxContext.responseText);
      }
    });

شكرا!!

أتلقى خطأ "Class 'Excel' غير موجود". هل يمكنك مساعدتي؟

randomhoodie أي مصدر كيف خرجت بهذا الحل؟

eldyvoon كما قلت ، "لقد قمت بتعديل" الإجابة الأصلية ،

لقد وجدت أنه ليس هناك حاجة إلى جافا سكريبت أو أياكس على الإطلاق. لدي صفحة ويب بها روابط لتنزيل مجموعة من ملفات csv / xls / xlsx المختلفة ولا أريد تحديث الصفحة على الإطلاق. كل ما فعلته هو ربط رابط إلى إجراء أعاد ما يلي ...

getSpreadsheet () للوظيفة العامة {
العناصر $ = العنصر :: all () ؛
Excel :: إنشاء ('العناصر' ، الوظيفة ($ excel) استخدام ($ items) {
excel-> sheet ('ExportFile' ، الوظيفة ($ sheet) استخدم ($ items) {
$ sheet-> fromArray ($ items)؛
}) ؛
}) -> تصدير ('xls') ؛
}

رائع !!!!

شكرا @ randomhoodie!

بالنسبة لحزمة 3.x ، سأقوم بتحديث PHP الخاص بك بشيء من هذا القبيل ، حسب دليل الترقية :

        $myFile = Excel::raw(new YOUR_Export_Class, \Maatwebsite\Excel\Excel::XLSX);

        $response =  array(
           'name' => "filename", //no extention needed
           'file' => "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,".base64_encode($myFile) //mime type of used format
        );

        return response()->json($response);

شكرًا kynetiv ، أستخدم الإصدار 3.x ، لكنني كنت بحاجة إلى إضافة ملحق مثل: filename.xlsx

إذا كنت لا تزال تواجه هذه المشكلة في 2020. لاحظ أن الإصدار 3.x من Laravel excel قد تغير ، لذا إليك الحل

  1. أرسل بياناتك عبر Ajax إلى وحدة التحكم الخاصة بك والتي تتفاعل مع كائن Laravel Excel
  2. دع كائن Laravel excel يرسل بياناتك إلى عرض النص
  3. تخزين عرض النص على الخادم
  4. استخدم js لتنزيل الملف على الخادم.
    لذا تكمن الفكرة في تصدير عرض الشفرة كملف Excel وتخزينه على موقع القرص حيث يمكنك تنزيله
    جافا سكريبت.

مثال:

 $exports = new ReportsExporter($data, $columns);
  Excel::store($exports , 'filename.xlsx', 'custom_disk_location');

حدد موقع القرص المخصص في نظام ملفات التكوين مثل هذا

'custom_disk_location' => [
            'driver' => 'local',
            'root' => public_path('files'),
        ],
...

سيضمن ذلك عدم حفظ ملف Excel في التخزين / التطبيق
ولكن سيحفظه في المسار العام / الملفات على الخادم الخاص بك

العودة إلى جافا سكريبت الخاص بك ، قم بتنزيل الملف مثل هذا

function download(filename, path) {
        let element = document.createElement('a');
        element.setAttribute('href', path);
        element.setAttribute('download', filename);

        element.style.display = 'none';
        document.body.appendChild(element);

        element.click();

        document.body.removeChild(element);
    }

استدعاء وظيفة التنزيل عن طريق تمرير اسم الملف والمسار
تنزيل ("filename.xlsx" ، location.origin + "files / filename.xlsx") ؛

بعد التنزيل ، تذكر العودة إلى الخادم وإزالة الخادم المخزن على الخادم مثل هذا
إلغاء الارتباط ("files / filename.xlsx") ؛

آمل أن يساعد هذا أي شخص يجد صعوبة في تنزيل Laravel-excel من خلال ajax أو javascript.
يعد هذا خيارًا أفضل لأنه يمنحك مزيدًا من المرونة لتخصيص تجربة المستخدم الخاصة بك و
قدم لهم ملاحظات فيما يتعلق بحالة التنزيل بالإضافة إلى تسمية ملفك بالطريقة التي تريدها.

كنت بحاجة إلى إرجاع xlsx من ajax ، لذلك قمت بالتعديل مرة أخرى قليلاً وهذا ما انتهى بي الأمر:

بي أتش بي
البيانات $ هي استعلام Eloquent تم تحويله إلى Array.

$myFile= Excel::create("filename", function($excel) use($data) {
   $excel->setTitle('title');
   $excel->sheet('sheet 1', function($sheet) use($data) {
     $sheet->fromArray($data, null, 'A1', true, true);
   });
});

$myFile = $myFile->string('xlsx'); //change xlsx for the format you want, default is xls
$response =  array(
   'name' => "filename", //no extention needed
   'file' => "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,".base64_encode($myFile) //mime type of used format
);
return response()->json($response);

شبيبة

$.ajax({
      cache: false,
      url: url, //GET route 
      data:  params, //your parameters data here
      success: function (response, textStatus, request) {
        var a = document.createElement("a");
        a.href = response.file; 
        a.download = response.name;
        document.body.appendChild(a);
        a.click();
        a.remove();
      },
      error: function (ajaxContext) {
        toastr.error('Export error: '+ajaxContext.responseText);
      }
    });

كنت بحاجة إلى إرجاع xlsx من ajax ، لذلك قمت بالتعديل مرة أخرى قليلاً وهذا ما انتهى بي الأمر:

بي أتش بي
البيانات $ هي استعلام Eloquent تم تحويله إلى Array.

$myFile= Excel::create("filename", function($excel) use($data) {
   $excel->setTitle('title');
   $excel->sheet('sheet 1', function($sheet) use($data) {
     $sheet->fromArray($data, null, 'A1', true, true);
   });
});

$myFile = $myFile->string('xlsx'); //change xlsx for the format you want, default is xls
$response =  array(
   'name' => "filename", //no extention needed
   'file' => "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,".base64_encode($myFile) //mime type of used format
);
return response()->json($response);

شبيبة

$.ajax({
      cache: false,
      url: url, //GET route 
      data:  params, //your parameters data here
      success: function (response, textStatus, request) {
        var a = document.createElement("a");
        a.href = response.file; 
        a.download = response.name;
        document.body.appendChild(a);
        a.click();
        a.remove();
      },
      error: function (ajaxContext) {
        toastr.error('Export error: '+ajaxContext.responseText);
      }
    });

جيد جدا

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات