使用 JSON 将数据传递到 Office 脚本和从 Office 脚本传递数据
JSON (JavaScript 对象表示法) 是一种用于存储和传输数据的格式。 每个 JSON 对象都是可在创建时定义的名称/值对的集合。 JSON 在 Office 脚本中很有用,因为它可以在 Excel 中处理范围、表和其他数据模式的任意复杂性。 JSON 允许分析来自 Web 服务的 传入数据,并通过 Power Automate 流传递复杂对象。
本文重点介绍如何将 JSON 与 Office 脚本配合使用。 建议首先从 W3 学校的 JSON 简介 等文章中详细了解格式。
将 JSON 数据分析为区域或表
JSON 对象的数组提供了一种在应用程序和 Web 服务之间传递表数据行的一致方式。 在这些情况下,每个 JSON 对象表示一行,而属性表示列。 Office 脚本可以循环访问 JSON 数组,并将其重新组合为 2D 数组。 然后,此数组设置为区域的值并存储在工作簿中。 还可以将属性名称添加为标头以创建表。
以下脚本显示了要转换为表的 JSON 数据。 请注意,数据不是从外部源获取的。 本文稍后将对此进行介绍。
/**
* Sample JSON data. This would be replaced by external calls or
* parameters getting data from Power Automate in a production script.
*/
const jsonData = [
{ "Action": "Edit", /* Action property with value of "Edit". */
"N": 3370, /* N property with value of 3370. */
"Percent": 17.85 /* Percent property with value of 17.85. */
},
// The rest of the object entries follow the same pattern.
{ "Action": "Paste", "N": 1171, "Percent": 6.2 },
{ "Action": "Clear", "N": 599, "Percent": 3.17 },
{ "Action": "Insert", "N": 352, "Percent": 1.86 },
{ "Action": "Delete", "N": 350, "Percent": 1.85 },
{ "Action": "Refresh", "N": 314, "Percent": 1.66 },
{ "Action": "Fill", "N": 286, "Percent": 1.51 },
];
/**
* This script converts JSON data to an Excel table.
*/
function main(workbook: ExcelScript.Workbook) {
// Create a new worksheet to store the imported data.
const newSheet = workbook.addWorksheet();
newSheet.activate();
// Determine the data's shape by getting the properties in one object.
// This assumes all the JSON objects have the same properties.
const columnNames = getPropertiesFromJson(jsonData[0]);
// Create the table headers using the property names.
const headerRange = newSheet.getRangeByIndexes(0, 0, 1, columnNames.length);
headerRange.setValues([columnNames]);
// Create a new table with the headers.
const newTable = newSheet.addTable(headerRange, true);
// Add each object in the array of JSON objects to the table.
const tableValues = jsonData.map(row => convertJsonToRow(row));
newTable.addRows(-1, tableValues);
}
/**
* This function turns a JSON object into an array to be used as a table row.
*/
function convertJsonToRow(obj: object) {
const array: (string | number)[] = [];
// Loop over each property and get the value. Their order will be the same as the column headers.
for (let value in obj) {
array.push(obj[value]);
}
return array;
}
/**
* This function gets the property names from a single JSON object.
*/
function getPropertiesFromJson(obj: object) {
const propertyArray: string[] = [];
// Loop over each property in the object and store the property name in an array.
for (let property in obj) {
propertyArray.push(property);
}
return propertyArray;
}
提示
如果知道 JSON 的结构,则可以创建自己的接口,以便更轻松地获取特定属性。 可以将 JSON 到数组的转换步骤替换为类型安全的引用。 以下代码片段演示了这些步骤 (现在注释掉) 替换为使用新 ActionRow
接口的调用。 请注意,这会使 convertJsonToRow
函数不再需要。
// const tableValues = jsonData.map(row => convertJsonToRow(row));
// newTable.addRows(-1, tableValues);
// }
const actionRows: ActionRow[] = jsonData as ActionRow[];
// Add each object in the array of JSON objects to the table.
const tableValues = actionRows.map(row => [row.Action, row.N, row.Percent]);
newTable.addRows(-1, tableValues);
}
interface ActionRow {
Action: string;
N: number;
Percent: number;
}
从外部源获取 JSON 数据
可通过两种方法通过 Office 脚本将 JSON 数据导入工作簿。
修改示例以使用 Power Automate
Power Automate 中的 JSON 数据可以作为泛型对象数组传递。 向脚本添加属性 object[]
以接受该数据。
// For Power Automate, replace the main signature in the previous sample with this one
// and remove the sample data.
function main(workbook: ExcelScript.Workbook, jsonData: object[]) {
然后,你将在 Power Automate 连接器中看到一个选项,可添加到jsonData
“运行脚本”操作。
修改示例以使用 fetch
调用
Web 服务可以使用 JSON 数据回复 fetch
调用。 这会为脚本提供在 Excel 中保存所需的数据。 阅读 Office 脚本中的外部 API 调用支持,详细了解fetch
和外部调用。
// For external services, replace the main signature in the previous sample with this one,
// add the fetch call, and remove the sample data.
async function main(workbook: ExcelScript.Workbook) {
// Replace WEB_SERVICE_URL with the URL of whatever service you need to call.
const response = await fetch('WEB_SERVICE_URL');
const jsonData: object[] = await response.json();
从范围创建 JSON
工作表的行和列通常表示其数据值之间的关系。 表的一行在概念上映射到编程对象,其中每一列都是该对象的属性。 请考虑以下数据表。 每行表示电子表格中记录的事务。
ID | 日期 | Amount | 供应商 |
---|---|---|---|
1 | 6/1/2022 | $43.54 | 最适合你的有机公司 |
2 | 6/3/2022 | $67.23 | 自由面包店和咖啡馆 |
3 | 6/3/2022 | $37.12 | 最适合你的有机公司 |
4 | 6/6/2022 | $86.95 | Coho Vineyard |
5 | 6/7/2022 | $13.64 | 自由面包店和咖啡馆 |
每个事务 (每一行) 都有一组与之关联的属性:“ID”、“Date”、“Amount”和“Vendor”。 这可以在 Office 脚本中建模为 对象。
// An interface that wraps transaction details as JSON.
interface Transaction {
"ID": string;
"Date": number;
"Amount": number;
"Vendor": string;
}
示例表中的行对应于 接口中的属性,因此脚本可以轻松地将每一行转换为 Transaction
对象。 输出 Power Automate 的数据时,这很有用。 以下脚本循环访问表中的每一行,并将其添加到 Transaction[]
。
function main(workbook: ExcelScript.Workbook) {
// Get the table on the current worksheet.
const table = workbook.getActiveWorksheet().getTables()[0];
// Create an array of Transactions and add each row to it.
let transactions: Transaction[] = [];
const dataValues = table.getRangeBetweenHeaderAndTotal().getValues();
for (let i = 0; i < dataValues.length; i++) {
let row = dataValues[i];
let currentTransaction: Transaction = {
ID: row[table.getColumnByName("ID").getIndex()] as string,
Date: row[table.getColumnByName("Date").getIndex()] as number,
Amount: row[table.getColumnByName("Amount").getIndex()] as number,
Vendor: row[table.getColumnByName("Vendor").getIndex()] as string
};
transactions.push(currentTransaction);
}
// Do something with the Transaction objects, such as return them to a Power Automate flow.
console.log(transactions);
}
// An interface that wraps transaction details as JSON.
interface Transaction {
"ID": string;
"Date": number;
"Amount": number;
"Vendor": string;
}
使用 导出 JSON fetch
与使用 导入数据 fetch
非常相似,可以使用类似的命令从工作簿发送数据。 命令 POST
采用任何字符串化的 JSON 数据,并将其发送到指定的终结点。
若要查看此操作的操作,请将上一示例中的 行 console.log(transactions);
替换为以下代码。 这会向测试服务器发出 POST
命令,然后读回数据。
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
body: JSON.stringify(transactions),
headers: {
'Content-type': 'application/json; charset=UTF-8',
},
});
const jsonData: object[] = await response.json();
console.log(jsonData);
使用泛型对象
前面的示例假定表标头值是一致的。 如果表具有变量列,则需要创建一个通用 JSON 对象。 以下脚本显示了一个脚本,该脚本将任何表记录为 JSON。
function main(workbook: ExcelScript.Workbook) {
// Get the table on the current worksheet.
const table = workbook.getActiveWorksheet().getTables()[0];
// Use the table header names as JSON properties.
const tableHeaders = table.getHeaderRowRange().getValues()[0] as string[];
// Get each data row in the table.
const dataValues = table.getRangeBetweenHeaderAndTotal().getValues();
let jsonArray: object[] = [];
// For each row, create a JSON object and assign each property to it based on the table headers.
for (let i = 0; i < dataValues.length; i++) {
// Create a blank generic JSON object.
let jsonObject: { [key: string]: string } = {};
for (let j = 0; j < dataValues[i].length; j++) {
jsonObject[tableHeaders[j]] = dataValues[i][j] as string;
}
jsonArray.push(jsonObject);
}
// Do something with the objects, such as return them to a Power Automate flow.
console.log(jsonArray);
}