在模板化 HTML(Google Apps 脚本)中提供云端硬盘存储的图像
Serving Drive-stored images in templated HTML (Google Apps Script)
我一直按照说明 让我的 Gmail 签名模板显示存储在 Google 驱动器上的图像作为徽标。
目标是让图像标记的 'src' 属性指向图像并将其内联显示。在上面链接的答案中,图像 blob 是使用 UrlFetchApp 获取的。在我的代码中,我调用 DriveApp 的 openById(id) 方法来打开图像文件并获取 blob。
但是,这两种方法似乎都不起作用。只有当我将 'src' 直接指向图像 URL 时,它才会加载图像。我尝试同时使用 base64Encode 和 base64EncodeWebSafe 但签名只显示图像的空容器。
我在这里错过了什么?
HTML模板
<table>
<tbody>
<tr>
<td>
<img src="{{config.imgData}}" alt="my logo">
</td>
<td>
<table>
<tbody>
<tr><td> My name is {{config.name}} </td> </tr>
<tr><td> www.example.com </td> </tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
GS码
var config = {
name: "Anton",
imgData: ""
}
function updateSignature() {
var imgFileId = "DRIVE FILE ID";
var imgFile = DriveApp.getFileById(imgFileId);
var imgBlob = imgFile.getBlob().getAs("image/png"); //getAs doesn't change anything
//Get content type and bytes
var contentType = imgBlob.getContentType();
var imgBytes = imgBlob.getBytes();
var imgData = contentType + ";base64," + Utilities.base64Encode(imgData);
config.imgData = imgData;
var alias = Gmail.Users.Settings.SendAs.get("me", myEmail);
//Get signature html as a string
var templateString = HtmlService.createHtmlOutputFromFile("signature_template").getContent();
for (var configKey in config) {
if (config.hasOwnProperty(configKey)) {
templateString = templateString.replace("{{config." + configKey + "}}", config[configKey]);
}
}
var finalTemplate = HtmlService.createHtmlOutput(templateString).getContent();
alias.signature = finalTemplate;
Gmail.Users.Settings.SendAs.update(alias, "me", myEmail);
}
试试这个:
您需要做的就是将默认图像文件 ID 添加到函数 convertImageToDataURI 中,然后启动对话框。或者您也可以部署为 Web 应用程序。为了我的目的,我通常将图像的大小缩小到小于 1000 像素宽,并保持纵横比小于一。
Code.gs:
function onOpen() {
SpreadsheetApp.getUi().createMenu('My Tools')
.addItem('Display Dialog', 'displayDialog')
.addItem('Get File Ids from FolderId','getFileIds')
.addToUi();
}
function convertImageToDataURI(fileId) {
var fileId=fileId||'default image file id';
if(fileId) {
var file=DriveApp.getFileById(fileId);
var blob=file.getBlob();
var dataUri='data:' + blob.getContentType() + ';base64,' + Utilities.base64Encode(blob.getBytes());
return dataUri;
}
}
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
function displayDialog() {
var userInterface=HtmlService.createTemplateFromFile('image').evaluate();
SpreadsheetApp.getUi().showModelessDialog(userInterface, "For the Birds");
}
function doGet() {
return HtmlService.createTemplateFromFile('image').evaluate();
}
resources.html:(本例不需要)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
css.html:(本例不需要)
<style>
body {background-color:#ffffff;}
input{padding:2px;margin:2px;}
</style>
script.html:(本例不需要)
<script>
console.log('script.html code');
</script>
content.html为空
images.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= include('resources') ?>
<?!= include('css') ?>
</head>
<body>
<img id="birds" src="<?!=convertImageToDataURI()?>" width="320" />
<?!= include('content') ?>
<?!= include('script') ?>
</body>
</html>
<html><head>
如果您需要一个工具来获取文件夹中图像的文件 ID,请试试这个功能:
function getFileIds() {
var resp=SpreadsheetApp.getUi().prompt("Folder Id","Enter Folder Id", SpreadsheetApp.getUi().ButtonSet.OK_CANCEL);
if(resp.getSelectedButton()==SpreadsheetApp.getUi().Button.OK && resp.getResponseText().length>0) {
try{
var folder=DriveApp.getFolderById(resp.getResponseText());
var files=folder.getFiles();
var html='<style>td,th{border:1px solid black;padding:2px 5px;}</style><table><tr><th>File Name</th><th>File Id</th><th>Type</th></tr>';
while(files.hasNext()) {
var file=files.next();
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>', file.getName(),file.getId(),file.getMimeType());
}
html+='</table><br /><input type="button" value="Close" onClick="google.script.host.close();" />';
var userInterface=HtmlService.createHtmlOutput(html).setWidth(800).setHeight(400);
SpreadsheetApp.getUi().showModelessDialog(userInterface, "Files in Folder");
}
catch(e){SpreadsheetApp.getUi().alert(e);}
}else{
SpreadsheetApp.getUi().alert("Invalid or Missing Inputs: No FileId Provided");
}
}
这是我的对话框的样子:
- 您想使用模板 HTML.
将您的 Google 驱动器图像放入您的 Gmail 签名中
- 您想使用 Google Apps 脚本实现此目的。
如果我的理解是正确的,这个答案怎么样?请将此视为几个可能的答案之一。
问题和解决方法:
当我检查the official document时,我看到签名的图像如下。
- If you added a photo or image from Google Drive, you'll need to share your image publicly for it to appear in your signature. Note: If you use Gmail with your work or school account, ask your administrator to let you share images publicly.
- Search for an image, like your company logo, then get the image URL.
- Add your own image to Google and use that URL.
当data:image/png;base64,###
用于图片标签的src
时,发现用Gmail.Users.Settings.SendAs.update()
更新的签名不包含src
属性。当使用 https://###
时,使用 Gmail.Users.Settings.SendAs.update()
更新的签名包括 src
属性。
从以上情况来看,认为data:image/png;base64,###
可能无法用于签名的图片标签src
。这可能是规范。
那么为了把来自Google驱动器的图片放入,下面的流程如何?我认为这是 the official document.
中显示的方法
- 在 Google 驱动器中公开共享图像。
- 把图片的URL放到签名里
修改后的脚本:
当你的脚本修改后,下面的修改怎么样?
发件人:
var imgBlob = imgFile.getBlob().getAs("image/png"); //getAs doesn't change anything
//Get content type and bytes
var contentType = imgBlob.getContentType();
var imgBytes = imgBlob.getBytes();
var imgData = contentType + ";base64," + Utilities.base64Encode(imgData);
收件人:
imgFile.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
var imgData = "https://drive.google.com/uc?export=download&id=" + imgFileId;
注:
- 手动将图片放入签名时,使用以上URL,文件自动公开分享。
- 顺便说一句,在您当前的脚本中,
var imgData = contentType + ";base64," + Utilities.base64Encode(imgData);
的 imgData
可能是 imgBytes
。而当你想使用base64数据将图像放入src
时,请使用src="data:image/png;base64,###"
。在您的脚本中,使用了 src="image/png;base64,###"
。
参考文献:
如果我误解了您的问题并且这不是您想要的方向,我深表歉意。
我一直按照说明
目标是让图像标记的 'src' 属性指向图像并将其内联显示。在上面链接的答案中,图像 blob 是使用 UrlFetchApp 获取的。在我的代码中,我调用 DriveApp 的 openById(id) 方法来打开图像文件并获取 blob。
但是,这两种方法似乎都不起作用。只有当我将 'src' 直接指向图像 URL 时,它才会加载图像。我尝试同时使用 base64Encode 和 base64EncodeWebSafe 但签名只显示图像的空容器。
我在这里错过了什么?
HTML模板
<table>
<tbody>
<tr>
<td>
<img src="{{config.imgData}}" alt="my logo">
</td>
<td>
<table>
<tbody>
<tr><td> My name is {{config.name}} </td> </tr>
<tr><td> www.example.com </td> </tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
GS码
var config = {
name: "Anton",
imgData: ""
}
function updateSignature() {
var imgFileId = "DRIVE FILE ID";
var imgFile = DriveApp.getFileById(imgFileId);
var imgBlob = imgFile.getBlob().getAs("image/png"); //getAs doesn't change anything
//Get content type and bytes
var contentType = imgBlob.getContentType();
var imgBytes = imgBlob.getBytes();
var imgData = contentType + ";base64," + Utilities.base64Encode(imgData);
config.imgData = imgData;
var alias = Gmail.Users.Settings.SendAs.get("me", myEmail);
//Get signature html as a string
var templateString = HtmlService.createHtmlOutputFromFile("signature_template").getContent();
for (var configKey in config) {
if (config.hasOwnProperty(configKey)) {
templateString = templateString.replace("{{config." + configKey + "}}", config[configKey]);
}
}
var finalTemplate = HtmlService.createHtmlOutput(templateString).getContent();
alias.signature = finalTemplate;
Gmail.Users.Settings.SendAs.update(alias, "me", myEmail);
}
试试这个:
您需要做的就是将默认图像文件 ID 添加到函数 convertImageToDataURI 中,然后启动对话框。或者您也可以部署为 Web 应用程序。为了我的目的,我通常将图像的大小缩小到小于 1000 像素宽,并保持纵横比小于一。
Code.gs:
function onOpen() {
SpreadsheetApp.getUi().createMenu('My Tools')
.addItem('Display Dialog', 'displayDialog')
.addItem('Get File Ids from FolderId','getFileIds')
.addToUi();
}
function convertImageToDataURI(fileId) {
var fileId=fileId||'default image file id';
if(fileId) {
var file=DriveApp.getFileById(fileId);
var blob=file.getBlob();
var dataUri='data:' + blob.getContentType() + ';base64,' + Utilities.base64Encode(blob.getBytes());
return dataUri;
}
}
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
function displayDialog() {
var userInterface=HtmlService.createTemplateFromFile('image').evaluate();
SpreadsheetApp.getUi().showModelessDialog(userInterface, "For the Birds");
}
function doGet() {
return HtmlService.createTemplateFromFile('image').evaluate();
}
resources.html:(本例不需要)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
css.html:(本例不需要)
<style>
body {background-color:#ffffff;}
input{padding:2px;margin:2px;}
</style>
script.html:(本例不需要)
<script>
console.log('script.html code');
</script>
content.html为空
images.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= include('resources') ?>
<?!= include('css') ?>
</head>
<body>
<img id="birds" src="<?!=convertImageToDataURI()?>" width="320" />
<?!= include('content') ?>
<?!= include('script') ?>
</body>
</html>
<html><head>
如果您需要一个工具来获取文件夹中图像的文件 ID,请试试这个功能:
function getFileIds() {
var resp=SpreadsheetApp.getUi().prompt("Folder Id","Enter Folder Id", SpreadsheetApp.getUi().ButtonSet.OK_CANCEL);
if(resp.getSelectedButton()==SpreadsheetApp.getUi().Button.OK && resp.getResponseText().length>0) {
try{
var folder=DriveApp.getFolderById(resp.getResponseText());
var files=folder.getFiles();
var html='<style>td,th{border:1px solid black;padding:2px 5px;}</style><table><tr><th>File Name</th><th>File Id</th><th>Type</th></tr>';
while(files.hasNext()) {
var file=files.next();
html+=Utilities.formatString('<tr><td>%s</td><td>%s</td><td>%s</td></tr>', file.getName(),file.getId(),file.getMimeType());
}
html+='</table><br /><input type="button" value="Close" onClick="google.script.host.close();" />';
var userInterface=HtmlService.createHtmlOutput(html).setWidth(800).setHeight(400);
SpreadsheetApp.getUi().showModelessDialog(userInterface, "Files in Folder");
}
catch(e){SpreadsheetApp.getUi().alert(e);}
}else{
SpreadsheetApp.getUi().alert("Invalid or Missing Inputs: No FileId Provided");
}
}
这是我的对话框的样子:
- 您想使用模板 HTML. 将您的 Google 驱动器图像放入您的 Gmail 签名中
- 您想使用 Google Apps 脚本实现此目的。
如果我的理解是正确的,这个答案怎么样?请将此视为几个可能的答案之一。
问题和解决方法:
当我检查the official document时,我看到签名的图像如下。
- If you added a photo or image from Google Drive, you'll need to share your image publicly for it to appear in your signature. Note: If you use Gmail with your work or school account, ask your administrator to let you share images publicly.
- Search for an image, like your company logo, then get the image URL.
- Add your own image to Google and use that URL.
当data:image/png;base64,###
用于图片标签的src
时,发现用Gmail.Users.Settings.SendAs.update()
更新的签名不包含src
属性。当使用 https://###
时,使用 Gmail.Users.Settings.SendAs.update()
更新的签名包括 src
属性。
从以上情况来看,认为data:image/png;base64,###
可能无法用于签名的图片标签src
。这可能是规范。
那么为了把来自Google驱动器的图片放入,下面的流程如何?我认为这是 the official document.
中显示的方法- 在 Google 驱动器中公开共享图像。
- 把图片的URL放到签名里
修改后的脚本:
当你的脚本修改后,下面的修改怎么样?
发件人:
var imgBlob = imgFile.getBlob().getAs("image/png"); //getAs doesn't change anything
//Get content type and bytes
var contentType = imgBlob.getContentType();
var imgBytes = imgBlob.getBytes();
var imgData = contentType + ";base64," + Utilities.base64Encode(imgData);
收件人:
imgFile.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
var imgData = "https://drive.google.com/uc?export=download&id=" + imgFileId;
注:
- 手动将图片放入签名时,使用以上URL,文件自动公开分享。
- 顺便说一句,在您当前的脚本中,
var imgData = contentType + ";base64," + Utilities.base64Encode(imgData);
的imgData
可能是imgBytes
。而当你想使用base64数据将图像放入src
时,请使用src="data:image/png;base64,###"
。在您的脚本中,使用了src="image/png;base64,###"
。
参考文献:
如果我误解了您的问题并且这不是您想要的方向,我深表歉意。