通过 importJSON 导入额外的 API 数据 + 在公式中使用来自 json 的数据

Importing extra API data via importJSON + usage of data from json in formulas

在 Tanaike 的支持下,我做了一个 google sheet。它功能齐全,但我想更改输入中的某些内容,并且还有一个列导致另一种格式或公式。这就是我被困的地方。首先这是我的代码:



function updateStampInSheet(e) {
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
    var stamp = new Date();
    sheet.getRange(1,1).setValue(stamp);
}
function SAMPLE() {
  const url1 = "https://prices.runescape.wiki/api/v1/osrs/mapping";
  const url2 = "https://prices.runescape.wiki/api/v1/osrs/latest";
  const [res1, res2] = [url1, url2].map(url => JSON.parse(UrlFetchApp.fetch(url).getContentText()));
  const head = ['id', 'name', 'examine', 'members', 'lowalch', 'highalch', 'limit', 'high', 'low', 'lowTime', 'highTime','icon'];
  const obj1 = res1.reduce((o, e) => (o[e.id] = e, o), {});
  const obj2 = Object.entries(res2.data).reduce((o, [k, v]) => (o[k] = v, o), {});
  const keys = Object.keys(obj1).map(e => Number(e)).sort((a, b) => a - b);
  const timeZone = Session.getScriptTimeZone();
  const values = [head, ...keys.map(k => {
    const o = Object.assign(obj1[k], obj2[k]);
    return head.map(h => o[h] ? (['lowTime', 'highTime'].includes(h) ? Utilities.formatDate(new Date(o[h] * 1000), timeZone, "HH:mm:ss") : o[h]) : "");
  })];
  return values;
}
  1. json 每秒更新一次,日期戳打印在 sheet 中。更新时还有一个名为“lowTime”和“highTime”的列。是否可以使用以下数据添加 2 个额外的列,并将现在的数据减去“lowTime”或“highTime”?在 sheet 中是可能的,但我无法弄清楚如何在代码中做到这一点。见下图:https://postimg.cc/GTRJ3FP5

  2. id是已知的,根据id我想展示一张图片然后可以在下面找到link:例如id=2:https://static.runelite.net/cache/item/icon/2.png .是否有可能将公式中有价值的 id 添加到额外的列中,例如 =IMAGE("https://static.runelite.net/cache/item/icon/2.png") ? 我已经在下图说明了:https://postimg.cc/nCbczdDz

  3. 我试图在数据库中添加第三个 json 但它总是给出一个错误(一个额外的列)。这是以下内容:https://prices.runescape.wiki/api/v1/osrs/volumes。它给出了对应于 id 的卷。

  4. 我的最后一个问题,如何在公式(额外列)中使用来自 json 数据库的数据?比如看link里的图片,我试了一些函数,结果不行https://postimg.cc/PCPNBLss.

希望大家已经清楚了,如果不清楚请评论(这是google电子表格,我添加了列:https://docs.google.com/spreadsheets/d/1fFrVLCWyCwDcqSU5-Bpt_C4sHXzLHFA30gk84TaUwOE/edit#gid=0)。

为了实现你的4个请求,下面的示例脚本怎么样?不幸的是,为了实现你的4个请求,自定义函数无法使用。因此,在此示例脚本中,请 运行 使用脚本编辑器编写脚本。

示例脚本:

请将以下脚本复制粘贴到Spreadsheet的脚本编辑器中。并且,请设置 sheet 名称。并且,请 运行 sample2 使用脚本编辑器。这样,脚本就是运行.

function sample2() {
  const sheetName = "Sheet1"; // Please set the sheet name.

  // Set the value to the cell "A1".
  const stamp = new Date();
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  sheet.clearContents();
  sheet.getRange("A1").setValue(stamp);
  const date = stamp.getTime();

  // Retrieve values from URLs.
  const url1 = "https://prices.runescape.wiki/api/v1/osrs/mapping";
  const url2 = "https://prices.runescape.wiki/api/v1/osrs/latest";
  const url3 = "https://prices.runescape.wiki/api/v1/osrs/volumes";
  const [res1, res2, res3] = [url1, url2, url3].map(url => JSON.parse(UrlFetchApp.fetch(url).getContentText()));

  // Create an array for putting to Spreadsheet.
  const head = ['id', 'name', 'examine', 'members', 'lowalch', 'highalch', 'limit', 'high', 'low', 'lowTime', 'highTime'];
  const exHead = ["Icon", "Low Time (mins)", "High Time (mins)", "margin", "profit", "tax", "roi", "volume"];
  const obj1 = res1.reduce((o, e) => (o[e.id] = e, o), {});
  const obj2 = Object.entries(res2.data).reduce((o, [k, v]) => (o[k] = v, o), {});
  const obj3 = res3.data;
  const keys = Object.keys(obj1).map(e => Number(e)).sort((a, b) => a - b);
  const values = [[...head, ...exHead], ...keys.map(k => {
    const o = Object.assign(obj1[k], obj2[k]);
    const temp = head.map(h => o[h] ? (['lowTime', 'highTime'].includes(h) ? new Date(o[h] * 1000) : o[h]) : "");
    const colO = temp[7] - temp[8];
    const colQ = temp[7] * 0.01;
    const colP = colO - colQ;
    const exTemp = [`=IMAGE("https://static.runelite.net/cache/item/icon/${temp[0]}.png")`, temp[9] ? Math.floor((date - temp[9].getTime()) / 60000) : null, temp[10] ? Math.floor((date - temp[10].getTime()) / 60000) : null, colO, colP, colQ, colP && temp[8].toString() ? colP / temp[8] : 0, obj3[k] || 0];
    return [...temp, ...exTemp];
  })];
  sheet.getRange(2, 1, values.length, values[0].length).setValues(values);

  // Set number format. These formats are retrieved from your sample Spreadsheet.
  sheet.getRange(3, 10, values.length, 2).setNumberFormat("d-m-yyyy");
  const formats = ['#,##0 "minutes ago"', '#,##0 "minutes ago"', "0", "0", "0", "0.00%"];
  const numberFormats = Array(values.length).fill(formats);
  sheet.getRange(3, 13, values.length, formats.length).setNumberFormats(numberFormats);
}

测试:

当这个脚本用脚本编辑器运行时,得到如下结果。通过从您提供的示例 Spreadsheet.

中检索来使用数字格式

注:

  • 首先,我认为可以使用 CellImageBuilder 将图像直接放入单元格。但是,在您的情况下,数据很大。在这种情况下,我注意到当使用 IMAGE 公式时,处理成本可以比 CellImageBuilder 降低。所以在这个示例中,我使用了 IMAGE 公式。

参考: