新功能“插入”>“图像”>“ Google表格中的单元格中的图像”将图像插入单元格中,而不是作为OverGridImage插入。 我想以这种方式插入图片,然后从Google Apps脚本访问图片。这可能吗?
插入图像后,选择单元格时该单元格的公式为空白。我尝试搜索GAS参考,但找不到有关此相对较新功能的任何信息。 有关过度网格图像的信息。我希望单元内图像具有相似的功能。
我已经尝试过这样的事情:
// See what information is available on a cell with inserted image:
var image = sheet.getRange(1, 1).getFormula();
Logger.log(image);
日志显示为空。 我尝试了几种:.getImage()(不存在)、. getValue()、. getFormula()
我希望能够以某种方式访问图像URL或Blob。
答案 0 :(得分:2)
我相信您的目标如下。
不幸的是,在当前阶段,尚没有方法可以在Spreadsheet服务和Sheets API中检索Spreadsheet上单元格中的图像。 Rafa Guillermo's answer已经提到了这一点。因此,在这个答案中,我想提出一种解决方法,以使用Google Apps脚本检索单元格中的图像。
在这种解决方法中,我使用从Google Spreadsheet转换的Microsoft Excel数据。即使将Google Spreadsheet转换为Microsoft Excel Data,也不会删除单元格中的图像。我用这个当然,还可以从Spreadsheet转换的HTML数据中检索图像。但是在这种情况下,HTML数据的解析比Excel数据的解析有点复杂。因此,在这里,我想建议从从Spreadsheet转换的Excel数据中检索图像。此解决方法的流程如下。
在这种模式下,我想介绍一种简单的方法。
function myFunction() {
const spreadsheetId = SpreadsheetApp.getActiveSpreadsheet().getId();
const url = "https://docs.google.com/spreadsheets/export?exportFormat=xlsx&id=" + spreadsheetId;
const blob = UrlFetchApp.fetch(url, {headers: {authorization: `Bearer ${ScriptApp.getOAuthToken()}`}}).getBlob().setContentType(MimeType.ZIP);
const xlsx = Utilities.unzip(blob);
xlsx.forEach(b => {
const name = b.getName().match(/xl\/media\/(.+)/);
if (name) DriveApp.createFile(b.setName(name[1]));
});
}
setContentType(MimeType.ZIP)
时,在Utilities.unzip(blob)
处发生错误。请注意这一点。在此模式下,使用表格名称和单元格坐标从Spreadsheet检索图像。在这种情况下,脚本会变得有些复杂。因此,在这里,我想介绍一个使用Google Apps脚本库的示例脚本。 Ref当然,您可以在那里看到整个脚本。
在使用此脚本之前,请安装Google Apps脚本库的DocsServiceApp
(此GAS库的作者是tanaike。)。 Ref并运行myFunction
的功能。
function myFunction() {
const cell = "A1";
const sheetName = "Sheet1";
const spreadsheetId = SpreadsheetApp.getActiveSpreadsheet().getId();
const obj = DocsServiceApp.openBySpreadsheetId(spreadsheetId).getSheetByName(sheetName).getImages();
console.log(obj)
const blobs = obj.filter(({range, image}) => range.a1Notation == cell && image.innerCell);
console.log(blobs.length)
if (blobs.length > 0) DriveApp.createFile(blobs[0].image.blob);
}
image1
,image2
,不是原始文件名。因此,这似乎是当前的规范。答案 1 :(得分:2)
Rafa Guillermo和Tanaike都要求我根据对Tanaike帖子的评论做出回答。我在下面这样做,但是它属于解决方法的类别,而不是“答案”的类别。一个正确的答案将解决原始帖子中的确切问题。
正如我在评论中所说,我已经在简单的情况下使用了此方法,并且还进行了一些测试,表明该方法可以保留图像分辨率。由于我仅在以下简单情况下使用过此方法,因此我不知道它的一般工作原理。
下面提供的步骤是(尽我所能)我记得做一个特定示例时所经历的步骤。使用此方法后,这是最终结果的前十二行:
此示例总共有7100多行
第1列包含430多个图像或空白单元格,其中大多数重复 多次
第2列包含每个图片的唯一ID
第3列是使用 下面的方法
从Google表格单元格提取图像的步骤:
要将下载的图像文件名键入到工作表中的图像单元格中,请执行以下操作:
*在我的示例中,所有图像均具有p.txt,p(1).txt,p(2).txt等名称。在Mac OS Finder中,我选择了所有文件,并右键单击了“重命名文件”…然后使用replace选项将.txt替换为.jpg,将(1)替换为(001),依此类推…
**例如,可以使用Terminal ls -l
命令获取文件名列表
***例如,我使用了=vlookup(B2,unique!$B$2:$C$430,2,false)
答案 2 :(得分:1)
我只是尝试了一些非常基本的东西,它奏效了。也许并非在所有情况下都有效,取决于您之前是否通过公式添加了图像...
var ss = SpreadsheetApp.openByUrl(SPREADSHEET_URL);
var sheet = ss.getSheetByName(SHEET_NAME);
sheet.getRange('A1').setFormula('=IMAGE("https://developers.google.com/google-ads/scripts/images/reports.png")');
工作(它在单元格中,将自动适应调整大小):
var imgVal = sheet.getRange('A1').getFormula();
var regEx = /"(.*)"/gm;
var url = regEx.exec(imgVal)[1];
Logger.log(url);
日志将是:
答案 3 :(得分:1)
这个问题有点老了,但既然我今天遇到了这个问题,请允许我分享我的经验。
我意识到单元格的 getValue() 返回一个对象,它的文本是“CellImage”。这让我明白在这个单元格中有一个嵌入的图像。此对象似乎与 OverGridImage 对象相似(或相同)。至少,您可以使用 getAltTextTitle 和 getAltTextDescription 方法。
通过结合所有这些功能,我的解决方法是:
示例代码如下:
/*-------------------------------------------------------------------------
Custom event handler triggered when a single cell is selected in the spreadsheet.
@param {Event} e The onSelectionChange event.
-------------------------------------------------------------------------*/
function onSingleCellSelected(e) {
var cell = e.range.getCell(1, 1);
var v = cell.getValue();
if(v == "CellImage") {
var altText = v.getAltTextTitle();
Logger.log(v.getAltTextDescription());
if(altText == "@action(recordTime)"){
cell.setBackground("cyan");
}
}
}
答案 4 :(得分:0)
我来自G-Suite支持。这是一项新功能,遗憾的是,目前还没有一种方法可以使用Google Apps脚本或Sheets API将图像插入到单元格中。尝试使用具有以下参数的spreadsheets.get
方法获取单元格中的数据
spreadsheetId: "ID of private spreadsheet created in Drive"
includeGridData: True
ranges: D7
fields: sheets/data/rowData/values
将返回200 response
,但是不返回图像数据:
{
"sheets": [
{
"data": [
{
"rowData": [
{
"values": [
{
"userEnteredValue": {},
"effectiveValue": {},
"effectiveFormat": {
"backgroundColor": {
"red": 1,
"green": 1,
"blue": 1
},
"padding": {
"top": 2,
"right": 3,
"bottom": 2,
"left": 3
},
"horizontalAlignment": "LEFT",
"verticalAlignment": "BOTTOM",
"wrapStrategy": "OVERFLOW_CELL",
"textFormat": {
"foregroundColor": {},
"fontFamily": "Arial",
"fontSize": 10,
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false
},
"hyperlinkDisplayType": "PLAIN_TEXT"
}
}
]
}
]
}
]
}
]
}
但是,在Google的问题跟踪器上有一项针对此功能的请求,您可以找到here。如果您转到功能请求页面并单击左上角的星号,则可以让Google知道您也希望使用此功能,并会自动获取有关其进度的更新。
答案 5 :(得分:0)
这个答案是关于插入细胞内图像。我还没有找到实际提取图像数据的方法,因此 Panos's answer 是读取单元格内图像数据的最佳选择。
有几种不同的方法可以做到这一点,其中一些使用一些未记录的 API。
=IMAGE(<http url>)
=IMAGE
是一个标准函数,它显示在单元格内的图像中。它几乎与手动插入内嵌图像完全相同。
=IMAGE
一旦你有一个 =IMAGE
图像,你可以复制它并按值粘贴它,这将复制图像没有公式(如果你出于某种原因想要那个)。您可以使用 copyTo
function:
srcImageRange.copyTo(dstRange, { contentsOnly: true })
这个无公式的图像只能与真正的单元格内图像区分开来,因为当您右键单击它时,它会缺少“替代文本”和“将图像置于单元格上”上下文菜单选项。这些选项仅显示在真实的细胞内图像上。
CellImage
API当您对单元格内图像(公式和手动插入)调用 getValue()
时,您会得到一个 CellImage
实例。
细胞图像
道具/方法 | (返回)类型 | 说明 |
---|---|---|
toString() |
string |
返回"CellImage" 。 |
getContentUrl() |
? | 总是抛出错误? |
toBuilder() |
CellImageBuilder |
将其转换为可写的 CellImageBuilder 实例。 |
getAltTextDescription() |
string |
返回替代文本描述。 |
getAltTextTitle() |
string |
返回替代文本标题。 |
getUrl() |
? | 似乎不起作用,总是返回未定义。 :( |
valueType |
? | 和SpreadsheetApp.ValueType 一样,好像没什么意义。 |
CellImageBuilder
具有与 CellImage
相同的所有属性和方法以及这些附加属性:
道具/方法 | (返回)类型 | 说明 |
---|---|---|
toString() |
string |
返回"CellImageBuilder" 。 |
build() |
CellImage |
转换为(只读)CellImage 实例。 |
setSourceUrl(string) |
void |
通过提供网络或数据 URL 更新图像。 |
setAltTextTitle(string) |
void |
设置替代文本标题。 |
setAltTextDescription(string) |
void |
设置替代文字描述。 |
我看到在 IMAGE()
上使用它的主要好处是它支持数据 URL,因此间接支持 blob。
请记住,未记录的 API 可能会更改,恕不另行通知。
// 1 (or just use IMAGE in formula directly)
function insertImageFormula(range, httpUrl) {
range.setFormula(`=IMAGE("${httpUrl}")`);
}
// 2
function insertImageValue(range, httpUrl) {
range.setFormula(`=IMAGE("${httpUrl}")`);
SpreadsheetApp.flush(); // Flush needed for image to load.
range.copyTo(range, { contentsOnly: true }); // Copy value onto itself, removing the formula.
}
// 3
function insertCellImage(range, sourceUrl) {
range.setFormula('=IMAGE("http")'); // Set blank image to get CellImageBuilder handle.
const builder = range.getValue().toBuilder();
builder.setSourceUrl(sourceUrl);
builder.setAltTextDescription(sourceUrl); // Put url in description for later identification, for example.
range.setValue(builder.build());
}
const DATA_URI = "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7///"
+ "/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAos"
+ "J6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7";
function test() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
sheet.clear();
sheet.getRange(1, 1).setValue("IMAGE formula");
insertImageFormula(sheet.getRange(2, 1), "https://www.google.com/images/icons/illustrations/paper_pencil-y128.png");
sheet.getRange(1, 2).setValue("Copied-by-value IMAGE");
insertImageValue(sheet.getRange(2, 2), "https://www.google.com/images/icons/illustrations/paper_pencil-y128.png");
sheet.getRange(1, 3).setValue("In-Cell Image (Http URL)");
insertCellImage(sheet.getRange(2, 3), "https://www.google.com/images/icons/illustrations/paper_pencil-y128.png");
sheet.getRange(1, 4).setValue("In-Cell Image (DATA URI)");
insertCellImage(sheet.getRange(2, 4), DATA_URI);
sheet.getRange(1, 5).setValue("In-Cell Image (Blob DATA URI)");
const blob = UrlFetchApp.fetch("https://www.gstatic.com/script/apps_script_1x_24dp.png").getBlob();
insertCellImage(sheet.getRange(2, 5), blobToDataUrl(blob));
}
function blobToDataUrl(blob) {
return `data:${blob.getContentType()};base64,${Utilities.base64Encode(blob.getBytes())}`
}