Save a range of Google Sheet as image in Google Drive [duplicate] - google-apps-script

I am trying to copy a range of cells of a specific Google spreadsheet as an image onto a Google slide. But I could barely find useful code. This is what I came up with, but I still cannot transfer the cell range into an image/png.
Goal: Insert the image stored just in a variable to a specific slide!
Any help is very much appreciated. Thank you.
function add_WSA(){
//Opening the Spreadsheet
var ss = SpreadsheetApp.openById("insertSpreadsheetID");
var range = ss.getRange("example!A1:F20");//in A1 Notation
//Conversion into an png image
var image = range.getAs('image/png');
//Opening the specific Slide (Nr. 3)
var slide = SlidesApp.openById("mySlidesID").getSlides()[2];
//Insertion of image
slide.insertImage(image);
}
Error: TypeError: range.getAs is not a function
at add_WSA(report:5:21)
PS: I am farely new to the community and to JavaScript. Please be patient. Every other help on a leaner or more efficient solution to the problem is very much appreciated. Thank you.

How about this answer?
Issue and workaround:
Unfortunately, in the current stage, the range object cannot be directly converted to the PNG format. So in this case, it is required to use a workaround. In this answer, as the workaround, I would like to propose to use Charts Service. When Charts Service is used, the range of Spreadsheet can be converted to an image blob.
Sample script:
function add_WSA(){
//Opening the Spreadsheet
var ss = SpreadsheetApp.openById("insertSpreadsheetID");
var range = ss.getRange("example!A1:F20");//in A1 Notation
//Conversion into an png image
// I modified below script.
const [header, ...values] = range.getDisplayValues();
const table = Charts.newDataTable();
header.forEach(e => table.addColumn(Charts.ColumnType.STRING, e));
values.forEach(e => table.addRow(e));
const image = Charts.newTableChart().setDataTable(table.build()).setDimensions(500, 500).setOption('alternatingRowStyle', false).build().getBlob();
//Opening the specific Slide (Nr. 3)
var slide = SlidesApp.openById("mySlidesID").getSlides()[2];
//Insertion of image
slide.insertImage(image);
}
Result:
When above script is run, the following sample result can be obtained.
Note:
Please use this script with enabling V8.
In this case, for example, when you want to change the font color, please use HTML code in each cell value.
Reference:
Charts Service

Related

How can I get an image FROM A CELL in a Google Sheet and insert it into a Google Doc [duplicate]

I have a script that creates a document during runtime and attach it to a variable.
I need to insert images to it using a script.
Here is my code:
var modulo = "foo";
var nomeDoc = "bar";
let doc = DocumentApp.create("Validação escopo ("+ modulo +") cliente: " + nomeDoc);
var body = doc.getBody();
var imgPDF = body.appendImage(blob);
How do i pass an image as "blob" inside the variable: imgPDF?
Important: The image is in the Spreadsheet that calls this function.
On January 19, 2022, 2 Classes for using the inner cell image were added to the Spreadsheet service. Ref But, in the current stage, the image can be put into a cell. But, unfortunately, the image in the cell cannot be retrieved. I think that this might be a bug. And also, these Classes cannot retrieve the images on a cell as the blob and the image URL. I think that this is the specification.
So, as the current workaround, I thought that in your situation, in the current stage, this method can be used. Ref
In this workaround, a Google Apps Script library might be able to be used. Ref This library can retrieve both the image in a cell and the image on a cell.
Usage:
1. Install Google Apps Script library.
You can see the method for installing this library at here.
2. Enable Drive API.
In this case, Drive API is used. So, please enable Drive API at Advanced Google services.
3. Sample script.
const spreadsheetId = "###"; // Google Spreadsheet ID
const res = DocsServiceApp.openBySpreadsheetId(spreadsheetId).getSheetByName("Sheet1").getImages();
console.log(res); // You can check the retrieved images at the log.
if (res.length == 0) return;
const blob = res[0].image.blob; // Here, 1st image of Sheet1 is retrieved. Of course, you can choose the image on the sheet.
let doc = DocumentApp.create("Validação escopo (" + modulo + ") cliente: " + nomeDoc);
var body = doc.getBody();
var imgPDF = body.appendImage(blob);
In this case, please declare modulo and nomeDoc.
4. Testing.
When the above script is run, the images are retrieved from "Sheet1" and put the 1st image to the created Document body.
References:
DocsServiceApp
Related thread
How to access new 'in-cell-image' from google apps script?

Modifying Google Chart - Vertical Axis 'number format' reverts to "from source data" after I update my chart title by script (shows date) dynamically

I'm trying to update the title of my chart through the code so it is changed dynamically. When this happens, the title changes successfully, but the number format for the vertical axis changes to dates (changes to from source data).
I'm not sure where it's getting the dates either because the source data is set to Number. Changing it to 'format by' anything else using the script has no effect. It just ignores it.
Even a macro doesn't work. When I try to do this with a macro I get the error: "Exception: Unexpected error while getting the method or property setOption on object SpreadsheetApp.EmbeddedChartBuilder."
I have this code that runs when the button is pressed. It changes the title of the chart to the value in K1 but I don't understand why it changes the vertical axis to dates as well. I just want it to remain at "none" or "decimal":
function updateTitle() {
var sheet = SpreadsheetApp.getActive().getActiveSheet();
var chart = sheet.getCharts()[0];
var title = sheet.getRange('K1').getValue();
chart = chart.modify()
.setOption('title', title || 'Empty')
.setOption('vAxis.format', 'none')
.build();
sheet.updateChart(chart);
}
I'm thinking the formatting of the code must be incorrect, is that true? I've searched all over the Internet, and I've found tons of different ways to format modifying google charts, and have tried many different variations. I'm not getting it right and am kind of lost about what format is correct and why what I'm doing isn't working.
Here is an example of my chart: https://docs.google.com/spreadsheets/d/16vmDv5sJvle4hLXaz1ZTgkP8V2-5dlWJvdJ9eqPxc-w/edit?usp=sharing
Thank you
Issue and workaround:
I have experienced the same situation with your situation. In this case, even when the following simple script is run, the number format is changed.
var sheet = SpreadsheetApp.getActive().getActiveSheet();
var chart = sheet.getCharts()[0];
sheet.updateChart(chart);
But, unfortunately, at that time, although I had looked for the method for keeping the number format for updateChart, I couldn't find it. So in this answer, I would like to propose to use Sheets API for your situation. In my experience, I had confirmed that when Sheets API is used, the title can be updated without changing the number format of the vertical axis.
When your script is modified, it becomes as follows.
Sample script:
Before you use this script, please enable Sheets API at Advanced Google services.
function updateTitle() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
var chart = sheet.getCharts()[0];
var title = sheet.getRange('K1').getValue();
var chartId = chart.getChartId();
sheet.getRange("F3:H5").setNumberFormat("0");
SpreadsheetApp.flush();
var sheets = Sheets.Spreadsheets.get(ss.getId(), {fields: "sheets(charts)"}).sheets;
var c = sheets.reduce((ar, s) => {
var temp = s.charts.filter(c => c.chartId == chartId);
if (temp.length == 1) ar = ar.concat(temp);
return ar;
}, []);
if (c.length == 1) {
var chartObj = c[0];
delete chartObj.position;
chartObj.spec.title = title || 'Empty';
Sheets.Spreadsheets.batchUpdate({requests: [{updateChartSpec: chartObj}]}, ss.getId());
}
}
Result:
When above script is used for sample chart of your sample Spreadsheet, the following result is obtained.
Note:
In this case, the number format of the cells "F3:H5" is reflected to the number format of the vertical axis. So when you want to use the format like 1.00, 2.00,,,, please remove sheet.getRange("F3:H5").setNumberFormat("0") and SpreadsheetApp.flush() from above script.
In the case of above script, because fields cannot be used for UpdateChartSpecRequest], by this, at first, it is required to retrieve all objects of the chart and modify the object, and then, put the modified object to the chart. This situation has already been reported to Google issue tracker as the future request. Ref
References:
Method: spreadsheets.get
Method: spreadsheets.batchUpdate
UpdateChartSpecRequest
If you change the vertical axis format in any way after the graph was first made, you must leave the vertical axis format in its virgin state and never change it.

Google Slides Apps Script retrive a shape in a page

how to retrieve a particular shape base on the text of the shape.
example: I would like to retrieve a shape in which text starts with "Issue" and get the content of the text to input it in Google Sheets
thanks for helping!
I believe your goal as follows.
You want to retrieve the texts from the shapes in Google Slides.
When the top of text is Issue, you want to retrieve the text, and want to put the retrieved texts to Google Spreadsheet.
You want to achieve this using Google Apps Script.
In this case, how about the following sample script? Unfortunately, from your question, I cannot understand about the output situation you expect. So the following sample script puts the retrieved values to the 1st column.
Sample script:
Please copy and paste the following script to the script editor. And, please set the variables and run myFunction.
function myFunction() {
const presentationId = "###"; // Please set the presentation ID (Google Slides ID).
const spreadsheetId = "###"; // Please set the Spreadsheet ID.
const sheetName = "Sheet1"; // Please set the sheet name.
const searchText = "Issue";
// Check texts and retrieve texts from Google Slides.
const regex = new RegExp(`^${searchText}`);
const slides = SlidesApp.openById(presentationId).getSlides();
const values = slides.flatMap(slide => slide.getShapes().reduce((ar, shape) => {
const text = shape.getText().asString().trim();
if (regex.test(text)) ar.push([text]);
return ar;
}, []));
// Put the retrieved texts to Google Spreadsheet.
const sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName);
sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
}
Note:
Unfortunately, I'm not sure whether above sample script is what you need. So when above script is not useful for your situation, in order to correctly understand about your goal, can you provide the sample Slides and the sample result you expect? By this, I would like to modify the script.
References:
getShapes()
getText()
setValues(values)

How to print the result of a script on the current sheet

I am working with a script that translates a text in a cell of a sheet through the Deepl API.
Thanks to a colleague help it worked correctly (Use Deepl API and google sheets).
In this case, I need to know how I can make the result of the translation to be included in a cell of the same sheet.
My data object is the following. The first script picks up the text from column 2, row 3. It would be perfect if the result is printed in column 2, row 4, but I don't know exactly how to do it.
I include an image of the corresponding data
I am using this script to translate the text of a cell in my sheet:
function deeplapi() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var text = sheet.getRange(3,2).getValue(); // define text before response
var response = UrlFetchApp.fetch("https://api.deepl.com/v2/translate?auth_key=xxxx-xxxx-xxxx-xxxx-xxxx&text="+ text +"&target_lang=en&source_lang=es");
var json = response.getContentText();
var data = JSON.parse(json);
Logger.log(data);
}
This way I get the result in the records section, but with this format:
Información {translations=[{text=Hi, I'm Carlos, detected_source_language=ES}]}
First, I have tried to extract only the translation in this section and then add it in the same sheet. With this I get the exact translation, but I don't know how to include it in a specific range of my sheet.
Logger.log(data.translations[0].text);
In addition to this, I think that to get this result and paste it in the sheet I would have to use:
sheet.getRange () .setValues (sortedOutput);
Anyway, I'm not sure
Try something like that at the bottom of your script to paste the translation text into cell B4:
sheet.getRange('B4').setValue(data.translations[0].text)
Minimal reproducible example:
const data = {translations:[{text:"Hi, I'm Carlos", detected_source_language:"ES"}]};
console.log(data.translations[0].text)

Efficient Way of sending Spreadsheet over email using GAS function?

I am creating an addon for Google Sheets that my local High School's volunteer clubs can use to keep track of their member's volunteer hours. Most of the code is done and works very nicely, and I am currently working on a system that will send a member a spreadsheet listing all of the volunteer events that they have logged. I have GAS create a separate spreadsheet, and then send an email with that separate spreadsheet attached in PDF. When the email is received, the PDF is empty except for a singular empty cell at the top left of the page.
I am pretty new to GAS but have been able to grasp the content pretty easily. I have only tried one method of sending the Spreadsheet and that is by using the .getAs(MimeType.PDF). When I changed the "PDF" to "GOOGLE_SHEETS," GAS returned the error: "Blob object must have non-null data for this operation." I am not entirely sure what a Blob object is, and have not found any website or video that has fully explained it, so I am not sure how to go about troubleshooting that error.
I think I'm having a problem grabbing the file because it either sends an empty PDF or it returns an error claiming it needs "non-null data."
function TigerMail()
{
var Drive = DriveApp;
var app = SpreadsheetApp;
var LOOKUP = app.getActiveSpreadsheet().getSheetByName("Student
Lookup");
var Name = LOOKUP.getRange("E1").getValue();
Name = Name + "'s Hours";
//app.openById(Name+"'s Hours");
var HOURS = app.create(Name);
var ESheet = HOURS.getSheets()[0];
var ROW = LOOKUP.getLastRow();
var arr = LOOKUP.getRange("D1:J"+ROW).getValues();
var cell = ESheet.getRange("A1:G"+ROW);
cell.setValues(arr);
////////////////////////////////////////////////////
var LOOKUP = app.getActiveSpreadsheet().getSheetByName("Student
Lookup");
var cell = LOOKUP.getRange("D1");
var Addr = cell.getValue();
var ROW = LOOKUP.getLastRow();
var file = Drive.getFilesByName(Name);
var file = file.next();
var FORMAT = file.getAs(MimeType.GOOGLE_SHEETS);
TigerMail.sendEmail(Addr, "Hours", "Attached is a list of all of the
events you have volunteered at:", {attachments: [FORMAT]} );
}
the final four lines are where the errors are occurring at. I believe I am misunderstanding how the .next() and .getFilesByName() work.
(above the comment line: creating a spreadsheet of hours)
(below the comment line: grabbing the spreadsheet and attaching it to an email)
Here is the link to the Google Sheet:
https://docs.google.com/spreadsheets/d/1qlUfTWaj-VyBD2M45F63BtHaqF0UOVkwi04XwZFJ4vg/edit?usp=sharing
In your script, new Spreadsheet is created and put values.
You want to sent an email by attaching the file which was converted from the created Spreadsheet to PDF format.
If my understanding is correct, how about this modification? Please think of this as just one of several answers.
Modification points:
About Drive.getFilesByName(Name), unfortunately, there is no method of getFilesByName() in Drive.
I think that when you want to use the created Spreadsheet, HOURS of var HOURS = app.create(Name) can be used.
About var FORMAT = file.getAs(MimeType.GOOGLE_SHEETS), in the case of Google Docs, when the blob is retrieved, the blob is automatically converted to PDF format. This can be also used for your situation.
In order to save the values put to the created Spreadsheet, it uses SpreadsheetApp.flush().
When above points are reflected to your script, it becomes as follows.
Modified script:
Please modify as follows.
From:
var file = Drive.getFilesByName(Name);
var file = file.next();
var FORMAT = file.getAs(MimeType.GOOGLE_SHEETS);
To:
SpreadsheetApp.flush();
var FORMAT = HOURS.getBlob();
Note:
In your script, it seems that var ROW = LOOKUP.getLastRow() is not used.
References:
flush()
getBlob()
If I misunderstood your question and this was not the result you want, I apologize.