使用Google Apps Script从Google Drive导入CSV联系人时遇TypeError: Cannot read property 'getRange' of null错误的解决方法
修复错误并实现CSV导入Google联系人的方案
首先,先解决你遇到的TypeError: Cannot read property 'getRange' of null错误:这个错误是因为SpreadsheetApp.getActiveSheet()在没有激活任何Google表格文件的情况下运行时会返回null——比如你直接在脚本编辑器里运行代码,但没有打开对应的表格。不过更重要的是,你的代码当前是把CSV导入到表格,但你的实际需求是导入到Google联系人,所以我们需要完全调整代码逻辑,不用操作表格,直接使用Google的People Service来创建联系人。
第一步:启用People API
在脚本编辑器中,你需要先启用People API才能操作联系人:
- 点击左侧边栏的「服务」图标(看起来像闪电)
- 在弹出的服务列表中找到「People API」,点击「添加」完成启用
第二步:完整的联系人导入代码
下面的代码会读取你Drive中的CSV文件,解析后逐个创建Google联系人,同时处理空行和异常情况:
function importCSVToContacts() { // 获取Drive中的CSV文件(确保文件名唯一,否则需要调整获取方式) var file = DriveApp.getFilesByName('file.csv').next(); var csvContent = file.getBlob().getDataAsString(); var csvData = Utilities.parseCsv(csvContent); // 跳过表头行,从第二行开始处理实际联系人数据 for (var i = 1; i < csvData.length; i++) { var row = csvData[i]; // 提取CSV中的字段(根据你的CSV列顺序调整索引) var fullName = row[0]; var givenName = row[1]; var familyName = row[3]; var emailValue = row[30]; // 对应"E-mail 1 - Value"列 var emailType = row[29].replace('* ', ''); // 对应"E-mail 1 - Type"列,去掉前缀* var phoneValue = row[32]; // 对应"Phone 1 - Value"列 var phoneType = row[31] || 'mobile'; // 对应"Phone 1 - Type"列,默认mobile var groupName = row[28]?.replace('* ', ''); // 对应"Group Membership"列,去掉前缀* // 跳过空行(避免处理无效数据) if (!fullName && !emailValue && !phoneValue) { Logger.log('跳过空行: 第' + (i+1) + '行'); continue; } // 构建联系人数据结构 var contactPayload = { names: [{ givenName: givenName, familyName: familyName, displayName: fullName }] }; // 添加邮箱信息(如果有) if (emailValue) { contactPayload.emailAddresses = [{ value: emailValue, type: emailType.toLowerCase() }]; } // 添加电话信息(如果有) if (phoneValue) { contactPayload.phoneNumbers = [{ value: phoneValue.replace(/\s/g, ''), // 去掉电话号码中的空格 type: phoneType.toLowerCase() }]; } // 添加到指定联系人组(如果有) if (groupName) { // 获取当前用户的联系人组列表 var userMemberships = People.People.getBatchGet({ resourceNames: ['people/me'], personFields: 'memberships' }).responses[0].person.memberships; // 匹配目标组的资源ID var targetGroup = userMemberships.find(membership => { return membership.contactGroupMembership?.contactGroupName === groupName; }); if (targetGroup) { contactPayload.memberships = [{ contactGroupMembership: { contactGroupResourceName: targetGroup.contactGroupMembership.contactGroupResourceName } }]; } else { Logger.log('未找到联系人组: ' + groupName); } } // 创建联系人 try { People.People.createContact(contactPayload); Logger.log('成功创建联系人: ' + fullName); } catch (error) { Logger.log('创建联系人失败 [' + fullName + ']: ' + error.message); } } Logger.log('联系人导入任务完成!'); }
第三步:代码说明和注意事项
- 字段索引调整:代码中的索引(比如
row[30])是根据你提供的CSV表头顺序设置的,如果你的CSV列顺序有变化,需要对应调整索引值。 - 文件名唯一性:
DriveApp.getFilesByName('file.csv').next()会获取第一个匹配文件名的文件,如果Drive中有多个同名CSV,建议改用DriveApp.getFileById('文件ID')来精准获取。 - 权限授权:第一次运行代码时,会提示你授权访问Google Drive和People API的权限,按照页面提示完成授权即可。
- 异常处理:代码中加入了
try-catch块,即使某个联系人创建失败,脚本也会继续处理下一个联系人。
关于原表格导入错误的补充(如果需要)
如果你只是想把CSV导入到Google表格,而不是联系人,可以修改原代码,指定要操作的表格:
function importCSVToSheet() { var file = DriveApp.getFilesByName('file.csv').next(); var csvData = Utilities.parseCsv(file.getBlob().getDataAsString()); // 替换成你的表格ID var spreadsheet = SpreadsheetApp.openById('你的表格ID'); var sheet = spreadsheet.getActiveSheet(); sheet.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData); }
内容的提问来源于stack exchange,提问作者Thomas Kast
相关产品推荐
相关产品推荐

