Use SAS to send an email that embeds a graph in the body of the email

17

send an email that embeds a graphWhen using the SAS® system to email graphics output, a common request is to use SAS to send an email in which the graphics output is embedded in the body of the email. This functionality is not available until the second maintenance release for SAS® 9.4 (TS1M2). If you are using a version of SAS earlier than SAS 9.4 TS1M2, your best option is to create graphics output in a format such as RTF or PDF, and then attach the RTF or PDF file to your email.

Using the INLINED Option to Embed Graphics

If you are running SAS 9.4 TS1M2 or later, you can embed graphics output in an email. To do this, use the INLINED suboption with the ATTACH option in a SAS FILENAME statement that uses the EMAIL engine. Here is an example:

filename sendmail email to=("first.last@company.com")          from=("first.last@company.com")
    attach=("c:\temp\email.png" inlined='sgplot')
    type='text/html' subject="Emailing graphics output";

 

Then, later in your code, reference the value specified for the INLINED option in DATA step code that creates custom HTML output, as shown below:

    data _null_;  
        file sendmail;  
  put '<html>';
  put '<body>';
  put '<img src=cid:sgplot>';
  put '</body>';
  put '</html>';
run;

With this technique, although the graph is sent as an attachment, the attachment is hidden. When the email recipient opens the email, the attached graph is automatically displayed in the email (so that it looks like the graph is embedded in the body of the email).

Note: When using SAS to email graphics output, you must first set the EMAILSYS system option to SMTP and the EMAILHOST system option to the name of the SMTP email server at your site.

Embedding Multiple Graphs

You can also send multiple graphs in a single email using a SAS FILENAME statement as shown here:

                        filename sendmail email to=("first.last@company.com") from=("first.last@company.com")
    attach=("c:\temp\email1.png" inlined='sgplot1'  "c:\temp\email2.png" inlined='sgplot2')
    type='text/html' subject="Emailing graphics output";

Then, create custom HTML output using DATA step code similar to the following:

     Data _null_;  
       file sendmail;  
 put '<html>';
 put '<body>';
 put '<img src=cid:sgplot1>';
 put '<img src=cid:sgplot2>';
 put '</body>';
 put '</html>';
    run;

Embedding a Graph and a PROC PRINT Table

This example shows how to embed a graph and PRINT procedure table in one email. Let us assume that you have a graph named sgplot.png stored in C:\Temp. You want to send an email using SAS that displays the SGPLOT graph in the body of the email directly before a table created with PROC PRINT. The following sample code demonstrates how to do this using a TITLE statement with PROC PRINT:

filename sendmail email  to=("first.last@company.com") from=("first.last@company.com")
     attach=("c:\temp\sgplot.png" inlined='sgplot') 
     type='text/html' subject="Email test of GRAPH output";
      ods _all_ close; 
ods html file=sendmail; 
title1 '<img src=cid:sgplot>';
proc print data=sashelp.class; 
run;
ods html close; 
ods listing; 
filename sendmail clear;

Embedding a Graph (Complete Program)

Here is a complete sample program that demonstrates embedding graphics in an email using graphics output created with the SGPLOT procedure:

%let workdir=%trim(%sysfunc(pathname(work)));
ods _ALL_ close; 
ods listing gpath="&workdir";
ods graphics / reset=index outputfmt=PNG imagename='email';  
title1 'Graph output emailed using SAS';
proc sgplot data=sashelp.cars; 
  bubble x=horsepower y=mpg_city size=cylinders;
run;
filename sendmail email to=("first.last@company.com") from=("first.last@company.com")
     attach=("&workdir./email.png" inlined='sgplot')
     type='text/html' subject="Emailing graphics output";
      data _null_;
 file sendmail;  
 put '<html>';
 put '<body>';
 put '<img src=cid:sgplot>';
 put '</body>';
 put '</html>';
run; 
      filename sendmail clear;

In conclusion, if you are running SAS 9.4 TS1M2 or later, using the INLINED option in a FILENAME statement is an excellent option when emailing graphics output.  Note that you can use this technique to email any graphics file in PNG, GIF, or JPEG format created with the SAS SG procedures, ODS Graphics, or SAS/GRAPH® procedures (such as GPLOT and GCHART).  You can also use this technique to email graphics files created with software other than SAS.

Share

About Author

Martin Mincey

Senior Technical Support Analyst, SAS Technical Support

Martin Mincey is a Senior Principal Technical Support Analyst in the Foundation SAS group in Technical Support. He has been in SAS Technical Support since 1984. His main areas of expertise are SAS/GRAPH, ODS, and ODS Graphics.

17 Comments

    • Martin Mincey
      Martin Mincey on

      Hi Roman,

      Are you currently using the older SAS/GRAPH procedures (such as GPLOT or GCHART)? Or are you using the newer SG procedures (such as SGPLOT)?

      Regards, Martin

  1. hi there, thank you for sharing the code.
    I am trying to add image to the email its added well by it is left justified i wanted bring in center of body of email. please help with syntax.
    regards Mary

    • Martin Mincey
      Martin Mincey on

      Hi Mary,

      To center justify an image embedded in the body of an email, try using DATA step code similar to the following...

      data _null_;  
        file sendmail;  
        put '<html>';
        put '<body>';
        put '<table align="center"> <tr> <td>';
        put '<img align="middle" src=cid:sgplot class="center">';
        put '</td> </tr> </table>';
        put '</body>';
        put '</html>';
      run;

      Regards, Martin

  2. Thank you for your post, Martin.
    How can I make this work if I have two proc sgplot (meaning two graphs to display in the body of email)?

    • Martin L Mincey on

      There is a section in the blog with the section heading of "Embedding multiple graphs" that contains information that should answer your question. This section shows how to send two SGPLOT graphs in a single email. It involves specifying multiple graphs in the ATTACH option, such as:

      filename sendmail email to=("first.last@company.com") from=("first.last@company.com")
      attach=("c:\temp\email1.png" inlined='sgplot1' "c:\temp\email2.png" inlined='sgplot2')
      type='text/html' subject="Emailing graphics output";

      And then referencing the two PNG graphs later on in the code as CID:SGPLOT1 and CID:SGPLOT2.

      Regards, Martin

      • Thank you for your reply, Martin.
        Yes, your option will work too.
        I was thinking of outputting multiple graphs into one .png file and then attach it.

        • Martin Mincey on

          Note that there is not an easy way to write multiple graphs to a single PNG graph file. This is not due to restrictions in SAS, but just the way the PNG graph format was originally designed. But if you need to write multiple graphs to a single PNG graph file, you will need to use the following 3 step process:
          Step 1: Use SGPLOT to write multiple PNG graph files to disk.
          Step 2: Use PROC GSLIDE with the IBACK graphics option to read the graphs from step 1 back into SAS.
          Step 3: Use PROC GREPLAY to "replay" the graphs created in step 2 into a single PNG graph file.
          Here is sample SAS code which demonstrates how to put two SGPLOT graphs (one above the other) in a single PNG graph file:

          %macro delcat(catname);

          %if %sysfunc(cexist(&catname))
          %then %do;
          proc greplay nofs igout=&catname;
          delete _all_;
          run;
          quit;
          %end;
          %mend delcat;

          %delcat(work.gseg)

          %let outdir=%trim(%sysfunc(pathname(work)));

          options orientation=landscape nodate nonumber;

          goptions reset=all;

          /* This step uses multiple PROC SGPLOT procedures */
          /* to write multiple PNG files to disk. Note that */
          /* this step uses the IMAGENAME= option on the ODS */
          /* GRAPHICS ON statement to name each PNG file */
          /* that is written to disk. */

          ods _all_ close;
          ods listing gpath="&outdir" image_dpi=300;

          ods graphics on / reset=all imagename='sgplot1'
          width=5in height=4in;

          title1 'Graph for Females';
          proc sgplot data=sashelp.class;
          histogram height;
          density height;
          density height / type=kernel;
          where sex="F";
          run;

          ods graphics on / reset=all imagename='sgplot2'
          width=5in height=4in;

          title1 'Graph for Males';
          proc sgplot data=sashelp.class;
          histogram height;
          density height;
          density height / type=kernel;
          where sex="M";
          run;

          /* This step uses PROC GSLIDE with the IBACK= and */
          /* IMAGESTYLE= graphics options to read the PNG */
          /* files created in step 1 back into SAS. */

          goptions reset=all device=png300 nodisplay
          xmax=5in ymax=4in;

          goptions iback="&outdir.\sgplot1.png" imagestyle=fit;

          proc gslide;
          run;
          quit;

          goptions iback="&outdir.\sgplot2.png" imagestyle=fit;

          proc gslide;
          run;
          quit;

          filename grafout 'c:\temp\greplay.png';

          goptions reset=all device=PNG300 gsfname=grafout
          xmax=5in ymax=8in;

          proc greplay igout=work.gseg nofs tc=sashelp.templt
          template=V2;
          treplay 1:1 2:2;
          run;
          quit;

  3. barefootguru on

    This works for Windows, but macOS and iOS display the image in the body (as expected), then again at the end… any thoughts?

    • Chris Hemedinger
      Chris Hemedinger on

      Could that be a side-effect of the way the e-mail client renders messages with attached images?

  4. Thanks this works great so far except for one issue I'm having. When using this method to email a graph with multiple lines the graph is created correctly in SAS but after emailing all the lines are different patterns. Have you encountered this?

  5. Martin,
    This is helpful.

    Could you suggest How to embed image and table(proc print) in the body of email?

    Here is the code I tried:

    filename report "c:/users/test.html";
    filename SEND email to ="*****@****.com"
    from="****@****.com"
    attach=("/C/users/graph1.png" name="testgraph1" inlined="logo1")
    content_type="text/html";

    ods html file=report;
    proc print data=test;
    run;
    ods html close;

    data _null_;
    infile report;
    file SEND;
    input;
    put _infile_;
    put "";
    run;

    • Thank you for the help Martin. It really saved a good amount of time.

      filename SEND email to ="martin.mincey@sas.com"
      from="martin.mincey@sas.com"
      attach=("c:\temp\graph1.png" inlined="logo1")
      content_type="text/html";

      title1;

      ods _all_ close;
      ods html file=SEND;

      ods html text="";
      proc print data=sashelp.class;
      run;

      ods html close;
      ods listing;

      filename SEND clear;
      This code works well.

      Is ther any way that i can put text for the tables(like heading) between graph body and tables.

      Thanks,
      Sravan.

  6. Thanks, this just blew my mind! I always figured I would need to use HTML5 to embed images. This technique looks very handy. Finally got access to a server running 9.4 recently, so this tip comes at a good time.

Leave A Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Back to Top