在laravel中使用ajax下载maatwebsite excel

时间:2017-09-19 10:48:21

标签: ajax excel laravel-5.4 maatwebsite-excel

我试图在laravel中使用ajax方法下载excel文件。 控制器功能:

$myFile = Excel::create($name, function ($excel) use ($export) {
            $excel->sheet('Data', function ($sheet) use ($export) {
                $sheet->fromArray($export);

                $sheet->cells('A1:N1', function ($cells) {

                    $cells->setBackground('#dbdbdb');
                    $cells->setFontColor('#000000');
                    $cells->setFontWeight('bold');
                    $cells->setFont(array(
                        'family' => 'Calibri',
                        'size'   => '9',

                    ));

                });

                $sheet->setStyle(array(
                    'font' => array(
                        'name' => 'Calibri',
                        'size' => 9,

                    ),
                ));

            });
        });
        $myFile   = $myFile->string('xlsx'); 
        $response = array(
            'name' => $name, 
            'file' => "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64," . base64_encode($myFile), 
        );

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

Ajax功能:

$(document).on('click', '.ExportJobs', function() {
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });
    var ids = [];
    $(".InvoiceCheckBox:checked").each(function(e) {
        ids.push(this.value);
    });
    data = {
        "ids": ids,
    };
    $.ajax({
        method: "POST",
        url: "/exportNew",
        data: data,
        success: function(response) {
            var a = document.createElement("a");
            a.href = response.file;
            a.download = response.name;
            document.body.appendChild(a);
            a.click();
            a.remove();
        }
    });
});

但是,如果我将字符串值从xlsx更改为csv,则使用上述控制器方法不会返回excel格式的文件,然后csv格式化文件将被下载。

我们如何下载excel格式的文件?有任何建议,拜托!

2 个答案:

答案 0 :(得分:1)

我知道这已经很晚了,但要为像我这样遇到同样问题的人发帖

我还需要通过使用ajax发布调用从Maatwebsite excel库中下载excel。

  1. 添加了一个按钮来触发ajax调用以下载excel文件

     <button onclick="downloadExcel()" id="btn-download-payroll" class="btn btn-dark-success btn-md" style="transform: translateY(50%); top: 50%; font-size: 13px;"><i aria-hidden="true" class="fa fa-cog mr-10"></i>
                            Download
                        </button>
    

使用以下js代码发布ajax请求

function downloadExcel() {
var salaryMonth = $("#dp-salary-month").datepicker("getDate");
var department = $("#cbox-department");
var month = new Date(salaryMonth).getMonth() + 1;
var year = new Date(salaryMonth).getFullYear();
$.ajax({
    xhrFields: {
        responseType: 'blob',
    },
    type: 'POST',
    url: '/downloadPayroll',
    data: {
        salaryMonth: month,
        salaryYear: year,
        is_employee_salary: 1,
        department: department.val()
    },
    success: function(result, status, xhr) {

        var disposition = xhr.getResponseHeader('content-disposition');
        var matches = /"([^"]*)"/.exec(disposition);
        var filename = (matches != null && matches[1] ? matches[1] : 'salary.xlsx');

        // The actual download
        var blob = new Blob([result], {
            type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        });
        var link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob);
        link.download = filename;

        document.body.appendChild(link);

        link.click();
        document.body.removeChild(link);
    }
});
}
routes / web.php 文件中

为我的控制器设置路径

Route::post('/downloadPayroll', 'Payroll\\Process\\PayrollController@downloadPayroll');

这里,我使用 maatwebsite / excel 库通过 FromQuery 方法生成excel文件,但是由于库更新,Excel :: create已由<: strong>“ maatwebsite / excel”:“ ^ 3.1” 在我的案例中,我使用了下载方法,这里是我的HelperClass根据我的要求生成记录

PayrollHelper.php

namespace App\Http\Helpers;

use App\PayrollEmployee;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\Exportable;

class PayrollHelper implements FromQuery
{
use Exportable;

public function forDepartment(int $department)
{
    $this->department = $department;
    return $this;
}

public function forMonth(string $month)
{
    $this->month = $month;
    return $this;
}

public function query()
{
// get the salary information for the given month and given department 
    return PayrollEmployee::query()->where(['salary_month' => $this->month,'department_id'=>$this->department]); 
}
}

最终在我的控制器中

class PayrollController extends Controller
{
public function downloadPayroll(Request $request)
{
    $file_name = '';


    try {
        $requestData = $request->all();
        $salary_month = $requestData['salaryMonth'];
        $salary_year = $requestData['salaryYear'];
        $department = $requestData['department'];
        $is_employee_salary = boolval($requestData['is_employee_salary']);
        $month = Carbon::createFromDate($salary_year, $salary_month);
        $month_start = Carbon::parse($month)->startOfMonth();
        $formated_month = Carbon::parse($month)->format('F Y');
        $file_name = 'Employee_salary_' . $formated_month . '.xlsx';

        // to download directly need to return file
        return Excel::download((new PayrollHelper)->forMonth($month_start)->forDepartment($department), $file_name, null, [\Maatwebsite\Excel\Excel::XLSX]);


    } catch (exception $e) {

    }
}
}

创建excel文件后,返回文件以ajax 响应为blob

就这样

答案 1 :(得分:0)

我也遇到了完全相同的问题,但是对我来说,我的代码可以正常工作,但是下载文件的内容不可读,而且仍然经过编码。

如果您可以帮助我,那就好了...

这里是ajax调用:


        $.ajax({
            type:"post",
            url: btnExportExcel.attr('data-url-export'),
            responseType:'document',
            data: {
                projetsJSON: JSON.stringify(projets)
            },
            success:function(data,status,xhr) {
                console.log("success")
                var disposition = xhr.getResponseHeader('content-disposition');
                var matches = /"([^"]*)"/.exec(disposition);
                var filename = (matches != null && matches[1] ? matches[1] : 'salary.xlsx');
                var blob = new Blob([data],{type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
                var downloadUrl = URL.createObjectURL(blob);
                var a = document.createElement("a");
                a.href = downloadUrl;
                a.download = filename
                document.body.appendChild(a);
                a.click();
            },
            error: function(jqXHR, textStatus,errorThrown) {
                alert(errorThrown);
            }
        })

它很好用,并以json发送数据。 之后,我调用从控制器加载此功能的路由:


/**
 * Fonction d'export Excel
 * @return Excel
 */
public function exportExcel(Request $request) {
    $projets = json_decode($request->projetsJSON);
    return Excel::download(new ProjetsExport($projets),'projets'. date('Y-m-d') . '.xlsx');
}

ProjetsExport类的构造函数中,我将在数组中解码的数据传递给参数:

<?php

namespace App\Exports;

use App\Models\Projet;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;

class ProjetsExport implements FromArray, WithHeadings, WithMapping
{

    protected $request;
    
    public function __construct($request)
    {
        $this->request = $request;
    }
    
    /**
    * @return array
    */
    public function array():array
    {   
        return $this->request;
    }

    /**
     * Initialisation des headers des colonnes du fichier Excel.
     */
    public function headings(): array
    {
        return ['Libellé','Date de création','Date de fin','Budget HT','Objectif','Etat','Type','Ouverture','Chef de projet','Famille'];
    }

    /**
     * Formattage des données.
     */
    public function map($row): array
    {
        return [
            $row->libelle,
            (new \DateTime($row->dt_creation))->format('d/m/Y'),
            (new \DateTime($row->dt_fin))->format('d/m/Y'),
            $row->budget_ht,
            $row->obj_collect,
            $row->type_proj,
            $row->ouverture,
            $row->chef_proj,
            $row->famille
        ];
    }
    
}

然后,如果上面显示的ajax调用成功,那么我将创建一个blob对象,然后下载该对象,并且得到了此类文档。

PK   HvSQG�D�X  �     [Content_Types].xml��MN�0���"�%nY ��vAa   �(0����ؖg�w{&i�@�nbE�{��y��d۸l
    m�����X�(���)���F��;@1_�����c)j�x/%��E��y�
�QĿi!��K� y3�J<���Z1�0?Y�L%zV
c��Ib7�����a/l٥P1:�q�r��j��j0A����u�""���(� ���W�M��)Tj�({ܲ�>�O��,X٭���>B��~׭���Ӥ6�J=�oBZ����t��X4���Cg�,���Qg mrL�ٯc�e��t��    Z�?����hPv��±��u�j���R������}�Cv��PK   HvSQ�78�   K     _rels/.rels���j�0��{
�{���1F�^ʠ�2��l�$���-}�y����Î��O��v�y�;�؋Ӱ.JP��޵^�����Yű�3G�Ww�g)���>�qQC��D���b!�]�i$L��3����2n���oT�:Z
�h����[��4�ი��]��yN�,ە�>�>�j

如果您有个主意,我很乐意提出建议,因为我现在有点卡住了...