I would like to be able to add an image file into my spreadsheet from Google Drive. I see there is a built-in image function available =image, but this requires a URL and that image files should be shared publicly on the internet. However, I am working with digital assets and can not share them publicly.
I have the following code, this works but does not add to the required cell. Is this at all possible?
function insertImageFromDrive(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var fileId = '0B5UAkV0avfiKNGYtd1VzUzlsTVk';
var img = DriveApp.getFileById(fileId).getBlob();
sheet.insertImage(img, 4, 3)
}
Try using the guide Insert image in a spreadsheet from App Script:
function insertImageOnSpreadsheet() {
var SPREADSHEET_URL = 'INSERT_SPREADSHEET_URL_HERE';
// Name of the specific sheet in the spreadsheet.
var SHEET_NAME = 'INSERT_SHEET_NAME_HERE';
var ss = SpreadsheetApp.openByUrl(SPREADSHEET_URL);
var sheet = ss.getSheetByName(SHEET_NAME);
var response = UrlFetchApp.fetch(
'https://developers.google.com/adwords/scripts/images/reports.png');
var binaryData = response.getContent();
// Insert the image in cell A1.
var blob = Utilities.newBlob(binaryData, 'image/png', 'MyImageName');
sheet.insertImage(blob, 1, 1);
}
Just replace the necessary values. The part where you indicate which cell you insert the image is in:
sheet.insertImage(blob, 1, 1);
There is a google spreadsheet add-on ImageKit to help insert multiple images from difference sources including Google Drive, check it out > https://chrome.google.com/webstore/detail/imagekit/cnhkaohfhpcdeomadgjonnahkkfoojoc
Here you find a screenshot of tool's interface.
It is not possible if the drive image file is not public on your google drive, Having said that there is a trick to overcome i.
First make sure the image file is temporary public on your drive. you can do that also via app script by changing the file permissions to DriveApp.Access.ANYONE, DriveApp.Permission.EDIT. Then the drive file is like a file as if it was from the internet. You can then add the blob.
After that you can decide two things.
Change the permissions back or remove the image file from your drive (if you only want to use it embedded in your blob (also via app script code if you want)
good luck
I don't think it is currently possible, see here: https://code.google.com/p/google-apps-script-issues/issues/detail?id=3303
Here's another alternative:
var fileId = "..."; // your image's google drive id
sheet.insertImage("https://docs.google.com/uc?id=" + fileId, column, row);
Just make sure your file has link sharing turned on (anyone with the link can view) otherwise this method won't work.
Documentation
Related
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?
Trying to get image url in google script.
couldn’t find any function that is able to get the url from images that are not in a specific cell, images are located above the grid.
any ideas?
Issue and workaround:
On October 30, 2018, in order to manage the images on the cells in Spreadsheet, a new Class of OverGridImage has been added. Ref By this, the images on the cells got to be able to be managed. This class has the method of getUrl. The official document of this method says as follows.
Gets the image's source URL; returns null if the URL is unavailable. If the image was inserted by URL using an API, this method returns the URL provided during image insertion.
Namely, for example, when the following script is run, the URL of the image can be retrieved.
function sample1() {
const sheet = SpreadsheetApp.getActiveSheet();
// Put image from URL.
sheet.insertImage("https://stackoverflow.design/assets/img/logos/so/logo-stackoverflow.png", 1, 1);
// Retrieve image URL.
const images = sheet.getImages();
const url = images[0].getUrl();
console.log(url)
}
In your actual situation, if your images are put on the cells using the above script, the URLs can be retrieved by the above simple script. But, here, there is an important point. After the image was put using this script, when you manually move the image, the URL cannot be retrieved. I think that this is a bug.
And also, if you had manually put the images from the URL and your drive, unfortunately, the URL of the images cannot be retrieved. About this, it has already been reported to the Google issue tracker. Ref
If you had manually put the images from the URL and your drive, and when you want to retrieve the URLs of the images, it is required to use a workaround. In this case, I would like to propose to use this method of this answer. In this answer, my created Google Apps Script library is used.
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.
function sample2() {
const sheetName = "Sheet1"; // Please set the sheet name.
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(sheetName);
const images = sheet.getImages();
const obj = images.reduce((o, e) => {
const u = e.getUrl();
if (u) o[e.getAnchorCell().getA1Notation()] = u;
return o;
}, {});
const res = DocsServiceApp.openBySpreadsheetId(ss.getId()).getSheetByName(sheetName).getImages();
if (res.length == 0) return;
const urls = res.map(({ image, range }, i) => {
if (obj[range.a1Notation]) return obj[range.a1Notation];
const o = Drive.Files.insert({ title: `sample${i + 1}` }, image.blob);
const url = o.thumbnailLink.replace(/\=s\d+/, "=s1000");
DriveApp.getFileById(o.id).setTrashed(true);
return url;
});
console.log(urls)
}
4. Testing.
When the above script is run, the images are retrieved from "Sheet1" and retrieve the URLs of the images. For example, when there are images put with the image URL using the script, the URL can be retrieved.
Note:
In this workaround, in order to retrieve the URL of the image, the thumbnail link is used. This link is not permanent. Please be careful about this. If you are required to retrieve the permanent link, please create the retrieved image file blob as the file, and please publicly share them, and then, please retrieve the WebContentLink. By this, you can retrieve the permanent link of the image.
References:
DocsServiceApp
Related thread
How to access new 'in-cell-image' from google apps script?
I am using this script to download a URL set in a google sheet cell to a specific folder in google drive called "game_thumb"
If cell B1 is "yyyyy.com/picture.png" I expect picture.png to be downloaded to the google drive folder.
I get an error"ReferenceError: "DocsList" not defined. (line 5).
I also would like the file to be renamed to include Cell A1
(contentCellA1_picture.png) before it is downloaded to drive.
The code I use:
function getFile(fileURL) {
// see https://developers.google.com/apps-script/class_urlfetchapp
var response = UrlFetchApp.fetch(fileURL);
var fileBlob = response.getBlob()
var folder = DocsList.getFolder('game_thumb');
var result = folder.createFile(fileBlob);
debugger; // Stop to observe if in debugger
}
You want to save the downloaded file in the specific folder which has the name of game_thumb.
You want to set the value of cell "A1" to the filename of downloaded file.
If my understanding is correct, how about this modification?
For your question 1:
From your question, it is found that although I'm not sure whether the data is the file blob you want, the data from the URL can be retrieved. So in order to remove the error, please modify as follows.
From:
var folder = DocsList.getFolder('game_thumb');
To:
var folder = DriveApp.getFoldersByName('game_thumb').next();
In this modification, it supposes that the folder which has the name of game_thumb is only one in your Drive. If there are the folders with several same names, please tell me.
For your question 2:
Please modify as follows.
From:
var result = folder.createFile(fileBlob);
To:
var name = SpreadsheetApp.getActiveSheet().getRange("A1").getValue();
var result = folder.createFile(fileBlob).setName(name);
From your question, I'm not sure whether you are using the container-bound script or standalone script, and also I'm not sure where sheet there is the cell "A1" is. So this modification supposes that the cell "A1" of the active sheet is used.
References:
getFoldersByName()
getValue()
If I misunderstood your question and this modification didn't work, I apologize. At that time, can you provide the information of the situation?
This question already has answers here:
How to get the file URL from file name in Google Sheets with correct Authorization via custom function/script
(3 answers)
Closed 4 years ago.
The code below generates the IMAGE function for the sheet to show thumbnails of all (PDF) files in a chosen folder, obtained with a URL and the file ID:
function scannedMail() {
var files, file, sheet;
sheet = SpreadsheetApp.getActive().getSheetByName('ScannedMail');
files = DriveApp.getFoldersByName("ScannedMail").next().searchFiles('');
var i = 1;
while (files.hasNext()) {
var file = files.next();
var ID = file.getId();
sheet.getRange('A' + i).setValue("=IMAGE(\"https://drive.google.com/thumbnail?authuser=0&sz=w320&id=" + ID + "\"\)");
sheet.getRange('B' + i).setValue(file.getName());
i=i+1;
}
}
Yet it does not show the thumbnails. I found out that it shows just the ones where I manually retrieved the ID from getting a "shareable link". Apparently this ensures the right share settings to get the thumbnails of my own files.
1) Is the previous assumption correct, and why do I need to adapt share settings somehow, where I have read other files without any issues?
2) How can I adapt the script to adapt the share settings, or make it work otherwise?
The script is meant to operate just within my own Google account, and to keep the files private.
I tried sharing the folder with myself, but that does not make a difference (or sense). Is the script somehow regarded as being another user than myself?
Following suggestions from #Rubén and #Cooper, I have tried using insertImage either based on a URL:
sheet.insertImage(file.thumbnailLink, 1, i)
or based on a blob:
sheet.insertImage(file.getThumbnail(), 1, i)
But the most I could get out of Google was "We're sorry, a server error occurred. Please wait a bit and try again", with the code below:
function ScannedMail() {
var files, file, , name, blob, sheet;
sheet = SpreadsheetApp.getActive().getSheetByName('ScannedMail');
files = DriveApp.getFoldersByName("ScannedMail").next().searchFiles('');
var i = 1;
while (files.hasNext()) {
file = files.next();
name = file.getName(); //not needed, just for debugging
blob = file.getThumbnail();
sheet.insertImage(blob, 1, i); // it runs up to here...
i = i + 1;
}
}
The code execution gets stuck on the first occurrence of insertImage().
So we have 3 approaches (IMAGE function in sheet, insertImage(URL,1,1), and insertImage(blob,1,1)) but all 3 do not make a thumbnail appear, apart from the first method when you make the file public (not a serious option).
I don't see a duplicate question and answer that helps me find out what is wrong with my code, or helps me to somehow get the required thumbnails in the spreadsheet. The kindly proposed solutions did not succeed in that yet.
Try something like this:
function imgArray() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('ImageArray');
if(!sh){
sh=ss.insertSheet('ImageArray');
}
var imgA=[];
var folder=DriveApp.getFolderById('folderid');
var files=folder.getFiles();
while(files.hasNext()){
var file=files.next();
var filename=file.getName();
imgA.push(file.getBlob());
}
for(var r=0;r<imgA.length;r++){
sh.insertImage(imgA[r],1,r+1);
}
}
This was adapted from an answer from #Tanaike.
I guess this is what you were looking for:
function ScannedMail() {
var sheet = SpreadsheetApp.getActive().getSheetByName('ScannedMail');
var files = DriveApp.getFoldersByName("ScannedMail").next().searchFiles('');
var i = 1;
while (files.hasNext()) {
var file = files.next();
var blob = file.getBlob();
sheet.insertImage(blob, 1, i); // it runs up to here...
i = i + 1;
}
}
Google Sheets IMAGE built-in function only is able to retrieve images that are publicly available, so, yes you should have to adapt the sharing settings to make the images viewable by anyone.
In order to keep the files private you should not use IMAGE built-in function, you could use one of the methods of Class Sheet to insert images like insertImage(blobSource,column,row). See answer to Adding Image to Sheet from Drive for an example.
NOTES:
As custom functions run anonymously they can't be used them either.
According to Mogsdad answer to InsertImage(url,x,y) doesn't work with Google Drive insertImage(url,row,column) can't be used to insert images from Google Drive
Related
Image function or .insertImage not working for Google Apps Script and Sheets
What is the right way to put a Drive image into a Sheets cell programmatically?
I have Created a form that generates a response sheet. I also have created a Doc which is a Template that my responses fill into. From here it was being turned into a PDF and e-mailed to specific recipients. I now need to archive these into specific folders based on a columns answer. I simply first would like to just be able to move or copy them into a specific folder. How is this possible. I have used multiple scripts but just cant see where the disconnect is. Any help would be greatly appreciated. Thank you enter link description here
You could try using some code like this:
function moveFileToFolder() {
var theFolder = DriveApp.getFolderById('your Folder ID');
var theFile = DriveApp.getFileById('Your File ID').makeCopy(theFolder);
var oldFileName = theFile.getName();
var archivedName = oldFileName.slice(5);
Logger.log('archivedName: ' + archivedName);
archivedName = "archive" + archivedName;
theFile.setName(archivedName);
}
To delete the old file without having to send it to the trash:
//This requires the Drive API To be turned on in the Advanced Google Services.
//RESOURCES menu, ADVANCED GOOGLE SERVICES
function deleteFile(idToDLET) {
//idToDLET = 'the File ID';
//This deletes a file without needing to move it to the trash
var rtrnFromDLET = Drive.Files.remove(idToDLET);
}