0

I was trying to generate pdf files in a asynchronous way with html2pdf.js.

The generation of PDF files works very well but I would like the waiting process at the end of the geeneration of all the files to display the result in the elemé Div.Alert with the list of generated files and their path access and hide the loading that everything is finished. Look function convertToPdf()

I wrote this code but there is what is wrong, thank you for your help

var envLabSub = ['env1', 'env2'];

//call function to convert in PDF
convertToPdf(msg, subject);

function convertToPdf(msg, subject) {
    envLabSub.forEach(async env => {
        await printer(msg, subject, env);
    })
        var message = "<h3><span class='glyphicon glyphicon-warning-sign' aria-hidden='true'></span> Email was sent with success !!</h3>";

    $("div.alert").removeClass().addClass('alert alert-success').html(message);
    $("div.alert").append("<ul></ul>");
    
    returArray.forEach(function (pdf) {
        $("div.alert ul").append("<li>File :<b>" + pdf.fileName + "</b> was created with success<br><a href='" + pdf.path + "' target='_blank'>" + pdf.path + "</a></ii>");
    });
    
    $("div.alert").show();
    $(".loading").hide();
}

async function printer(msg, subject, env) {

    var divToPrint = $('<div/>').append(msg);
    var versionTarget = $('#inpTargetVersion').val();
    var service = $('#Select_Service option:selected').text();
    var returArray = [];

    // date export Csv
    var MyDate = new Date();
    var datePdf = MyDate.getFullYear() + "-" + ('0' + (MyDate.getMonth()+1)).slice(-2) + "-" + ('0' + MyDate.getDate()).slice(-2) + "_" + ('0' + MyDate.getHours()).slice(-2) + ('0' + MyDate.getMinutes()).slice(-2) + ('0' + MyDate.getSeconds()).slice(-2);
    var fileName = datePdf + "_" + env.replace('/','_').trim() + "_" + service.trim() + "_" + versionTarget + ".pdf";
    
    var worker = html2pdf();
    await worker.from(divToPrint[0]);
    let myPdf = await worker.outputPdf('datauristring', 'mypdf.pdf');
  
    //this converts the uri to blob
    var preBlob = dataURItoBlob(myPdf);
    var file = new File([preBlob], fileName, {type: 'application/pdf'});
   
    // sends the message to api
    sendFile(file);
}

async function sendFile(userFiles) {
    let filePaths;
    let formData = new FormData();
    formData.append("filePdf", userFiles);
    let response = await fetch('views/ajax_response.php', {
        method: 'POST',
        body: formData
    });
        
    filePaths = await response.json();
    return filePaths;
}

function dataURItoBlob(dataURI) {
    // convert base64/URLEncoded data component to raw binary data held in a string
    var byteString;
    if (dataURI.split(',')[0].indexOf('base64') >= 0)
        byteString = atob(dataURI.split(',')[1]);
    else
        byteString = unescape(dataURI.split(',')[1]);

    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

    // write the bytes of the string to a typed array
    var ia = new Uint8Array(byteString.length);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }

    return new Blob([ia], {type:mimeString});
}

1 Answers1

0

You could try using Promise.all(), and wrap the foreach loop with it. Like so:

    await Promise.all(envLabSub.forEach(async env => {
        await printer(msg, subject, env);
    }))

Similar to this answer: https://stackoverflow.com/a/32828546/13190911