Google App Script(异常:从URL检索图像时出错或URL无效)

huangapple go评论57阅读模式
英文:

Google App Script (Exception: Error retrieving image from URL or bad URL)

问题

I'm here to provide the translated portion of your text. Here it is:

"我正试图创建一个Google Apps脚本代码,用于从文件夹中检索图像文件并将它们插入到一列的单元格中。

此电子表格中的所有工作表都具有相同的模板,因此所有getRange()的行和列都是正确的。
我尝试检索图像的所有文件夹中的所有图像都具有标准化的尺寸为1,202 x 720像素(98KB),为JPG格式,并且它们的名称只是Slide1.JPG,Slide2.JPG等。

以下是代码部分:

const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getActiveSheet();

function insertImgsFromDriveFolder() {
  Logger.log('sheet name: ' + sheet.getSheetName());
  Logger.log('Drive Folder ID cell: ' + sheet.getRange(1,4).getA1Notation());
  var folderID = sheet.getRange(1,4).getValue();
  Logger.log('Drive Folder ID: ' + folderID);
  var folder = DriveApp.getFolderById(folderID);

  var files = folder.getFiles(); // 检索文件的迭代器,有时以相反顺序

  // 因此必须获取文件夹中的项目数
  var count = 0;
  while (files.hasNext()) {
    var file = files.next();
    count++;
  }

  // 然后按名称搜索每个项目并在表格中显示
  for (let i=1; i <= count; i++) {
    var imgFile = folder.getFilesByName("Slide" + i + ".JPG").next();
    //imgFile.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.EDIT);
    Logger.log('filename: ' + imgFile);
    img = SpreadsheetApp.newCellImage().setSourceUrl('https://drive.google.com/uc?export=view&id=' + imgFile.getId()).build();
    Logger.log('file: ' + img);
    sheet.getRange(i+4,2).setValue(img);
  }
}

在执行日志中收到的错误消息是“异常:无法从URL检索图像或URL无效:<URL>”,出现在sheet.getRange(i+4,2).setValue(img);行。

我能够通过在Chrome的无痕模式下复制错误中的URL来查看该图像(未登录任何Google帐户),因此我认为该文件是公开可访问的。我还能够使用=IMAGE(&lt;URL&gt;)手动将图像插入到单元格中。取消注释imgFile.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.EDIT);以强制其成为公共可访问结果会导致相同的错误。

我还认为文件大小不是问题,因为它小于此帖子中指定的大小限制。

我也不想使用insertImage(),因为我希望将图像插入到单元格中。
我还尝试了这里这里这里提供的解决方案。

请告诉我我可以尝试修复此问题的方法!如果您还有关于如何强制FileIteration按字母/创建日期顺序获取文件的解决方案,那将是很棒的。

提前感谢!"

英文:

I'm tryna create a google app script code that will retrieve image files from a folder and insert them into cells in a column.

All sheets within this spreadsheet have the same template, so all getRange() rows and columns are correct.
All images within all folders that I'm trying to retrieve images from have standardised dimensions of ‪1,202 x 720‬ pixels (98KB), are in JPG format, and its names are just Slide1.JPG, Slide2.JPG, etc.

const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getActiveSheet();

function insertImgsFromDriveFolder() {
  Logger.log(&#39;sheet name: &#39; + sheet.getSheetName());
  Logger.log(&#39;Drive Folder ID cell: &#39; + sheet.getRange(1,4).getA1Notation());
  var folderID = sheet.getRange(1,4).getValue();
  Logger.log(&#39;Drive Folder ID: &#39; + folderID);
  var folder = DriveApp.getFolderById(folderID);

  var files = folder.getFiles(); // retrieves Iteration of files, sometimes in reverse order

  // so must get count of no items in folder
  var count = 0;
  while (files.hasNext()) {
    var file = files.next();
    count++;
  }

  // then search for each item by name + display in sheet
  for (let i=1; i &lt;= count; i++) {
    var imgFile = folder.getFilesByName(&quot;Slide&quot; + i + &quot;.JPG&quot;).next();
    //imgFile.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.EDIT);
    Logger.log(&#39;filename: &#39; +imgFile);
    img = SpreadsheetApp.newCellImage().setSourceUrl(&#39;https://drive.google.com/uc?export=view&amp;id=&#39; + imgFile.getId()).build();
    Logger.log(&#39;file: &#39; +img);
    sheet.getRange(i+4,2).setValue(img);
  }
}

The error message I receive in the Execution log is "Exception: Error retrieving image from URL or bad URL: <URL>" on the sheet.getRange(i+4,2).setValue(img); line.

I am able to view the image by copying that URL from the error in Chrome's Incognito Mode (no google account signed in), so I think the file is publicly-accessible. I am also able to manually insert an image into a cell using that URL using =IMAGE(<URL>). De-commenting imgFile.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.EDIT); to force it to be public-accessible results in the same error.

I also think that the file size is not an issue as it smaller than the size limit stated in this post.

I also do not want to use insertImage() as I want the images to be inserted into the cells.
I have also tried the solutions provided in here, here and here.

Lmk what I can try to fix this issue! Also, if you also have a solution on how to force the FileIteration to take files in alphabetical/date-created order that would be awesome.

Thanks in advance!

答案1

得分: 0

根据您的评论,我相信您的目标如下。

  • 您希望按照Slide1.JPG,Slide2.JPG,Slide3.JPG,Slide4.JPG,Slide5.JPG的顺序,通过Google Apps Script按文件名检索图像文件,并将它们放入单元格“B5:B”。
  • 文件名的格式是固定的,类似于Slide1.JPG,Slide2.JPG,Slide3.JPG,Slide4.JPG,Slide5.JPG

修改点:

  • 在当前阶段,可以使用setValues将图像放入多个单元格。
  • 在您的脚本中,使用了2个循环。我认为可以使用单个循环。
  • 根据您的错误消息“Exception: Error retrieving image from URL or bad URL:”,在这种情况下,作为一种解决方法,我建议将图像作为数据URL放置。
  • 关于文件的排序,怎么样

当这些点在您的脚本中得到反映时,它会变成如下所示。

修改后的脚本:

function insertImgsFromDriveFolder() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getActiveSheet();
  var folderID = sheet.getRange(1, 4).getValue();
  var folder = DriveApp.getFolderById(folderID);
  var files = folder.searchFiles("title contains 'Slide' and mimeType contains 'image' and trashed=false");
  var ar = [];
  while (files.hasNext()) {
    var file = files.next();
    var filename = file.getName();
    var mimeType = file.getMimeType();
    if ((/Slide\d*\.JPG/i).test(filename)) {
      var base64 = Utilities.base64Encode(file.getBlob().getBytes());
      var img = SpreadsheetApp.newCellImage().setSourceUrl(`data:${mimeType};base64,${base64}`).build();
      ar.push({ filename, createdDate: file.getDateCreated(), img });
    } else {
      console.log(filename); // 如果文件不是您期望的文件,您可以在日志中看到它们。
    }
  }
  if (ar.length == 0) return;
  ar.sort((a, b) => Number(a.filename.match(/Slide(\d*)\.JPG/i)[1]) < Number(b.filename.match(/Slide(\d*)\.JPG/i)[1]) ? -1 : 1);
  sheet.getRange(5, 2, ar.length).setValues(ar.map(({ img }) => [img]));
}
  • 运行此脚本时,将检索图像并将其转换为数据URL。然后,数据URL将作为图像放入活动工作表的单元格“B5:B”中。
  • 为了检索文件,我使用了title contains 'Slide' and mimeType contains 'image' and trashed=false的搜索查询。

注意:

  • 在此脚本中,假设您的文件夹ID和图像文件是有效的。请注意这一点。

参考资料:

英文:

From your comments, I believe your goal is as follows.

  • You want to retrieve the image files by the filename like Slide1.JPG, Slide2.JPG, Slide3.JPG, Slide4.JPG, Slide5.JPG,,, in order, and want to put them to the cells "B5:B" using Google Apps Script.
  • The format of filename is constant like Slide1.JPG, Slide2.JPG, Slide3.JPG, Slide4.JPG, Slide5.JPG,,,.

Modification points:

  • In the current stage the images can be put into multiple cells using setValues.
  • In your script, 2 loops are used. I thought that a single loop can be used.
  • From your error message Exception: Error retrieving image from URL or bad URL:, in this case, as a workaround, I would like to propose putting the images as the data URL.
  • About the sort of files, how about

When these points are reflected in your script, it becomes as follows.

Modified script:

function insertImgsFromDriveFolder() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getActiveSheet();
  var folderID = sheet.getRange(1, 4).getValue();
  var folder = DriveApp.getFolderById(folderID);
  var files = folder.searchFiles(&quot;title contains &#39;Slide&#39; and mimeType contains &#39;image&#39; and trashed=false&quot;);
  var ar = [];
  while (files.hasNext()) {
    var file = files.next();
    var filename = file.getName();
    var mimeType = file.getMimeType();
    if ((/Slide\d*\.JPG/i).test(filename)) {
      var base64 = Utilities.base64Encode(file.getBlob().getBytes());
      var img = SpreadsheetApp.newCellImage().setSourceUrl(`data:${mimeType};base64,${base64}`).build();
      ar.push({ filename, createdDate: file.getDateCreated(), img });
    } else {
      console.log(filename); // If the file is not your expected file, you can see them in the log.
    }
  }
  if (ar.length == 0) return;
  ar.sort((a, b) =&gt; Number(a.filename.match(/Slide(\d*)\.JPG/i)[1]) &lt; Number(b.filename.match(/Slide(\d*)\.JPG/i)[1]) ? -1 : 1);
  sheet.getRange(5, 2, ar.length).setValues(ar.map(({ img }) =&gt; [img]));
}
  • When this script is run, the images are retrieved and converted to the data URL. And, the data URLs are put into the cells "B5:B" of the active sheet as the images.
  • In order to retrieve the files, I used the search query of title contains &#39;Slide&#39; and mimeType contains &#39;image&#39; and trashed=false.

Note:

  • In this script, it supposes that your folder ID and the image files are valid. Please be careful about this.

References:

huangapple
  • 本文由 发表于 2023年5月22日 14:00:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76303379.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定