Google 应用程序脚本有时无法将图像插入电子表格
Google app script can not insert image to spreadsheet sometimes
我的项目是Ruby在Rails上写的,因为google-api-client gem不支持插入图片传播sheet 到 sheet apis,所以我正在使用 Google 应用程序脚本来处理此任务。大多数情况下,插入已成功通过此调用:
@app_script.run_script(script_id, request)
我只是为所有好奇的人提供我的脚本:
https://script.google.com/a/vectorgroup.vn/d/1ndcgpfJMj3YdKj0pEvHWz0pF4NtcQyR1Qg8wj7ZnpKfIwP2UsH0xaYq4/edit?splash=yes
问题是有时调用失败并出现以下错误:
Error detail: [{\"@type\"=>\"type.googleapis.com/google.apps.script.v1.ExecutionError\", \"scriptStackTraceElements\"=>[{\"function\"=>\"addImageOnSpreadsheet\"}], \"errorMessage\"=>\"Exception: Error retrieving image from URL or bad URL: https://drive.google.com/uc?id=1MS6KMfua7kZCSGMUhny4kDUvalxTkoKJ&export=download\", \"errorType\"=>\"ScriptError\"}]"
2020-04-06T06:03:33.821Z pid=26645 tid=tz8bh class=ImageTakerWorker jid=d847bf91beea8aeb4a30b042 elapsed=11.689 INFO: done
Error: 3"
"Error detail: [{\"@type\"=>\"type.googleapis.com/google.apps.script.v1.ExecutionError\", \"scriptStackTraceElements\"=>[{\"function\"=>\"addImageOnSpreadsheet\"}], \"errorMessage\"=>\"Exception: Error retrieving image from URL or bad URL: https://drive.google.com/uc?id=1G9EDgvygwVztMG66FArZ6BEFpzW71izA&export=download\", \"errorType\"=>\"ScriptError\"}]"
2020-04-06T08:00:28.330Z pid=26645 tid=tz7zl class=ImageTakerWorker jid=a6b4fcb47db15f71dbf1d3f5 elapsed=6.514 INFO: done
"Insert image ERROR: #, #"
"Error: 3"
"Error detail: [{\"@type\"=>\"type.googleapis.com/google.apps.script.v1.ExecutionError\", \"scriptStackTraceElements\"=>[{\"function\"=>\"addImageOnSpreadsheet\"}], \"errorMessage\"=>\"Exception: Error retrieving image from URL or bad URL: https://drive.google.com/uc?id=1_3KzBDDgpINMCNkEZj2LivqdUaxFKZNT&export=download\", \"errorType\"=>\"ScriptError\"}]"
2020-04-06T08:00:28.941Z pid=26645 tid=tzahx class=ImageTakerWorker jid=8010f8c64cb9a0efa672b713 elapsed=7.121 INFO: done
问题似乎发生在 url 图像上,不知何故 google 应用程序脚本无法提取图像数据。但是当问题发生时,我只是将上面的图像 url 手动复制并粘贴到浏览器的错误日志中,它可以成功下载图像。
请注意,我已经为图像 url.
设置了 public
下面是我的 google 应用程序脚本部分:
class GoogleAppScript
APPLICATION_NAME = "Insert image to spreadsheet".freeze
def initialize(user_id, sheet_id, options = {})
@user = User.find(user_id)
@sheet_id = sheet_id
@from_class = options[:from_class]
@service = options[:service]
@keyword = options[:keyword]
@sheet_name = options[:service] == "google" ? "G" + options[:keyword].strip : "Y" + options[:keyword].strip
@image_file_id = options[:image_file_id]
@google_authorization = GoogleAuthorization.new(@user).authorize
@app_script = Google::Apis::ScriptV1::ScriptService.new
@app_script.client_options.application_name = APPLICATION_NAME
@app_script.authorization = @google_authorization
end
def execute
script_id = "1ndcgpfJMj3YdKj0pEvHWz0pF4NtcQyR1Qg8wj7ZnpKfIwP2UsH0xaYq4"
url_image = "https://drive.google.com/uc?id=#{@image_file_id}&export=download"
start_col = 1
if @from_class == "ImageX"
start_row = 51
width = 692
height = 1500
else # "ImageY"
start_row = @keyword.last == " " ? 30 : 9
width = 694
height = 418
end
request = Google::Apis::ScriptV1::ExecutionRequest.new(
function: "addImageOnSpreadsheet",
parameters: [@sheet_id, @sheet_name, url_image, start_col, start_row, width, height],
)
begin
response = @app_script.run_script(script_id, request)
if response.error
# Retry until success
# ImageTakerWorker.perform_async(@user.id, @sheet_id, @sheet_name, @image_file_id)
p "Insert image ERROR: #{response}, #{response.error}"
p "Error: #{response.error.code}"
p "Error detail: #{response.error.details}"
else
p "Insert image successfully"
end
rescue Google::Apis::ClientError
# Handle the error...
end
end
end
有人对此有经验吗?
这是我的理解:
- 在您的情况下,将图像插入 Google 电子表格时,会出现
Server error
错误。
- 在这种情况下,认为图像的大小超过了限制。 Reference
- 您想在插入到 Google 电子表格的限制大小超过时调整图像大小。
问题和解决方法:
在这种情况下,即使使用setWidth
和setHeight
,也无法消除错误。因为插入图片时出现错误。所以在这个答案中,我想建议通过在 Google Apps 脚本库中调整大小来插入图像。
修改后的脚本:
当你的脚本修改后,变成如下。在使用此脚本之前,请先安装 a GAS library of ImgApp.
function addImageOnSpreadsheet(spreadsheet_id, sheet_name, image_file_id, column, row, width, height) {
let blobSource = DriveApp.getFileById(image_file_id).getBlob();
const obj = ImgApp.getSize(blobSource);
if (obj.height * obj.width > 1048576) {
blobSource = ImgApp.doResize(image_file_id, width).blob;
}
let image = SpreadsheetApp.openById(spreadsheet_id).insertImage(blobSource, column, row);
image.setWidth(width).setHeight(height);
}
- 作为测试,我建议直接在脚本编辑器中运行脚本。
注:
- 在本例中,使用了以下3个作用域。尽管我不确定您的整个脚本,但请添加这些范围。请注意这一点。在您的情况下,请添加范围并重新授权。这样,就可以使用有效的访问令牌。
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/script.external_request
https://www.googleapis.com/auth/spreadsheets
参考文献:
已添加:
示例脚本:
此示例脚本用于接收多个文件 ID。
function addImageOnSpreadsheet(ar) {
ar.forEach(o => {
let blobSource = DriveApp.getFileById(o.image_file_id).getBlob();
const obj = ImgApp.getSize(blobSource);
if (obj.height * obj.width > 1048576) {
blobSource = ImgApp.doResize(o.image_file_id, o.width).blob;
}
var image = SpreadsheetApp.openById(o.spreadsheet_id).insertImage(blobSource, o.column, o.row);
image.setWidth(o.width).setHeight(o.height);
});
}
例如ar
如下
ar = [
{spreadsheet_id: "###", image_file_id: "###", column: ##, row: ##, width: ###, height: ###},
{spreadsheet_id: "###", image_file_id: "###", column: ##, row: ##, width: ###, height: ###},
,
,
];
我的项目是Ruby在Rails上写的,因为google-api-client gem不支持插入图片传播sheet 到 sheet apis,所以我正在使用 Google 应用程序脚本来处理此任务。大多数情况下,插入已成功通过此调用:
@app_script.run_script(script_id, request)
我只是为所有好奇的人提供我的脚本: https://script.google.com/a/vectorgroup.vn/d/1ndcgpfJMj3YdKj0pEvHWz0pF4NtcQyR1Qg8wj7ZnpKfIwP2UsH0xaYq4/edit?splash=yes
问题是有时调用失败并出现以下错误:
Error detail: [{\"@type\"=>\"type.googleapis.com/google.apps.script.v1.ExecutionError\", \"scriptStackTraceElements\"=>[{\"function\"=>\"addImageOnSpreadsheet\"}], \"errorMessage\"=>\"Exception: Error retrieving image from URL or bad URL: https://drive.google.com/uc?id=1MS6KMfua7kZCSGMUhny4kDUvalxTkoKJ&export=download\", \"errorType\"=>\"ScriptError\"}]" 2020-04-06T06:03:33.821Z pid=26645 tid=tz8bh class=ImageTakerWorker jid=d847bf91beea8aeb4a30b042 elapsed=11.689 INFO: done Error: 3" "Error detail: [{\"@type\"=>\"type.googleapis.com/google.apps.script.v1.ExecutionError\", \"scriptStackTraceElements\"=>[{\"function\"=>\"addImageOnSpreadsheet\"}], \"errorMessage\"=>\"Exception: Error retrieving image from URL or bad URL: https://drive.google.com/uc?id=1G9EDgvygwVztMG66FArZ6BEFpzW71izA&export=download\", \"errorType\"=>\"ScriptError\"}]" 2020-04-06T08:00:28.330Z pid=26645 tid=tz7zl class=ImageTakerWorker jid=a6b4fcb47db15f71dbf1d3f5 elapsed=6.514 INFO: done "Insert image ERROR: #, #" "Error: 3" "Error detail: [{\"@type\"=>\"type.googleapis.com/google.apps.script.v1.ExecutionError\", \"scriptStackTraceElements\"=>[{\"function\"=>\"addImageOnSpreadsheet\"}], \"errorMessage\"=>\"Exception: Error retrieving image from URL or bad URL: https://drive.google.com/uc?id=1_3KzBDDgpINMCNkEZj2LivqdUaxFKZNT&export=download\", \"errorType\"=>\"ScriptError\"}]" 2020-04-06T08:00:28.941Z pid=26645 tid=tzahx class=ImageTakerWorker jid=8010f8c64cb9a0efa672b713 elapsed=7.121 INFO: done
问题似乎发生在 url 图像上,不知何故 google 应用程序脚本无法提取图像数据。但是当问题发生时,我只是将上面的图像 url 手动复制并粘贴到浏览器的错误日志中,它可以成功下载图像。 请注意,我已经为图像 url.
设置了 public下面是我的 google 应用程序脚本部分:
class GoogleAppScript
APPLICATION_NAME = "Insert image to spreadsheet".freeze
def initialize(user_id, sheet_id, options = {})
@user = User.find(user_id)
@sheet_id = sheet_id
@from_class = options[:from_class]
@service = options[:service]
@keyword = options[:keyword]
@sheet_name = options[:service] == "google" ? "G" + options[:keyword].strip : "Y" + options[:keyword].strip
@image_file_id = options[:image_file_id]
@google_authorization = GoogleAuthorization.new(@user).authorize
@app_script = Google::Apis::ScriptV1::ScriptService.new
@app_script.client_options.application_name = APPLICATION_NAME
@app_script.authorization = @google_authorization
end
def execute
script_id = "1ndcgpfJMj3YdKj0pEvHWz0pF4NtcQyR1Qg8wj7ZnpKfIwP2UsH0xaYq4"
url_image = "https://drive.google.com/uc?id=#{@image_file_id}&export=download"
start_col = 1
if @from_class == "ImageX"
start_row = 51
width = 692
height = 1500
else # "ImageY"
start_row = @keyword.last == " " ? 30 : 9
width = 694
height = 418
end
request = Google::Apis::ScriptV1::ExecutionRequest.new(
function: "addImageOnSpreadsheet",
parameters: [@sheet_id, @sheet_name, url_image, start_col, start_row, width, height],
)
begin
response = @app_script.run_script(script_id, request)
if response.error
# Retry until success
# ImageTakerWorker.perform_async(@user.id, @sheet_id, @sheet_name, @image_file_id)
p "Insert image ERROR: #{response}, #{response.error}"
p "Error: #{response.error.code}"
p "Error detail: #{response.error.details}"
else
p "Insert image successfully"
end
rescue Google::Apis::ClientError
# Handle the error...
end
end
end
有人对此有经验吗?
这是我的理解:
- 在您的情况下,将图像插入 Google 电子表格时,会出现
Server error
错误。 - 在这种情况下,认为图像的大小超过了限制。 Reference
- 您想在插入到 Google 电子表格的限制大小超过时调整图像大小。
问题和解决方法:
在这种情况下,即使使用setWidth
和setHeight
,也无法消除错误。因为插入图片时出现错误。所以在这个答案中,我想建议通过在 Google Apps 脚本库中调整大小来插入图像。
修改后的脚本:
当你的脚本修改后,变成如下。在使用此脚本之前,请先安装 a GAS library of ImgApp.
function addImageOnSpreadsheet(spreadsheet_id, sheet_name, image_file_id, column, row, width, height) {
let blobSource = DriveApp.getFileById(image_file_id).getBlob();
const obj = ImgApp.getSize(blobSource);
if (obj.height * obj.width > 1048576) {
blobSource = ImgApp.doResize(image_file_id, width).blob;
}
let image = SpreadsheetApp.openById(spreadsheet_id).insertImage(blobSource, column, row);
image.setWidth(width).setHeight(height);
}
- 作为测试,我建议直接在脚本编辑器中运行脚本。
注:
- 在本例中,使用了以下3个作用域。尽管我不确定您的整个脚本,但请添加这些范围。请注意这一点。在您的情况下,请添加范围并重新授权。这样,就可以使用有效的访问令牌。
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/script.external_request
https://www.googleapis.com/auth/spreadsheets
参考文献:
已添加:
示例脚本:
此示例脚本用于接收多个文件 ID。
function addImageOnSpreadsheet(ar) {
ar.forEach(o => {
let blobSource = DriveApp.getFileById(o.image_file_id).getBlob();
const obj = ImgApp.getSize(blobSource);
if (obj.height * obj.width > 1048576) {
blobSource = ImgApp.doResize(o.image_file_id, o.width).blob;
}
var image = SpreadsheetApp.openById(o.spreadsheet_id).insertImage(blobSource, o.column, o.row);
image.setWidth(o.width).setHeight(o.height);
});
}
例如
ar
如下ar = [ {spreadsheet_id: "###", image_file_id: "###", column: ##, row: ##, width: ###, height: ###}, {spreadsheet_id: "###", image_file_id: "###", column: ##, row: ##, width: ###, height: ###}, , , ];