pdfHtml5 button to send table via PHPMailer

pdfHtml5 button to send table via PHPMailer

koppanmkoppanm Posts: 22Questions: 3Answers: 1
edited June 22 in Editor

Hi all,
I have partially succeeded with creating a send button to post filtered editor table data (using predefined search criteria) to phpmailer. The message comes thru, but the attachment file only contains "true".
Here is my code. Any help would be greatly appreciated.
Thanks,
Miklos

topStart: {
            buttons: [ 
                {
    extend: 'pdfHtml5',
    text: 'Send as PDF',
    title: 'DataTable Export',
    customize: function (doc) {
      // optional: customize PDF
    },
    action: function (e, dt, button, config) {
      let pdfDoc = window.pdfMake.createPdf(config);
      pdfDoc.getBlob(function (blob) {
        let formData = new FormData();
        formData.append("pdf", blob, "datatable.pdf");

        // send PDF to server via AJAX
        fetch("send_pdf_email_koppan.php", {
          method: "POST",
          body: formData,
        })
        .then(response => response.text())
        .then(result => alert("Email sent: " + result))
        .catch(error => alert("Error: " + error));
      });
    }
  },

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 64,755Questions: 1Answers: 10,713 Site admin

    Sounds like a problem in the send_pdf_email_koppan.php file rather than the client-side. Does the POST request include the generated PDF data?

    Allan

  • koppanmkoppanm Posts: 22Questions: 3Answers: 1
    edited June 23

    Dear Allan,
    Honestly, I do not know.
    Here is the <code>send_pdf_email_koppan.php</code> file:

    <?php
    require 'vendor/autoload.php'; // Composer: phpmailer/phpmailer
    
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\Exception;
    
    if (!isset($_FILES['pdf'])) {
        http_response_code(400);
        echo "No PDF received.";
        exit;
    }
    
    $tmpName = $_FILES['pdf']['tmp_name'];
    $originalName = $_FILES['pdf']['name'];
    $target = __DIR__ . '/' . $originalName;
    
    move_uploaded_file($tmpName, $target);
    
    // Send email with PHPMailer
    $mail = new PHPMailer(true);
    
    try {
        $mail->CharSet = "UTF-8";
        $mail->isSendmail();
        $mail->setFrom('no-reply@laparo.hu', 'GYN Team');
        $mail->addReplyTo('no-reply@laparo.hu', 'GYN Team');
        $mail->addAddress('name@icloud.com', 'Miklos Koppan');
        $mail->Subject = 'PDF tábla csatolva!';
        $mail->addCC('name@gmail.com', 'Viktoria Szanto');
        $mail->Body = 'PDF table export attached.';
        $mail->addAttachment($target);
    
        $mail->send();
        echo "PDF emailed successfully.";
    } catch (Exception $e) {
        echo "Mailer Error: {$mail->ErrorInfo}";
    }
    
  • allanallan Posts: 64,755Questions: 1Answers: 10,713 Site admin

    I would suggest checking the network inspector in your browser to make sure that the POST request has the PDF data. After that' I'd suggest checking that the file does get moved to the $target directory (you aren't deleting it, so it should still be present after the PHP file has completed its execution). See what that is and that it is a valid PDF. The result of that should hopefully inform you of what your next debugging action would be (i.e. if it isn't the PDF, trace back from there, etc).

    Allan

  • koppanmkoppanm Posts: 22Questions: 3Answers: 1

    Thank you Allan. I followed your instruction and checked first, wheter the file does get moved to the $target directory (since I am not deleting it, so it should still be present after the PHP file has completed its execution). Surprisingly, I have found no pdf file generated at all. I belive, the construction of the file is where the clue is. Will try a different approach, now it bothers me so much.

  • allanallan Posts: 64,755Questions: 1Answers: 10,713 Site admin

    Next step is to make sure that it is in the request body for the Ajax request the client-side is sending. Use the browser's network tools to check that.

    Allan

  • koppanmkoppanm Posts: 22Questions: 3Answers: 1
    edited June 26

    Will check further

  • koppanmkoppanm Posts: 22Questions: 3Answers: 1

    This is what I get. The button shows continuously spinning circle, and the "time" tab of inspector show "waiting" status.

    Summary
    URL: https://penzugy.laparo.hu/DTEditorOrvDiv/send_pdf_email_koppan.php
    Status: 200
    Source: Network
    Address: 185.33.55.22:443
    Initiator:
    table.orv_div.js:189

    Request
    :method: POST
    :scheme: https
    :authority: penzugy.laparo.hu
    :path: /DTEditorOrvDiv/send_pdf_email_koppan.php
    Accept: /
    Accept-Encoding: gzip, deflate, br
    Accept-Language: en-GB,en;q=0.9
    Connection: keep-alive
    Content-Length: 6189
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7n5FucJNBLtAKDGq
    Cookie: PHPSESSID=8f6a285a4cfae916baeaf4d9e47bff48; phpbb3_49udr_k=; phpbb3_49udr_sid=a42c1a28ab83a831cd38420a6168822f; phpbb3_49udr_u=2; phpbb3_49udr_ba_2=1744195485; phpbb3_49udr_ccat=%5B%22calendar_on_index%22%2C%22fid_14%22%5D; phpbb3_49udr_ba_1=1744136787; phpbb3_fn1je_k=; phpbb3_fn1je_sid=466e721fc17ea90b6d0a50fb641dcd81; phpbb3_fn1je_u=1
    Host: penzugy.laparo.hu
    Origin: https://penzugy.laparo.hu
    Referer: https://penzugy.laparo.hu/DTEditorOrvDiv/
    Sec-Fetch-Dest: empty
    Sec-Fetch-Mode: cors
    Sec-Fetch-Site: same-origin
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.6 Safari/605.1.15

    Response
    :status: 200
    Content-Type: text/html; charset=UTF-8
    Date: Thu, 26 Jun 2025 19:30:52 GMT
    Server: Apache

    Request Data
    MIME Type: multipart/form-data
    Boundary: ----WebKitFormBoundary7n5FucJNBLtAKDGq
    Request Data:

  • koppanmkoppanm Posts: 22Questions: 3Answers: 1

    I believe the clue is somewhere here:
    if (isset($_FILES['pdf']) && $_FILES['pdf']['error'] === UPLOAD_ERR_OK) {
    $uploadDir = sys_get_temp_dir();
    $uploadFile = $uploadDir . '/' . basename($_FILES['pdf']['name']);

    if (move_uploaded_file($_FILES['pdf']['tmp_name'], $uploadFile)) {
        $mail = new PHPMailer(true);
    

    I have not specified (nor created) an upload directory yet. May this be the reason?

  • kthorngrenkthorngren Posts: 22,160Questions: 26Answers: 5,101
    edited June 26

    I think the problem starts with this:

    let pdfDoc = window.pdfMake.createPdf(config);

    The config parameter is documented in buttons.buttons.action as:

    The button's configuration object

    PDFMake won't understand this object and won't be able to make a PDF out of it. Take a look at buttons.html5.js and find DataTable.ext.buttons.pdfHtml5. Here you will see how Datatables builds the document for pdfMake.createPdf().

    I'm not quite sure the best way to handle this as I've not done it before but you could take the relevant parts of that code and put in your action function or possibly add the ajax request to the end of the function in buttons.html5.js. If you modify buttons.html5.js then you will need to keep up those modifications every time you upgrade buttons.

    Another option might be to use buttons.exportData() to get teh table data, in the buttons.buttons.action function, to send via ajax to a server based PHP PDF library.

    Kevin

  • koppanmkoppanm Posts: 22Questions: 3Answers: 1
    edited June 27

    Hi all,
    I have finally managed it with success.
    Thank you for all your efforts trying to help me achieve this.
    For those being in a similar scenario, I would like to share how this can be done.
    Many thanks once more,

    Yours sincerely,
    Miklos

    -- JS button config --

    buttons: [ 
                    {
        extend: 'pdfHtml5',
        text: '<i class="fa-solid fa-file-pdf"></i> Email to..',
        className: 'btn btn-sm', 
        title: 'DataTable Export',
        
        customize: function (doc) {
          // optional: customize PDF
        },
        action: function (e, dt, button, config) {
      // Step 1: Get filtered data from the table
      const data = dt.rows({ search: "applied" }).data().toArray();
    
      // Step 2: Create header and rows
      const headers = [
        "dátum", "név", "műtét", "operatőr", "assziszt", "orvosdíj", "státusz", "számlára"
      ];
      const rows = data.map(row => [
        row.date,
        row.name,
        row.op,
        row.surgeon,
        row.assist,
        row.orv.toLocaleString("hu-HU"),
        row.state,
        parseInt(row.orv_div).toLocaleString("hu-HU")
      ]);
    
      // Step 3: Calculate the total
      const total = data.reduce((sum, row) => sum + parseInt(row.orv_div || 0), 0);
      const totalRow = [
        "", "", "", "", "", "", "Total:", total.toLocaleString("hu-HU") + " Ft"
      ];
    
      // Step 4: Define PDF document
      const docDefinition = {
        watermark: {
        text: 'Watermark text',       // Your watermark text
        color: 'gray',           // Optional
        opacity: 0.1,            // Between 0 and 1
        bold: true,              // Optional
        italics: false,          // Optional
        fontSize: 60             // Size of the watermark text
      },
        pageOrientation: "landscape",
        content: [
          { text: 'Text comes here', style: 'header' },
          {
            style: 'tableExample',
            table: {
              headerRows: 1,
              body: [headers, ...rows, totalRow]
            },
            layout: 'lightHorizontalLines'
          }
        ],
        styles: {
          header: {
            fontSize: 18,
            bold: true,
            margin: [0, 0, 0, 10]
          },
          tableExample: {
            margin: [0, 5, 0, 15]
          }
        }
      };
    
      // Step 5: Send PDF via AJAX
      pdfMake.createPdf(docDefinition).getBlob(function (blob) {
        const formData = new FormData();
        formData.append("pdf", blob, "filename.pdf");
    
        fetch("send_pdf.php", {
          method: "POST",
          body: formData
        })
        .then(response => response.text())
        .then(result => {
          alert("Email sent successfully.\n\n" + result);
        })
        .catch(error => {
          alert("Error: " + error);
        });
      });
    }
    ]
    

    -- PHP file --

    <?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);
    
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\Exception;
    
    require '../PHPMailer/vendor/autoload.php'; // Adjust if needed
    
    echo "Step 1: PHP is running!\n";
    echo "Step 2: PHPMailer loaded\n";
    
    // Create log
    file_put_contents("log.txt", "Script started\n", FILE_APPEND);
    
    // Check file upload
    if (!isset($_FILES['pdf'])) {
        echo "No PDF uploaded.\n";
        file_put_contents("log.txt", "No PDF in \$_FILES\n", FILE_APPEND);
        exit;
    }
    
    $tmpPath = $_FILES['pdf']['tmp_name'];
    $fileName = $_FILES['pdf']['name'];
    $fileSize = $_FILES['pdf']['size'];
    
    file_put_contents("log.txt", "Received file: $fileName ($fileSize bytes)\n", FILE_APPEND);
    
    if ($fileSize < 100) {
        echo "File too small.\n";
        file_put_contents("log.txt", "File too small or empty\n", FILE_APPEND);
        exit;
    }
    
    move_uploaded_file($tmpPath, "filename.pdf");
    file_put_contents("log.txt", "Saved telj_ig.pdf\n", FILE_APPEND);
    
    // Now send the email
    $mail = new PHPMailer(true);
    // DEBUG
    $mail->SMTPDebug = 2;
    $mail->Debugoutput = function($str, $level) {
        file_put_contents("mail_debug.txt", "Level $level: $str\n", FILE_APPEND);
    };
    
    try {
        $mail->isSMTP();
        $mail->Host       = 'smtp.gmail.com';         // Your SMTP server
        $mail->SMTPAuth   = true;
        $mail->Username   = 'me@domain.hu'; // Your Gmail or SMTP address
        $mail->Password   = 'pwd';      // Use Gmail App Password
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        $mail->Port       = 587;
    
        $mail->setFrom('me@domain.hu', 'team');
        $mail->addReplyTo('no-reply@domain.hu', 'Do Not Reply');
        $mail->addAddress('me@domain.hu', 'Me');
    
    
        // Add BCC recipients
        $mail->addBCC('you@gmail.com', 'You');
    
        $mail->isHTML(true); // THIS IS THE LINE
    
        $mail->Subject = 'My subject';
        
        
        $mail->Body = '
        <p>My message></p>
        ';
    
        $mail->addAttachment('filename.pdf');
    
        $mail->send();
        echo "SMTP mail sent successfully.\n";
        file_put_contents("log.txt", "SMTP mail sent successfully\n", FILE_APPEND);
    } catch (Exception $e) {
        echo "SMTP Mailer Error: " . $mail->ErrorInfo;
        file_put_contents("log.txt", "SMTP Mailer Error: " . $mail->ErrorInfo . "\n", FILE_APPEND);
    }
    
  • allanallan Posts: 64,755Questions: 1Answers: 10,713 Site admin
    Answer ✓

    Hi Miklos,

    Nice one! Thanks for sharing your solution with us :).

    Allan

Sign In or Register to comment.