使用Apps Script(Drive API V3)转换.docx到Google Docs报错求助
问题:将Google Drive中的DOCX文件转为Google Docs格式遇到API适配问题
问题背景
参考旧版教程操作时,首先遇到Drive API V3不支持Drive.Files.insert方法的报错:
TypeError: Drive.Files.insert is not a function
改用V3的Drive.Files.create方法后,又出现文档访问权限报错:
Exception: The document is inaccessible. Please try again later
最初使用的核心代码片段:
var docx = DriveApp.getFilesByName(nomeArquivo).next(); var newDoc = Drive.newFile(); var blob =docx.getBlob(); var file=Drive.Files.insert(newDoc,blob,{convert:true}); DocumentApp.openById(file.id).setName(docx.getName());
完整初始代码:
function AtualizarLinkDocs() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var pagListaArquivos = ss.getSheetByName("Lista de Arquivos"); var rangeLinks = pagListaArquivos.getRange('K1:M').getValues(); for (var i = 0; i<rangeLinks.length; i++){ if (rangeLinks[i][0]!="" && rangeLinks[i][2]==""){ var caminhoNomeArquivo = rangeLinks[i][0]; var nomeArquivo = caminhoNomeArquivo.toString().replace("Lista de Arquivos_Files_/","")); var idWord = DriveApp.getFilesByName(nomeArquivo).next().getId(); Logger.log(idWord); var docx = DriveApp.getFilesByName(nomeArquivo).next(); var newDoc = Drive.newFile(); var blob = docx.getBlob(); var file = Drive.Files.create(newDoc,blob,{convert:true}); DocumentApp.openById(file.id).setName(docx.getName()); Logger.log("novo arquivo: "+file.id); } } }
需求:将AppSheet上传到Google Drive的Word文档转为Google Docs副本,并在表格中保存其共享链接,目前卡在格式转换环节。
后续尝试与新问题
发现V3中{convert:true}参数无效,修改代码后仍生成Word文档;尝试用.getAs('application/vnd.google-apps.document')转换格式时,报错:
Exception: Converting from application/vnd.openxmlformats-officedocument.wordprocessingml.document to application/vnd.google-apps.document is not supported.
更新后的代码:
function AtualizarLinkDocs() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var pagListaArquivos = ss.getSheetByName("Lista de Arquivos"); var rangeLinks = pagListaArquivos.getRange('K1:M').getValues(); for (var i = 0; i<rangeLinks.length; i++){ if (rangeLinks[i][0]!="" && rangeLinks[i][2]==""){ var caminhoNomeArquivo = rangeLinks[i][0]; var nomeArquivo = caminhoNomeArquivo.toString().replace("Lista de Arquivos_Files_/","")); var idWord = DriveApp.getFilesByName(nomeArquivo).next().getId(); Logger.log("Id do Word: "+idWord); var docx = DriveApp.getFileById(idWord); var folder = docx.getParents().next(); var blob = docx.getBlob(); Logger.log(blob); var new_file = Drive.newFile(); var google_doc = Drive.Files.create(new_file.id,blob); Logger.log(google_doc); DriveApp.getFileById(google_doc.id) .setName(docx.getName().replace(/\.docx$/,'')) .moveTo(folder); Logger.log("será que foi?? Docs: "+google_doc.id) } } }
解决建议
1. 正确使用Drive API V3的格式转换逻辑
V3中无需convert:true,直接在文件元数据中指定目标MIME类型即可触发自动转换,核心代码修改如下:
var docx = DriveApp.getFileById(idWord); var folder = docx.getParents().next(); // 构造转换后的Google Docs元数据 var fileMetadata = { name: docx.getName().replace(/\.docx$/i, ''), // 自动去除docx后缀 parents: [folder.getId()], // 直接指定父文件夹,避免后续移动 mimeType: 'application/vnd.google-apps.document' // 明确指定转换为Google Docs格式 }; var blob = docx.getBlob(); var googleDoc = Drive.Files.create(fileMetadata, blob);
2. 修复代码语法与冗余问题
- 原代码中字符串替换多了一个右括号,修正为:
var nomeArquivo = caminhoNomeArquivo.toString().replace("Lista de Arquivos_Files_/", ""); - 避免重复调用
DriveApp.getFilesByName(nomeArquivo).next(),获取一次文件对象后复用:var docx = DriveApp.getFilesByName(nomeArquivo).next(); var idWord = docx.getId();
3. 解决文档访问权限问题
- 确保在Google Apps Script编辑器中已启用Drive API:通过「服务」菜单添加Drive API(版本选V3)
- 确认脚本运行账号有权限访问AppSheet上传的DOCX文件(若文件为私有,需先赋予账号访问权限)
4. 添加共享链接写入逻辑
转换完成后设置文件权限并写入表格:
// 设置为任何人可查看(可根据需求调整权限) DriveApp.getFileById(googleDoc.id).setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW); var shareLink = "https://docs.google.com/document/d/" + googleDoc.id + "/view"; // 写入表格M列(对应rangeLinks的索引2,行号i+1因为从第1行开始) pagListaArquivos.getRange(i+1, 13).setValue(shareLink);
完整修正后的代码
function AtualizarLinkDocs() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var pagListaArquivos = ss.getSheetByName("Lista de Arquivos"); var rangeLinks = pagListaArquivos.getRange('K1:M').getValues(); var driveService = Drive; // 确保已启用Drive API V3 for (var i = 0; i < rangeLinks.length; i++) { var row = i + 1; var caminhoNomeArquivo = rangeLinks[i][0]; var hasLink = rangeLinks[i][2]; if (caminhoNomeArquivo !== "" && hasLink === "") { // 修复字符串替换语法错误 var nomeArquivo = caminhoNomeArquivo.toString().replace("Lista de Arquivos_Files_/", ""); try { // 仅获取一次文件对象,避免同名文件冲突 var docx = DriveApp.getFilesByName(nomeArquivo).next(); var idWord = docx.getId(); Logger.log("Id do Word: " + idWord); var folder = docx.getParents().next(); // 构造Google Docs元数据 var fileMetadata = { name: nomeArquivo.replace(/\.docx$/i, ''), parents: [folder.getId()], mimeType: 'application/vnd.google-apps.document' }; var blob = docx.getBlob(); // 创建并转换文件 var googleDoc = driveService.Files.create(fileMetadata, blob); Logger.log("Novo arquivo Docs: " + googleDoc.id); // 设置共享权限并写入链接 var docFile = DriveApp.getFileById(googleDoc.id); docFile.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW); var shareLink = "https://docs.google.com/document/d/" + googleDoc.id + "/view"; pagListaArquivos.getRange(row, 13).setValue(shareLink); Logger.log("Link salvo na linha " + row); } catch (e) { Logger.log("Erro na linha " + row + ": " + e.toString()); // 标记错误到表格 pagListaArquivos.getRange(row, 13).setValue("Erro: " + e.message); } } } }
注意事项
- 启用Drive API:在脚本编辑器中依次点击「扩展」>「Apps Script API」>「启用」,再通过「服务」菜单添加Drive API(版本选V3)
- 同名文件处理:若Drive中存在多个同名DOCX,
getFilesByName().next()仅会获取第一个,建议改用文件ID定位更准确 - 异常处理:添加try-catch块可避免脚本中途崩溃,同时记录错误便于排查
内容的提问来源于stack exchange,提问作者user22813224
相关产品推荐
相关产品推荐

