How to force a download with ajax?

Asked

Viewed 2,852 times

6

I am using PHP’s DOMPDF class to generate reports of accounts receivable with dynamic filters.

The user selects the filters in a form and asks to generate, so far so good. But he will have the option to export what he filtered in PDF.

Today, I have the following jQuery code:

$('#exportPDF').click(function(){
        var relatorio = $('.relatorios').html();

        $.ajax({
            type: "POST",
            url: "acao.php?acao=exportPDF",
            data: 'relatorio='+relatorio,
            cache: false,
            beforeSend: function() {
                $('#loader').fadeIn(500);
            },
            complete: function() {
                $('#loader').fadeOut(500);
            },
            success: function (retorno) {
                console.log(retorno);
                $('.relatorios').html(retorno);

                // RETORNA MENSAGEM DE SUCESSO
                $.gritter.add({
                    title: 'Sucesso',
                    text: 'O download irá iniciar em breve.',
                    class_name: 'success'
                 });
            },
            error: function(data) {
                console.log(data);
            }
        });
    });

And I have the following code in PHP:

// Inclui classe DOMPDF
        require_once("../../../include/class/dompdf/dompdf_config.inc.php");

        // Recebe a tabela
        $relatorio = $_POST['relatorio'];

        $dompdf = new DOMPDF();

        $dompdf->load_html($relatorio);
        $dompdf->render();
        $dompdf->stream('relatorio_cliente.pdf');

The idea would be that when generating the PDF by PHP Ajax send to the browser/client the download request and the whole process flow. I’ve tried using headers in PHP and Ajax, among many other things. I’ve also looked for it on the internet and I’ve found some problems like mine, I just didn’t understand it very well.

You can do it?

3 answers

6


If I’m not mistaken, what you’re doing actually works in some browsers, but not in others. An alternative is to continue making the request ajax, and save the PDF to disk instead of trying to serve it as return of that request. Instead, pass the saved file URL as a response, and in the function success ajax use window.location = retorno.

  • I thought on this issue, the problem is that over time the server would fill with saved files unless I created a function to erase all X files in X days. What is your opinion?

  • You can schedule a task on the server, running every day and deleting files older than 1 day, or something like that.

  • Yes, perfect. I’ll take your suggestion, thanks @bfavaretto

1

I already did that and I couldn’t either. AJAX doesn’t receive PDF. In this case, I didn’t use ajax. I only opened a new page (_Blank) to force the download and after the download was done the page was automatically closed.

  • Yes, but how am I going to get this page to receive the contents of a certain table? Because with ajax, I get the whole html of the table and I get the pdf.

1

I went through a similar problem. After searching a little (too) on the net, I found this plugin: jQuery File Download (recommend to use together with this: jQuery URL Decoder)

The use is very simple, but has a little trick that gave me a lot of headache to find:

  1. Reference the plugin jquery.urldecoder.min.js
  2. Reference the plugin jquery.fileDownload.js

Example of my code:

var url = $.url.parse(window.location.href);

var href = $.url.build({
    protocol: url.protocol, //http|https
    host: url.host, //localhost|contoso.com
    port: url.port, //porta do web server 
    path: url.path + 'pdf.php', // url que receberá a requisição
    params: {
        param1: 'val1',
        param2: 'val2',
        param3: 'val3',
        paramN: 'valN',
    }
});
// output:
// http:// localhost:80/pdf.php?param1=param1&param2=param2&param3=param3

// prepara um modal de aviso ao usuário informando que o arquivo está sendo gerado (bootstrap)
var preparingFileModal = $("#preparing-file");
preparingFileModal.modal();

$.fileDownload(href, {
    successCallback: function(url) {
        // após a requisição ser completada com sucesso, fecha o modal
        setTimeout(function() {
            preparingFileModal.modal('hide');
        }, 3000);
    },
    failCallback: function(url) {
        // caso haja um erro na requisição, altera a mensagem do modal para callback do usuário
        preparingFileModal.find('.modal-body p').first().html('Ocorreu um erro ao tentar baixar o PDF.\n\nTente novamente mais tarde');
    }
});

Browser other questions tagged

You are not signed in. Login or sign up in order to post.