Search code examples
htmlemailqr-code

Formatting QR Codes in HTML emails using the <pre> tag


I'm writing an online booking system that sends a QR code as part of a confirmation email / electronic ticket.

The email is in HTML format and, because many people turn off images in their email client, I'm investigating displaying the QR Code in the body of the message using the <pre> tag.

This way the QR Code will display regardless of the email client setting on displaying images or not.

Here is what I have so far:

<pre style="font-family: 'Lucida Console', Monaco, monospace; font-size: 8px; font-weight: 900; padding: 0; letter-spacing: 0; line-height: 8px; ">



     ███████  █  █ ███████     
     █     █ █  █  █     █     
     █ ███ █  █    █ ███ █     
     █ ███ █ █  █  █ ███ █     
     █ ███ █   ███ █ ███ █     
     █     █ ███ █ █     █     
     ███████ █ █ █ ███████     
               ███             
     █████ ████  ██ █ █ █      
     █ █ █   ██  █  █  █       
     █ █  ███████ █  █ █
     ██  █   ██     ██ ███     
      ███  █    █ █  █ ██      
             █  ████  █        
     ███████ █ █ █ ██    █     
     █     █   █████  █        
     █ ███ █ ██  █  █  █       
     █ ███ █ ██  █  █  █       
     █ ███ █ ██ █ █  ███       
     █     █ ███    ██ ██      
     ███████ ████ █  ███       



</pre>

This is almost looking okay in Outlook, but in gmail it looks terrible:

pre tag in email reader

I have a few questions and I'm hoping someone can point me in the right direction:

  1. Is there a trick to get gmail to observe the line height?
  2. Is there a better font to use? I'm using 'Lucida Console' which gives me a 8px x 6px rectangle but I ideally want a monospace font that is square.

Solution

  • In the end I gave up on trying to represent a QR code as HTML. There were too many problems that could not be overcome, including the fact that chrome didn't like printing background colours in tables so the qrcode wouldn't print.

    However, I did manage to embed the image into the email so it showed up in outlook and gmail without the user having to download an image.

    In case someone else is trying to embed QR Codes (or other images) into emails so that they show immediately, I'll put my solution here.

    The important thing is to use a linked resource and reference it correctly in your HTML:

    ...
    <p><img src=""cid:{0}"" alt=""booking barcode"" /><br></p>
    ...
    

    I used the following references:

    using System.Drawing.Imaging;
    using System.IO;
    using System.Linq;
    using System.Net.Mail;
    using System.Net.Mime;
    

    When creating my email:

    public class BookingConfirmation : MailMessage
    {
        public BookingConfirmation( ... )
        {
            To.Add( ... );
            Subject = "...";
    
            // create some html for the email
            var html = String.Format(
            @"<!DOCTYPE HTML PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN"" 
            ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"">
            <html xmlns=""http://www.w3.org/1999/xhtml\"">
            <head>
            <meta http-equiv=""Content-Type"" content=""text/html; charset=utf-8"" />
            <meta name=""viewport"" content=""width=device-width, initial-scale=1.0"" />
            <title>My Title</title>
            </head>
            <body style=""font-family: Arial, sans-serif; font-size: 12px;"">
            <p><img src=""cid:{0}"" alt=""booking barcode"" /><br></p>
            </body>
            </html>","myuniqueid1234" );
    
            // create an html view
            var htmlView = AlternateView.CreateAlternateViewFromString(html, 
                                                                       Encoding.UTF8, 
                                                                       MediaTypeNames.Text.Html);
    
            // get an image as a memory stream
            var memoryStream = new MemoryStream();
            var qrCodeImage =  ... however you want to access your image ...;
            qrCodeImage .Save(memoryStream, ImageFormat.Jpeg);
            memoryStream.Position = 0;
    
            // add it as a linked resource to the alternate view
            var linkedImage = new LinkedResource(memoryStream, MediaTypeNames.Image.Jpeg)
            {
                ContentId = "myuniqueid1234" // this needs to match for <img src=""cid:{0}""
            }; 
    
            // add the linked resource to the html format alternate view
            htmlView.LinkedResources.Add(linkedImage) ;
            AlternateViews.Add(htmlView);
        }
    }