Google Apps Script导入嵌套JSON数据时列数不匹配异常排查求助
Fix "Columns Mismatch" Error When Importing JSON with Multi-Child Nodes to Google Sheets
咱们先捋清楚你遇到的问题根源:
你的脚本在处理JSON时,表头只固定取了第三个父节点的子节点键,而且直接提取子节点的values却没有和表头的键对应,导致当某些子节点的键数量(比如Child有1和2两个键)和表头的列数不一致时,就会触发列数不匹配的异常。手动加列没用是因为脚本里的范围是根据固定的表头列数计算的,和实际数据的列数对不上。
下面是修复后的完整脚本,我做了这些关键调整:
- 自动收集所有子节点的键,生成包含所有字段的完整表头(解决表头不全的问题)
- 按表头的键顺序提取每个父节点对应的值,缺失的字段填充空值(保证每行的列数和表头一致)
- 修正了range设置的逻辑,确保数据范围和实际数据的行列数匹配
function chunkArray(myArray, chunk_size){ var index = 0; var arrayLength = myArray.length; var tempArray = []; for (index = 0; index < arrayLength; index += chunk_size) { myChunk = myArray.slice(index, index+chunk_size); tempArray.push(myChunk); } return tempArray; } function flatten(arrayOfArrays){ return [].concat.apply([], arrayOfArrays); } function insertJSON(){ var aOneName = "id"; var sheet = SpreadsheetApp.getActiveSheet(); var fileURL = "link to .json" var res = UrlFetchApp.fetch(fileURL,{'muteHttpExceptions': true}); var content = res.getContentText(); var json = JSON.parse(content); // 获取所有父节点的键 var parentKeys = Object.keys(json); var rows = [parentKeys]; var toRows = parentKeys.length + 1; // 把父节点键写入A列 var rowsflate = flatten(rows); var rowstocols = chunkArray(rowsflate, 1); sheet.getRange("A2:A" + toRows).setValues(rowstocols); sheet.getRange(1, 1).setValue(aOneName); // 关键修复1:收集所有子节点的键,生成完整的表头(去重并排序) let allHeaderKeys = new Set(); parentKeys.forEach(parentKey => { const childNodes = json[parentKey]; Object.keys(childNodes).forEach(childKey => { Object.keys(childNodes[childKey]).forEach(key => allHeaderKeys.add(key)); }); }); const headerKeys = Array.from(allHeaderKeys).sort(); // 排序保证顺序稳定 const getHeaders = [headerKeys]; // 写入表头到第1行,从D列开始 sheet.getRange(1,4,getHeaders.length,getHeaders[0].length).setValues(getHeaders); // 关键修复2:按表头顺序提取每个父节点的对应值,缺失字段填空 var content = []; parentKeys.forEach(parentKey => { const parentNode = json[parentKey]; const rowValues = headerKeys.map(key => { // 遍历每个表头键,找到对应的子节点值,没有则返回空字符串 for (const childKey in parentNode) { if (parentNode[childKey].hasOwnProperty(key)) { return parentNode[childKey][key]; } } return ""; }); content.push(rowValues); }); // 写入数据:从第2行第1列开始,行数是父节点数量,列数是表头列数 sheet.getRange(2,1,content.length, headerKeys.length).setValues(content); }
为什么这样能解决问题?
- 原来的表头只取了
json[rows[0][2]](第三个父节点的子节点),现在改成收集所有出现过的子节点键,不管哪个父节点有多少字段,表头都会包含全部字段。 - 原来直接用
Object.values提取值,现在按表头的键顺序逐个匹配,确保每行的列数和表头完全一致,不会出现有的行多列、有的行少列的情况。 - 最后写入数据的range是根据实际数据的行列数动态计算的,彻底避免了“数据列数≠范围列数”的异常。
内容的提问来源于stack exchange,提问作者hugo1199




