function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Spencer Widman 9Spencer Widman 9 

Visual Force Page and Apex Class for Render as Pdf Email Attachement

Good Evening, 

I am struggling with finding the error in 2 items.  The first is a visualforce page to create a QR code ticket.  I am going to render as pdf and then call the apex in a flow and attach to an email.  For some reason my QR code is not displaying.  I have tried QRcode.js, google, and quickart.io and have not been able to get any of them to render the QR code.  Here is my visualforce page.
 
<apex:page standardController="Event_Registration__c" renderAs="pdf">
    <head>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
    </head>
    <body>
        <script>
            // Generate the QR code using QRCode.js
            var qrCode = new QRCode(document.createElement('canvas'), {
                width: 150,
                height: 150
            });
            qrCode.makeCode("{!Event_Registration__c.Id}");

            // Get the data URL for the canvas and render it as an image
            var qrCodeDataURL = qrCode._el.toDataURL("image/png");
            var qrCodeImage = document.createElement('img');
            qrCodeImage.src = qrCodeDataURL;

            // Append the image to the output panel
            var outputPanel = document.getElementById('outputPanel');
            outputPanel.appendChild(qrCodeImage);
        </script>
        <apex:outputPanel id="outputPanel" layout="none"/>
    </body>
</apex:page>

The other issue I am running into is the Apex class to generate the output.  I think it's a syntax issue but I have been unable to track it down.  Here is the apex class I am working with
 
public class EventRegistrationPDFGenerator {
  public static Blob generatePDF(Event_Registration__c reg) {
      // Create a new PageReference object for the modified Visualforce page
      PageReference pdfPage = new PageReference('/apex/EventRegistrationPDFWithQRCode');
      pdfPage.getParameters().put('id', reg.Id);

      // Generate the PDF and store it as a Blob
      Blob pdfBlob = pdfPage.getContentAsPdf();

      // Combine the PDF and QR code into a single file
      Blob attachmentBlob = combinePDFAndQRCode(pdfBlob, generateQRCode(reg.Id));

      // Send the combined file as an email attachment using Send Better Email
      Map<String, Object> emailParams = new Map<String, Object>();
      emailParams.put('toAddress', reg.Contact__r.Email);
      emailParams.put('subject', 'Event Registration PDF with QR code');
      emailParams.put('body', 'Please find attached the Event Registration PDF with QR code.');
      emailParams.put('attachments', new List<Messaging.EmailFileAttachment>{
          new Messaging.EmailFileAttachment{
              filename = 'Event Registration.pdf',
              body = attachmentBlob
          }
      });
      sendBetterEmail.SendEmail(emailParams);

      // Return the combined file as a Blob object
      return attachmentBlob;
  }

  private static Blob generateQRCode(Id regId) {
      // Create a new QRCode object with the registration ID as the data
      QRCode qrCode = new QRCode();
      qrCode.setData(regId);
      qrCode.setDimension(150);
      qrCode.setMargin(0);

      // Get the data URL for the canvas and return it as a Blob
      String qrCodeDataURL = qrCode.toDataURL();
      String base64Data = qrCodeDataURL.split(',')[1];
      Blob qrCodeBlob = EncodingUtil.base64Decode(base64Data);
      return qrCodeBlob;
  }

  private static Blob combinePDFAndQRCode(Blob pdfBlob, Blob qrCodeBlob) {
      // Convert the PDF and QR code Blobs to Byte Arrays
      List<Byte> pdfArray = pdfBlob.toByteArray();
      List<Byte> qrCodeArray = qrCodeBlob.toByteArray();

      // Create a new Byte array that can hold both arrays
      List<Byte> combinedArray = new List<Byte>();
      combinedArray.addAll(pdfArray);
      combinedArray.addAll(qrCodeArray);

      // Convert the combined array back to a Blob and return it
      Blob combinedBlob = Blob.valueOf(combinedArray);
      return combinedBlob;
  }
}

<apex:page standardController="Event_Registration__c" renderAs="pdf">
    <head>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
    </head>
    <body>
        <script>
            // Generate the QR code using QRCode.js
            var qrCode = new QRCode(document.createElement('canvas'), {
                width: 150,
                height: 150
            });
            qrCode.makeCode("{!Event_Registration__c.Id}");

            // Get the data URL for the canvas and render it as an image
            var qrCodeDataURL = qrCode._el.toDataURL("image/png");
            var qrCodeImage = document.createElement('img');
            qrCodeImage.src = qrCodeDataURL;

            // Append the image to the output panel
            var outputPanel = document.getElementById('outputPanel');
            outputPanel.appendChild(qrCodeImage);
        </script>
        <apex:outputPanel id="outputPanel" layout="none"/>
    </body>
</apex:page>

Does anyone see any glaring errors?

Thanks!
 
Prateek Prasoon 25Prateek Prasoon 25
——-> Regarding the first issue, it is difficult to determine the exact cause of the problem without additional information such as error messages, behavior, and context. However, one possible issue could be that the QR code image is not being properly appended to the output panel. You could try adding a console log to check if the QR code image is being generated correctly and if it is being appended to the output panel. For example, you could add the following line after creating the QR code image:
console.log(qrCodeImage);
This should output the QR code image object to the console, allowing you to inspect it and determine if it is being generated correctly.
——> As for the second issue, there is a syntax error in the generateQRCode method. The setData method of the QRCode class expects a string, but it is being passed an Id object. To fix this, you can convert the Id object to a string before passing it to the setData method. Here is the corrected code:

private static Blob generateQRCode(Id regId) {
// Convert the registration ID to a string
String regIdString = String.valueOf(regId);

// Create a new QRCode object with the registration ID as the data
QRCode qrCode = new QRCode();
qrCode.setData(regIdString);
qrCode.setDimension(150);
qrCode.setMargin(0);

// Get the data URL for the canvas and return it as a Blob
String qrCodeDataURL = qrCode.toDataURL();
String base64Data = qrCodeDataURL.split(',')[1];
Blob qrCodeBlob = EncodingUtil.base64Decode(base64Data);
return qrCodeBlob;
}

If you find my answer helpful, please mark it as the best answer. Thanks!