那么,如何在 App Script 中读取 Google Drive 文件的内容而不对行进行重新排序?
So how do I read the contents of a Google Drive file in App Script without the lines being reordered?
那么如何在 App Script 中读取 Google Drive 文件的内容而不重新排序行?
这是我的情况:
- 我有一些文件的文本内容的文件扩展名为 。lua
- 我已将它们复制到我的 Google 驱动器
- 出于某种原因,它认为它们是图像文件!这可能是我的主要问题的原因
我正在尝试在附加到 Google 电子表格
的脚本中阅读它们
function test_bug_readFile_linesInWrongOrder() {
var fileId1 = "12-YLK6Lv5UYNZIgkr-u-DBviwLIOr1F2" // orig file .lua
var fileId2 = "1fyvdHrc45Q_-G02XJ1ismCROKqcxyoPL" // test file shortened and .txt
var fileId3 = "1uw7gG869_yIhpYh2vY2iKtUU5njBRrwA" // test file same as orig but .txt
var file = DriveApp.getFileById( fileId1 )
var fileBlob = file.getBlob()
// var fileBlob = file.getBlob().setContentType( "text/plain" )
var raw = fileBlob.getDataAsString()
Logger.log( raw.length )
Logger.log( raw )
}
- 当我 运行 这时,我得到了文件的内容,但是行的顺序是错误的!!您可以通过更改传递给 getFileById(...) 的参数来查看各种行为
- fileId1 是原始文件并出现如下所述的错误
- fileId2 是一个小得多的文件,是一个 .txt,但它没有异常,我得到的行顺序正确
- fileId3 是原始文件的副本,但文件扩展名已更改为 .txt(为清楚起见,第一行)。这也没有显示错误,但它仍然显示为图像文件
似乎当错误发生时,具有相同 parent 行和相同缩进级别的行更改顺序,可能基于某些哈希值。我试着在这里复制文本,但无法弄清楚他的标记,而且问题已经很长了。 :)
我曾尝试在读取 blob 之前设置 MIME 类型,但这似乎没有任何作用。
以上三个数据文件我已经设置为公开可读,有问题可以私信我
那么如何在没有 google App Script "helpfully" 为您重新排序的情况下读取文件/blob 的内容?
在此先感谢您的帮助
编辑:
好的,我做了一个演示项目:
https://docs.google.com/spreadsheets/d/1i_VqYANrqE5FXEQxFAx4dbheEJ89I8MwGSDrxenwHtU
您需要让它加载,然后会出现一个标题为 "BugDemo" 的菜单。一旦你有了它,只需选择其中唯一的菜单项,你就会得到一个权限对话框。我知道您可能不想授予我的代码权限,所以我将代码包含在下面的块中,这样您就可以制作自己的项目并确保没有额外的后门或任何东西。
"use strict";
function onOpen() {
SpreadsheetApp.getUi().createMenu( 'BugDemo' )
.addItem( 'Read 3 Files and show first 10,000 chars', 'test_bug_readFile_linesInWrongOrder' )
.addToUi()
}
function test_bug_readFile_linesInWrongOrder() {
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
sh.clear()
var fileIds = ["12-YLK6Lv5UYNZIgkr-u-DBviwLIOr1F2", // orig file .lua
"1fyvdHrc45Q_-G02XJ1ismCROKqcxyoPL", // test file shortened and .txt
"1uw7gG869_yIhpYh2vY2iKtUU5njBRrwA" // test file same as orig but .txt
]
var fileDescs = ["original file",
"much smaller file, also with .txt extension",
"same as first file but with extension of .txt"
]
for ( var col = 0; col < fileIds.length; col++ ) {
var fileId = fileIds[col]
var file = DriveApp.getFileById( fileId )
var fileBlob = file.getBlob()
var text = fileBlob.getDataAsString().slice( 0, 10000 )
var r = sh.getRange( 1, col + 1, 1, 1 )
r.setValue( fileId )
r.offset( 1, 0, 1, 1 ).setValue( file.getName() )
r.offset( 2, 0, 1, 1 ).setValue( fileDescs[col] )
r.offset( 4, 0, 1, 1 ).setValue( text )
}
}
一旦你运行你应该看到三列数据出现,第一列是错误的。
错误:
你
应该看到它直接从 ["$AccountWide"] 到 ["SalesData"] ,因为数据文件还有其他几行在其中,如其他 2 列中所示。
最深的缩进块,键为:( ["itemLink"], ["timestamp"], ["price"], ["wasKiosk"] , ["buyer"], ["guild"], ["seller"], ["quant"], ["id"] )都在那里,但以不同但一致的方式订单.
第一列似乎以某种方式获得了数据文件中没有的开始和结束 {}。
是否有可能 Google 在幕后使用一些 Lua 代码,然后对数据进行上下文相关的解析(理解数据结构),然后得到 re-serialized 顺序不同 ?
当我看到您共享的电子表格时,original file
似乎与其他人不同。但是当我 运行 你的脚本时,所有文件 ID 的结果都是相同的。我无法复制你的情况。
所以虽然我无法确定这是否是您问题的直接解决方案,但在本次修改中,我使用 Drive API v3 而不是 DriveApp 来检索文件内容。
修改后的脚本:
function test_bug_readFile_linesInWrongOrder() {
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
sh.clear()
var fileIds = ["12-YLK6Lv5UYNZIgkr-u-DBviwLIOr1F2", // orig file .lua
"1fyvdHrc45Q_-G02XJ1ismCROKqcxyoPL", // test file shortened and .txt
"1uw7gG869_yIhpYh2vY2iKtUU5njBRrwA" // test file same as orig but .txt
]
var fileDescs = ["original file",
"much smaller file, also with .txt extension",
"same as first file but with extension of .txt"
]
for ( var col = 0; col < fileIds.length; col++ ) {
var fileId = fileIds[col]
var file = DriveApp.getFileById( fileId );
// var fileBlob = file.getBlob()
// var text = fileBlob.getDataAsString().slice( 0, 10000 )
var url = "https://www.googleapis.com/drive/v3/files/" + fileId + "?alt=media&access_token=" + ScriptApp.getOAuthToken(); // Added
var res = UrlFetchApp.fetch(url).getContentText(); // Added
var text = res.slice( 0, 10000 ); // Added
var r = sh.getRange( 1, col + 1, 1, 1 )
r.setValue( fileId )
r.offset( 1, 0, 1, 1 ).setValue( file.getName() )
r.offset( 2, 0, 1, 1 ).setValue( fileDescs[col] )
r.offset( 4, 0, 1, 1 ).setValue( text )
}
}
注:
- 我认为 Lua 代码不会影响到 Google 驱动器,因为当 Lua 文件上传到时,图像的 mimeType 用于 Lua 数据Google 驱动器,Lua 的正确 mimeType 也无法使用
setContentTypeFromExtension()
设置。
- 在您的脚本中,DriveApp 已被使用。所以我认为使用 Drive API 的范围已经安装并且 Drive API 也已经启用。如果出现与 Drive API 相关的错误,请在 API 控制台确认是否启用了 Drive API。
参考:
如果此修改未能解决您的问题,我深表歉意。
那么如何在 App Script 中读取 Google Drive 文件的内容而不重新排序行?
这是我的情况:
- 我有一些文件的文本内容的文件扩展名为 。lua
- 我已将它们复制到我的 Google 驱动器
- 出于某种原因,它认为它们是图像文件!这可能是我的主要问题的原因
我正在尝试在附加到 Google 电子表格
的脚本中阅读它们function test_bug_readFile_linesInWrongOrder() { var fileId1 = "12-YLK6Lv5UYNZIgkr-u-DBviwLIOr1F2" // orig file .lua var fileId2 = "1fyvdHrc45Q_-G02XJ1ismCROKqcxyoPL" // test file shortened and .txt var fileId3 = "1uw7gG869_yIhpYh2vY2iKtUU5njBRrwA" // test file same as orig but .txt var file = DriveApp.getFileById( fileId1 ) var fileBlob = file.getBlob() // var fileBlob = file.getBlob().setContentType( "text/plain" ) var raw = fileBlob.getDataAsString() Logger.log( raw.length ) Logger.log( raw ) }
- 当我 运行 这时,我得到了文件的内容,但是行的顺序是错误的!!您可以通过更改传递给 getFileById(...) 的参数来查看各种行为
- fileId1 是原始文件并出现如下所述的错误
- fileId2 是一个小得多的文件,是一个 .txt,但它没有异常,我得到的行顺序正确
- fileId3 是原始文件的副本,但文件扩展名已更改为 .txt(为清楚起见,第一行)。这也没有显示错误,但它仍然显示为图像文件
似乎当错误发生时,具有相同 parent 行和相同缩进级别的行更改顺序,可能基于某些哈希值。我试着在这里复制文本,但无法弄清楚他的标记,而且问题已经很长了。 :)
我曾尝试在读取 blob 之前设置 MIME 类型,但这似乎没有任何作用。 以上三个数据文件我已经设置为公开可读,有问题可以私信我
那么如何在没有 google App Script "helpfully" 为您重新排序的情况下读取文件/blob 的内容?
在此先感谢您的帮助
编辑:
好的,我做了一个演示项目: https://docs.google.com/spreadsheets/d/1i_VqYANrqE5FXEQxFAx4dbheEJ89I8MwGSDrxenwHtU 您需要让它加载,然后会出现一个标题为 "BugDemo" 的菜单。一旦你有了它,只需选择其中唯一的菜单项,你就会得到一个权限对话框。我知道您可能不想授予我的代码权限,所以我将代码包含在下面的块中,这样您就可以制作自己的项目并确保没有额外的后门或任何东西。
"use strict";
function onOpen() {
SpreadsheetApp.getUi().createMenu( 'BugDemo' )
.addItem( 'Read 3 Files and show first 10,000 chars', 'test_bug_readFile_linesInWrongOrder' )
.addToUi()
}
function test_bug_readFile_linesInWrongOrder() {
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
sh.clear()
var fileIds = ["12-YLK6Lv5UYNZIgkr-u-DBviwLIOr1F2", // orig file .lua
"1fyvdHrc45Q_-G02XJ1ismCROKqcxyoPL", // test file shortened and .txt
"1uw7gG869_yIhpYh2vY2iKtUU5njBRrwA" // test file same as orig but .txt
]
var fileDescs = ["original file",
"much smaller file, also with .txt extension",
"same as first file but with extension of .txt"
]
for ( var col = 0; col < fileIds.length; col++ ) {
var fileId = fileIds[col]
var file = DriveApp.getFileById( fileId )
var fileBlob = file.getBlob()
var text = fileBlob.getDataAsString().slice( 0, 10000 )
var r = sh.getRange( 1, col + 1, 1, 1 )
r.setValue( fileId )
r.offset( 1, 0, 1, 1 ).setValue( file.getName() )
r.offset( 2, 0, 1, 1 ).setValue( fileDescs[col] )
r.offset( 4, 0, 1, 1 ).setValue( text )
}
}
一旦你运行你应该看到三列数据出现,第一列是错误的。
错误:
你 应该看到它直接从 ["$AccountWide"] 到 ["SalesData"] ,因为数据文件还有其他几行在其中,如其他 2 列中所示。
最深的缩进块,键为:( ["itemLink"], ["timestamp"], ["price"], ["wasKiosk"] , ["buyer"], ["guild"], ["seller"], ["quant"], ["id"] )都在那里,但以不同但一致的方式订单.
第一列似乎以某种方式获得了数据文件中没有的开始和结束 {}。
是否有可能 Google 在幕后使用一些 Lua 代码,然后对数据进行上下文相关的解析(理解数据结构),然后得到 re-serialized 顺序不同 ?
当我看到您共享的电子表格时,original file
似乎与其他人不同。但是当我 运行 你的脚本时,所有文件 ID 的结果都是相同的。我无法复制你的情况。
所以虽然我无法确定这是否是您问题的直接解决方案,但在本次修改中,我使用 Drive API v3 而不是 DriveApp 来检索文件内容。
修改后的脚本:
function test_bug_readFile_linesInWrongOrder() {
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
sh.clear()
var fileIds = ["12-YLK6Lv5UYNZIgkr-u-DBviwLIOr1F2", // orig file .lua
"1fyvdHrc45Q_-G02XJ1ismCROKqcxyoPL", // test file shortened and .txt
"1uw7gG869_yIhpYh2vY2iKtUU5njBRrwA" // test file same as orig but .txt
]
var fileDescs = ["original file",
"much smaller file, also with .txt extension",
"same as first file but with extension of .txt"
]
for ( var col = 0; col < fileIds.length; col++ ) {
var fileId = fileIds[col]
var file = DriveApp.getFileById( fileId );
// var fileBlob = file.getBlob()
// var text = fileBlob.getDataAsString().slice( 0, 10000 )
var url = "https://www.googleapis.com/drive/v3/files/" + fileId + "?alt=media&access_token=" + ScriptApp.getOAuthToken(); // Added
var res = UrlFetchApp.fetch(url).getContentText(); // Added
var text = res.slice( 0, 10000 ); // Added
var r = sh.getRange( 1, col + 1, 1, 1 )
r.setValue( fileId )
r.offset( 1, 0, 1, 1 ).setValue( file.getName() )
r.offset( 2, 0, 1, 1 ).setValue( fileDescs[col] )
r.offset( 4, 0, 1, 1 ).setValue( text )
}
}
注:
- 我认为 Lua 代码不会影响到 Google 驱动器,因为当 Lua 文件上传到时,图像的 mimeType 用于 Lua 数据Google 驱动器,Lua 的正确 mimeType 也无法使用
setContentTypeFromExtension()
设置。 - 在您的脚本中,DriveApp 已被使用。所以我认为使用 Drive API 的范围已经安装并且 Drive API 也已经启用。如果出现与 Drive API 相关的错误,请在 API 控制台确认是否启用了 Drive API。
参考:
如果此修改未能解决您的问题,我深表歉意。