2

I'm building a search tool by which one can convert a google range into an image using google script. I tried to paste that data range to google slides and from there I get thumbnails and their url. I'm searching any other tools that directly give me the url of image of the selected range of a google sheet.

Thanks

Cooper
  • 59,616
  • 6
  • 23
  • 54
Abhijeet Pandit
  • 33
  • 1
  • 1
  • 4

2 Answers2

8

I am unsure of the reasoning behind doing this, but nonetheless, here is an answer:

This creates a custom menu on the top of your sheet that says:

Custom Functions => Export Range to Image Files.

When you click that it:

  • Turns whatever you have selected into a table in sheets
  • Saves it
  • Generates an image from that
  • Saves image to drive
  • Show a pop-up with the links of the saved images.

The code is ready to handle multiple ranges being exported, but right now it exports only the selected range.

function onOpen(e) {
  //Create custom menu to export range to Slides.
  SpreadsheetApp.getUi()
      .createMenu('Custom Functions')
      .addItem('Export Range to Image Files', 'SelectedRangeToImage')
      .addToUi();
}


function SelectedRangeToImage() {
  var slide = RangeToSlides();
  var slideId = slide.getId();
  var images  = [];
  for (var x=0; x<slide.getSlides().length;x++) {
    var image = SlidesToImage(slide.getName()+x, slideId, slide.getSlides()[x].getObjectId());
    images.push(image);
  }
  
  //Show interface with links to all images
  var ui = SpreadsheetApp.getUi();
  var html = HtmlService.createHtmlOutput();
  html.append("<p>Your images:</p>");
  html.append("<ul>");
  for (var i=0; i<images.length; i++) {
    html.append("<li><a href='"+images[i].getUrl()+"'>"+images[i].getName()+"</a></li>");
  }
  html.append("</ul>");
  html.append("<input type='button' value='Close' onclick='google.script.host.close()' />");
  ui.showModalDialog(html, "Exporting results:");
}

function RangeToSlides() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var range = ss.getActiveRange();
  
  var rangeValues = range.getDisplayValues();
  var rangeHorizontalAlignments = range.getHorizontalAlignments()
  var rangeBackgrounds = range.getBackgrounds();
  var rangeFontWeights = range.getFontWeights();
  
  
  var sl = SlidesApp.create("ExportToImage"+new Date());
  var slide = sl.getSlides()[0];
        
  //Create table with size of the range
  var table = slide.insertTable(rangeValues.length, rangeValues[0].length);
  for (var x=0; x<rangeValues.length; x++) {
    for (var y=0; y<rangeValues[x].length; y++) {
      var cell = table.getCell(x,y);
      cell.getText().setText(rangeValues[x][y]); //Set text
      cell.getFill().setSolidFill(rangeBackgrounds[x][y]); //Set background
      cell.getText().getTextStyle().setBold(rangeFontWeights[x][y]=="bold"?true:false); //Set text formatting
      var alignment;
      switch(rangeHorizontalAlignments[x][y]) {
        case "general-left":
          alignment = SlidesApp.ParagraphAlignment.START;
          break;
        case "general-right":
          alignment = SlidesApp.ParagraphAlignment.END;
          break;
        case "center":
          alignment = SlidesApp.ParagraphAlignment.CENTER;
          break;
      }
      cell.getText().getParagraphStyle().setParagraphAlignment(alignment); //Set text alignment
    }
  }
  sl.saveAndClose();
  return sl;  
}

function SlidesToImage(name, presentationId, slideId) {
  var url = "https://slides.googleapis.com/v1/presentations/"+presentationId+"/pages/"+slideId+"/thumbnail";
  var options = {
    headers: {
      Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
    }
  };
  var response = UrlFetchApp.fetch(url, options);
  var responseJson = JSON.parse(response.getContentText());
  var imageurl = responseJson.contentUrl;
  var imageResponse = UrlFetchApp.fetch(imageurl, options);
  var blob = imageResponse.getBlob();
  blob.setName(name);
  var resultingFile = DriveApp.createFile(blob);
  return resultingFile;
}

References:

  1. https://stackoverflow.com/a/51391196/11869748
  2. How to download Google Slides as images?
  3. https://developers.google.com/slides/reference/rest/v1/presentations.pages/getThumbnail
desertnaut
  • 57,590
  • 26
  • 140
  • 166
ZektorH
  • 2,680
  • 1
  • 7
  • 20
  • 1
    it didn't work for me.. or i did it wrong somehow.. Exception: The object (SLIDES_API1674193731_0) has no text. and other errors too. The custom function menu and script can start execute. but errors with above. – ihightower Apr 21 '21 at 14:26
  • @ihightower I recommend you open a new question and provide: a sample of the spreadsheet you are trying to export, the script you are using, a link to this answer, the specific (and complete) error message you are receiving. – ZektorH Apr 23 '21 at 08:58
  • @ihightower there are two places in the code where I got that error. I wrapped the statements in a try and continued. I assumed it was because the cell had no text. I did get an image with fill colors and centered text after doing this. – aNewb Jun 19 '21 at 21:32
  • works great but I am floundering setting borders and column widths in the slides table based on values in the spreadsheet. – aNewb Jun 19 '21 at 22:11
  • 1
    You wanted to know why - education - teacher can easily build tables in spreadsheet but needs as background in slide for students to work on top of. – aNewb Jun 22 '21 at 22:21
  • The table built may not fit on the slide. Cell sizes are not preserved. Table is surrounded by useless white space. I have opened a related question here - https://stackoverflow.com/questions/68444131/please-look-again-google-advanced-slides-api-insert-text-in-existing-table – aNewb Aug 07 '21 at 20:19
  • @Abhijeet Pandit have you had any luck with a creating a good background image table – aNewb Aug 07 '21 at 22:07
1

Only graphic images can be made with Google AppScript. I looked at a lot of code, but they didn't work for me; either they were making a PDF then converting it to a picture, or they were sending it to a slide and then making a picture.

My aim was to make a picture directly with its formats. I converted pictures with their formats, but when the picture was taken directly from the graphic, it was colorless.

Here I’ve converted a friend's code that converts the HTML table to a picture from there.

get the table

var aa = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Holiday");

active column

stun=aa.getActiveRange().getColumn();

active column width

stungen=aa.getColumnWidth(stun)+70

number of filled rows

var count = ss.getDisplayValues().flat().filter(String).length;

column and row to import

var sa =aa.getRange(1,stun,count);

formats of received data

 var data = sa.getDisplayValues();
        var background = sa.getBackgrounds();
        var fontColor = sa.getFontColors();
        var fontStyles = sa.getFontStyles();
        var fontWeight = sa.getFontWeights();
        var fontSize = sa.getFontSizes();

Making data into a formatted html table

 for (var i = 0; i < data.length; i++) {
            html += "<tr>"
            for (var j = 0; j < data[i].length; j++) {
                html += "<td style='height:20px;background:" + background[i][j] + ";color:" + fontColor[i][j] + ";font-style:" + fontStyles[i][j] + ";font-weight:" + fontWeight[i][j] + ";font-size:" + (fontSize[i][j] + 6) + "px;'>" + data[i][j] + "</td>";
            }
            html += "</tr>";
        }
        html + "</table>"

convert html table to chart

 const img = Charts.newTableChart().setDataTable(Charts.newDataTable().addColumn(Charts.ColumnType.STRING, '').addRow([html]).build()).setOption('allowHtml',true).setDimensions(stungen,count*28).build();

the size of the picture setDimensions(stungen,count*28) stungen=column width convert graphic to image and get link

 var imageData1 = Utilities.base64Encode(img.getAs('image/png').getBytes());
      var imageUrl = "data:image/png;base64," + encodeURI(imageData1);
      htmlOutput.append("Holiday Listesi <br/>");

show image in dialog

 htmlOutput.append("Holiday Listesi <br/>");
      htmlOutput.append("<img border=\"1\" src=\"" + imageUrl + "\">");

      SpreadsheetApp.getUi().showModelessDialog(htmlOutput,"demo");
      return htmlOutput;
    }

the whole code

function drawTable() {
       var aa = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Holiday");
       stun=aa.getActiveRange().getColumn();
       stungen=aa.getColumnWidth(stun)+70
        var sa =aa.getRange(1,stun);
        var lastRow = aa.getLastRow();
        var ss =aa.getRange(1,stun,lastRow);
        var count = ss.getDisplayValues().flat().filter(String).length;
    var sa =aa.getRange(1,stun,count);

        var data = sa.getDisplayValues();
        var background = sa.getBackgrounds();
        var fontColor = sa.getFontColors();
        var fontStyles = sa.getFontStyles();
        var fontWeight = sa.getFontWeights();
        var fontSize = sa.getFontSizes();
        var html = "<b>HOLİDAY</b>"+ "<table border='1'>";
        for (var i = 0; i < data.length; i++) {
            html += "<tr>"
            for (var j = 0; j < data[i].length; j++) {
                html += "<td style='height:20px;background:" + background[i][j] + ";color:" + fontColor[i][j] + ";font-style:" + fontStyles[i][j] + ";font-weight:" + fontWeight[i][j] + ";font-size:" + (fontSize[i][j] + 6) + "px;'>" + data[i][j] + "</td>";
            }
            html += "</tr>";
        }
        html + "</table>"

  

      var htmlOutput = HtmlService.createHtmlOutput();
      const img = Charts.newTableChart().setDataTable(Charts.newDataTable().addColumn(Charts.ColumnType.STRING, '').addRow([html]).build()).setOption('allowHtml',true).setDimensions(stungen,count*28).build();

        var imageData1 = Utilities.base64Encode(img.getAs('image/png').getBytes());
      var imageUrl = "data:image/png;base64," + encodeURI(imageData1);
      htmlOutput.append("Holiday Listesi <br/>");
      htmlOutput.append("<img border=\"1\" src=\"" + imageUrl + "\">");

      SpreadsheetApp.getUi().showModelessDialog(htmlOutput,"demo");
      return htmlOutput;
    }

Resim

Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77