简体   繁体   中英

Create PDF file from php ajax (post) request result in javascript

I've been searching through the web but it seems that nobody is having the same issue as me.

I'm trying to create a pdf file from post request to a php file that return a PDF 1.7 content.

Here is my code in js:

    function generateInvoices() {
  $.post(invoiceGenerationURL, { order_id: ordersID }).done(function (data) {
    document.write(data)
  });
}

I'm just writing the result to see what's the output. I've tried to use jsPDF, but it didn't work and gave me an empty pdf file.

Here is my Php code:

if (isset($_POST['order_id'])) {
    $id_orders = json_decode($_POST['order_id']);
    $pdfs = array();
    foreach ($id_orders as $id_order) {
        $order = new Order((int) $id_order);
        if (!Validate::isLoadedObject($order)) {
            die('The order cannot be found within your database for order :' . $id_order);
        }

        $order_invoice_list = $order->getInvoicesCollection();
        Hook::exec('actionPDFInvoiceRender', ['order_invoice_list' => $order_invoice_list]);

        $context = Context::getContext();

        $pdf = new PDF($order_invoice_list, PDF::TEMPLATE_INVOICE, $context->smarty);

        $pdfs[] = $pdf->render('I');
    }
    return $pdfs; 
    }

I'm creating an array of pdf files content to then generate a pdf with all the invoices in the same file, I'm on prestashop 1.7

This is the output:

%PDF-1.7 %���� 6 0 obj << /Type /Page /Parent 1 0 R /LastModified (D:20220224103446+01'00') /Resources 2 0 R /MediaBox [0.000000 0.000000 595.276000 841.890000] /CropBox [0.000000 0.000000 595.276000 841.890000] /BleedBox [0.000000 0.000000 595.276000 841.890000] /TrimBox [0.000000 0.000000 595.276000 841.890000] /ArtBox [0.000000 0.000000 595.276000 841.890000] /Contents 7 0 R /Rotate 0 /Group << /Type /Group /S /Transparency /CS /DeviceRGB >> /Annots [ 5 0 R ] /PZ 1 >> endobj 7 0 obj <> stream x��][s�F�~ϯ@թS��2��_��r┣(��'[�}`$:��dҡ��y۟�K��t 0��(^#ѩ$p�|}��i�Tj�?�|��_�������o��߾��2��5M(II�'����^~A6~����p��_Ë�o�u�&���.���=��q^6�$�IB���C��n<��O��yݣ�UdCn��I�PB���ƞ#jS'22K��s�0� FX*(��{M<س���;P��?��b�[���,����7"�Y�*n�d(O 3Z���:�痯O^^��8�ۿ�����Z��p���u�Bw��ؼ��PkS�e��4�l?IQ�*b���lE�PR�U�d��F�"�+���,,�У�8���(��lV(,ڦ���z}dI�3�޽tO�_?

...data...

�����Ǐ�����˵jӦ����u��Td��.�{�9�������M@�xKӈ,���٦Bi�5�ڦ/4.4�Q�i��V�s�Pg��7��G�М��)#Y�M~jq���de�~!!�_�@� endstream endobj 2 0 obj << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] /Font << /F1 3 0 R /F2 4 0 R >> /XObject << /I0 8 0 R /I1 9 0 R /I2 10 0 R /I3 11 0 R /I4 12 0 R /I5 13 0 R /I6 14 0 R /I7 15 0 R /I8 16 0 R /I9 17 0 R /I10 18 0 R /I11 19 0 R >> >> endobj 5 0 obj <> /H /I>> endobj 20 0 obj << /Producer (��TCPDF 6.3.2 \(http://www.tcpdf.org\)) /CreationDate (D:20220224103446+01'00') /ModDate (D:20220224103446+01'00') /Trapped /False >> endobj 21 0 obj << /Type /Metadata /Subtype /XML /Length 4223 >> stream application/pdf 2022-02-24T10:34:46+01:00 2022-02-24T10:34:46+01:00 2022-02-24T10:34:46+01:00 TCPDF 6.3.2 (http://www.tcpdf.org) uuid:32a9224a-f541-2ff9-5709-cc9cd0bf3a56 uuid:32a9224a-f541-2ff9-5709-cc9cd0bf3a56 http://ns.adobe.com/pdf/1.3/ pdf Adobe PDF Schema http://ns.adobe.com/xap/1.0/mm/ xmpMM XMP Media Management Schema internal UUID based identifier for specific incarnation of a document InstanceID URI http://www.aiim.org/pdfa/ns/id/ pdfaid PDF/A ID Schema internal Part of PDF/A standard part Integer internal Amendment of PDF/A standard amd Text internal Conformance level of PDF/A standard conformance Text endstream endobj 22 0 obj << /Type /Catalog /Version /1.7 /Pages 1 0 R /Names << >> /ViewerPreferences << /Direction /L2R >> /PageLayout /SinglePage /PageMode /UseNone /OpenAction [6 0 R /FitH null] /Metadata 21 0 R >> endobj xref 0 23 0000000000 65535 f 0000008325 00000 n 0000020164 00000 n 0000008384 00000 n 0000008490 00000 n 0000020410 00000 n 0000000015 00000 n 0000000483 00000 n 0000008601 00000 n 0000008872 00000 n 0000010321 00000 n 0000010593 00000 n 0000012132 00000 n 0000012404 00000 n 0000014038 00000 n 0000014310 00000 n 0000016027 00000 n 0000016299 00000 n 0000018130 00000 n 0000018402 00000 n 0000020626 00000 n 0000020824 00000 n 0000025130 00000 n trailer << /Size 23 /Root 22 0 R /Info 20 0 R /ID [ <32a9224af5412ff95709cc9cd0bf3a56> <32a9224af5412ff95709cc9cd0bf3a56> ] >> startxref 25339 %%EOF

The result is badly encoded whereas this is set in the php header:

                    header('Content-Type: application/pdf');
                if (headers_sent()) {
                    $this->Error('Some data has already been output to browser, can\'t send PDF file');
                }
                header('Cache-Control: private, must-revalidate, post-check=0, pre-check=0, max-age=1');
                //header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
                header('Pragma: public');
                header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
                header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
                header('Content-Disposition: inline; filename="'.basename($name).'"');

I don't really find out what is wrong, and how to get the pdf value of each pdf invoices to merge it in only one pdf file.

I'm not an expert in Javascript and Jquery.

Finally found a way to do it:

All the strval of the pdf file need to be base64 encoded

if (isset($_POST['order_id'])) {
$id_orders = json_decode($_POST['order_id']);

$count = 0;
foreach ($id_orders as $id_order) {
    $order = new Order((int) $id_order);
    if (!Validate::isLoadedObject($order)) {
        die('The order cannot be found within your database for order :' . $id_order);
    }

    $order_invoice_list = $order->getInvoicesCollection();
    Hook::exec('actionPDFInvoiceRender', ['order_invoice_list' => $order_invoice_list]);

    $context = Context::getContext();

    $pdf = new PDF($order_invoice_list, PDF::TEMPLATE_INVOICE, $context->smarty);

    $pdfs[]= strval(base64_encode($pdf->render(false)));
}
echo json_encode($pdfs);

}

Then I can download it like that

  $.post(invoiceGenerationURL, { order_id: ordersID }).done(function (data) {
$.parseJSON(data).forEach((element) => {
  var a = document.createElement("a");
  a.href = "data:application/pdf;base64," + element["data"];
  a.download = element["orderID"]; //update for filename
  document.body.appendChild(a);
  a.click();
  // remove `a` following `Save As` dialog,
  // `window` regains `focus`
  window.onfocus = function () {
    document.body.removeChild(a);
  };
});

});

I'm working on a pdf merger and will update my answer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM