5

I've search high and low for an answer but without an y luck. Got a Google spreadsheet which uses apps script to connect to a database to pull in some raw data into a spreadsheet. I then use various spreadsheet formulas to manipulate that data and then final create a chart.

My next challenge is that I want to be able to embed that chart into an email via apps script and send it as an HTML email..

Is this at all possible or should I start looking for some other solution?

Thanks!

Mikael

The Ginger Fox
  • 367
  • 1
  • 4
  • 15
  • embed it as an image type inside the email or an interactive chart? – Bryan P Nov 15 '13 at 13:41
  • you didn't search very well, a simple search on this forum returns a few results. Example : http://stackoverflow.com/questions/17769746/appscript-how-add-an-inline-chart-pulled-from-a-spreadsheet-into-an-email – Serge insas Nov 15 '13 at 16:23
  • The example that you sent me doesn't actually answer my question, the question is the same but the approach used isn't what I'm trying to achive. I already know how to progressivly create a chart using a data table i wanted to know if it's possible to access an existing chart within a spreadsheet... – The Ginger Fox Nov 18 '13 at 07:36
  • Did you try to create the chart with Charts.newDataTable() in the script that sends the email and than add this chart object to the HTMLbody of the email? Maybe you have to use the [build](https://developers.google.com/apps-script/reference/charts/column-chart-builder#build()) function in order to convert the chart into a image. Take a look at [this example](https://sites.google.com/a/lagaroo.com.br/dev-test/home/dev-test-star-graphs) for the part of the chart. – Jacobvdb Nov 18 '13 at 21:44

3 Answers3

5

Here is the code I used to email charts. Please note that you need to give everyone with the link access to the spreadsheet. If not, you'll get an image in the email stating user is not signed in. (very annoying that there's no workaround to this)

function emailCharts(sheet,emails,emailSubject){
  var charts = sheet.getCharts();

  if(charts.length==0){
    MailApp.sendEmail({
      to: emails,
      subject: "ERROR:"+emailSubject,
      htmlBody: "No charts in the spreadsheet"});    
    return;
  }

  var chartBlobs=new Array(charts.length); 
  var emailBody="Charts<br>";
  var emailImages={};
  for(var i=0;i<charts.length;i++){
    chartBlobs[i]= charts[i].getAs("image/png").setName("chartBlob"+i);
    emailBody= emailBody + "<img src='cid:chart"+i+"'><br>";
    emailImages["chart"+i]= chartBlobs[i];
  }

  MailApp.sendEmail({
    to: emails,
    subject: emailSubject,
    htmlBody: emailBody,
    inlineImages:emailImages});

}
dparnas
  • 4,090
  • 4
  • 33
  • 52
  • I tried running this script and the email that was sent only contained blank charts. Is there something special you had to do to get this working? – bobmagoo May 05 '14 at 19:41
  • 1
    make sure everyone with the link has access to the spreadsheet. In the email client you of course need to accept the download of the images.There are some charts that are displayed differently when emailed, but I've not experienced blank ones – dparnas May 06 '14 at 20:32
  • Thanks for the response, I've only been testing as myself so access isn't the issue. – bobmagoo May 18 '14 at 05:48
  • could you run a debug a find the values of the attributes used in the email call? – dparnas May 19 '14 at 15:49
  • I'm sending the email to myself. I should be able to see the image, right? – Luiz Guilherme Oct 24 '14 at 21:02
  • nope unfortunately. The job which creates the chart images doesn't run under your user context – dparnas Oct 26 '14 at 05:05
  • I'm sure if I got the way to solve it. The spreadsheet is public inside my domain and I'm sending the e-mail to my account that is part of that domain. The charts are published so everyone could see the chart. I don't really understand why I'm still seeing blank images. – Luiz Guilherme Oct 26 '14 at 15:45
  • 2
    I had this problem as well. You have to enable "link sharing" ("anyone with a link can view"). – Peter Rankin Dec 09 '14 at 14:20
  • I get this message: **EmbeddedChart API is deprecated.** The API has been marked as deprecated which means that the feature should be avoided and may be removed in the future. Consider using an alternative solution. – Ky - May 06 '15 at 18:59
1

Make the spreadsheet Public and run the script. Modified version of the script pasted below with comments

enter code here function 
emailCharts(sheet,emails,emailSubject){
var targetspreadsheet = SpreadsheetApp.getActiveSpreadsheet(); // Active        spreadsheet of the key file
var sheet = targetspreadsheet.getSheetByName('Sheet1'); // Change the sheet name 
var emailSubject = 'test';
var emails = 'test@test.com'; // your email ID
var charts = sheet.getCharts();


if(charts.length==0){
MailApp.sendEmail({
to: emails,
subject: "ERROR:"+emailSubject,
htmlBody: "No charts in the spreadsheet"});    
return;
}

var chartBlobs=new Array(charts.length); 
var emailBody="Charts<br>";
var emailImages={};
for(var i=0;i<charts.length;i++){
var builder = charts[i].modify();
builder.setOption('vAxis.format', '#');
var newchart = builder.build();
chartBlobs[i]= newchart.getAs('image/png');
emailBody= emailBody + "<p align='center'><img src='cid:chart"+i+"'></p>";
emailImages["chart"+i]= chartBlobs[i];
}

MailApp.sendEmail({
to: emails,
subject: emailSubject,
htmlBody: emailBody,
inlineImages:emailImages});
}
0

As the Charts Service appears to only be a partial implementation of EmbeddedChart used in SpreadsheetApp Service not all of the ChartTypes and options are implemented, meaning charts might render differently than they do in Google Sheets. The modified version of the previous answer below will mean charts are included in emails as images as they appear in Google Sheets. As this solution also uses an authentication token generated by the script the view permissions on the Google Sheet does not have to be changed.

// Based on https://stackoverflow.com/a/22200230/1027723
function emailChartUsingImageUrl(){
  const idt = SpreadsheetApp.getActive().getId();
  const sheet = SpreadsheetApp.getActiveSheet();
  const charts = sheet.getCharts();
  
  // setup some variables for our email
  const chartBlobs = new Array(); 
  const emailImages = {};
  let emailBody = "Charts<br>";
  
  // setup our call to fetch the chart image
  const token = ScriptApp.getOAuthToken(); // project requires https://www.googleapis.com/auth/spreadsheets scope
  const baseUrl = `https://docs.google.com/spreadsheets/d/${idt}/embed/oimg?access_token=${token}&disposition=ATTACHMENT&bo=false&filetype=png&oid=`;
  
  // for each chart fetch the download image as a blob and appended to our email body
  charts.forEach(function(chart, i){
    // NEW BIT
    const url = baseUrl + chart.getChartId();
    chartBlobs[i] = UrlFetchApp.fetch(url).getBlob();
    emailBody +=  "<p align='center'><img src='cid:chart"+i+"'></p>";
    emailImages["chart"+i]= chartBlobs[i];
  });
  
  // Send email with inline images
  MailApp.sendEmail({
    to: "me@example.com",
    subject: "Email Charts - get chart from image url",
    htmlBody: emailBody,
    inlineImages:emailImages});
}
mhawksey
  • 2,013
  • 5
  • 23
  • 61