如何将 Google 电子表格的工作表字符串 id 转换为整数索引 (GID)?

Posted

技术标签:

【中文标题】如何将 Google 电子表格的工作表字符串 id 转换为整数索引 (GID)?【英文标题】:How to convert Google spreadsheet's worksheet string id to integer index (GID)? 【发布时间】:2012-07-02 16:05:27 【问题描述】:

要将谷歌电子表格的单个工作表导出为 CSV,需要传递整数工作表索引(GID)。

https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key=%s&gid=%d&exportFormat=csv

但是,这些信息在哪里?使用 gdata.spreadsheets.client,我可以为工作表找到一些字符串 id,例如“oc6、ocv、odf”。

client = gdata.spreadsheets.client.SpreadsheetsClient()
feed = client.GetWorksheets(spreadsheet, auth_token=auth_token)

它返回下面的原子 XML。 (部分)

<entry gd:etag="&quot;URJFCB1NQSt7ImBoXhU.&quot;">
    <id>https://spreadsheets.google.com/feeds/worksheets/0AvhN_YU3r5e9dGpTWGx3UVU3MTczaXJuNEFKQjMwN2c/ocw</id>
    <updated>2012-06-21T08:19:46.587Z</updated>
    <app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-21T08:19:46.587Z</app:edited>
    <category scheme="http://schemas.google.com/spreadsheets/2006" term="http://schemas.google.com/spreadsheets/2006#worksheet"/>
    <title>AchievementType</title>
    <content type="application/atom+xml;type=feed" src="https://spreadsheets.google.com/feeds/list/0AvhN_YU3r5e9dGpTWGx3UVU3MTczaXJuNEFKQjMwN2c/ocw/private/full"/>
    <link rel="http://schemas.google.com/spreadsheets/2006#cellsfeed" type="application/atom+xml" href="https://spreadsheets.google.com/feeds/cells/0AvhN_YU3r5e9dGpTWGx3UVU3MTczaXJuNEFKQjMwN2c/ocw/private/full"/>
    <link rel="http://schemas.google.com/visualization/2008#visualizationApi" type="application/atom+xml" href="https://spreadsheets.google.com/tq?key=0AvhN_YU3r5e9dGpTWGx3UVU3MTczaXJuNEFKQjMwN2c&amp;sheet=ocw"/>
    <link rel="self" type="application/atom+xml" href="https://spreadsheets.google.com/feeds/worksheets/0AvhN_YU3r5e9dGpTWGx3UVU3MTczaXJuNEFKQjMwN2c/private/full/ocw"/>
    <link rel="edit" type="application/atom+xml" href="https://spreadsheets.google.com/feeds/worksheets/0AvhN_YU3r5e9dGpTWGx3UVU3MTczaXJuNEFKQjMwN2c/private/full/ocw"/>
    <gs:rowCount>280</gs:rowCount>
    <gs:colCount>28</gs:colCount>
</entry>

我也尝试使用工作表参数,但失败并出现“无效工作表”错误。

https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key=%s&sheet=XXX&exportFormat=csv

我想应该有一些神奇的功能,但找不到。如何将它们转换为整数 id?或者我可以使用字符串 id 导出工作表吗?

编辑:我刚刚用 python 制作了转换表。脏但工作:-(

GID_TABLE = 
    'od6': 0, 
    'od7': 1, 
    'od4': 2, 
    'od5': 3, 
    'oda': 4, 
    'odb': 5, 
    'od8': 6, 
    'od9': 7, 
    'ocy': 8, 
    'ocz': 9, 
    'ocw': 10, 
    'ocx': 11, 
    'od2': 12, 
    'od3': 13, 
    'od0': 14, 
    'od1': 15, 
    'ocq': 16, 
    'ocr': 17, 
    'oco': 18, 
    'ocp': 19, 
    'ocu': 20, 
    'ocv': 21, 
    'ocs': 22, 
    'oct': 23, 
    'oci': 24, 
    'ocj': 25, 
    'ocg': 26, 
    'och': 27, 
    'ocm': 28, 
    'ocn': 29, 
    'ock': 30, 
    'ocl': 31, 
    'oe2': 32, 
    'oe3': 33, 
    'oe0': 34, 
    'oe1': 35, 
    'oe6': 36, 
    'oe7': 37, 
    'oe4': 38, 
    'oe5': 39, 
    'odu': 40, 
    'odv': 41, 
    'ods': 42, 
    'odt': 43, 
    'ody': 44, 
    'odz': 45, 
    'odw': 46, 
    'odx': 47, 
    'odm': 48, 
    'odn': 49, 
    'odk': 50, 
    'odl': 51, 
    'odq': 52, 
    'odr': 53, 
    'odo': 54, 
    'odp': 55, 
    'ode': 56, 
    'odf': 57, 
    'odc': 58, 
    'odd': 59, 
    'odi': 60, 
    'odj': 61, 
    'odg': 62, 
    'odh': 63, 
    'obe': 64, 
    'obf': 65, 
    'obc': 66, 
    'obd': 67, 
    'obi': 68, 
    'obj': 69, 
    'obg': 70, 
    'obh': 71, 
    'ob6': 72, 
    'ob7': 73, 
    'ob4': 74, 
    'ob5': 75, 
    'oba': 76, 
    'obb': 77, 
    'ob8': 78, 
    'ob9': 79, 
    'oay': 80, 
    'oaz': 81, 
    'oaw': 82, 
    'oax': 83, 
    'ob2': 84, 
    'ob3': 85, 
    'ob0': 86, 
    'ob1': 87, 
    'oaq': 88, 
    'oar': 89, 
    'oao': 90, 
    'oap': 91, 
    'oau': 92, 
    'oav': 93, 
    'oas': 94, 
    'oat': 95, 
    'oca': 96, 
    'ocb': 97, 
    'oc8': 98, 
    'oc9': 99

【问题讨论】:

我正在尝试或多或少做同样的事情。就我而言,我正在以编程方式生成电子表格,我需要将各个工作表的链接存储在单独的数据库中。 好的,谷歌。这是一个玩笑,对吧?非常有趣。现在我们可以请适当的工作表索引而不是这些疯狂的东西吗?... 如果有人面临同样的问题,那么这里是简单的答案:code.google.com/p/gdata-python-client/issues/detail?id=698#c6 【参考方案1】:

我发现您的问题正在寻找相同问题的解决方案,并且惊讶地发现这些工作表 ID 实际上与 gids 对应 1:1 - 我最初假设它们是独立分配的,而不是进行混淆的练习。

通过对他们用来从您的表生成工作表 ID 的公式进行逆向工程,我能够找到一个稍微更清洁的解决方案:

worksheetID = (gid xor 31578) encoded in base 36

所以,一些 Python 从工作表 ID 转到 gid

def to_gid(worksheet_id):
    return int(worksheet_id, 36) ^ 31578

这仍然很脏,但适用于高于 99 的 GID,而不需要巨型表。至少只要他们不更改生成逻辑(他们可能不会,因为这会破坏人们已经使用的现有 ID)。

【讨论】:

您能指导我们解决这个问题吗? 我注意到重复的模式。前四个值以 6,7,4,5 结尾,接下来的四个:a(10),b(11),8,9 - 相同的级数。我注意到如果你对连续的数字与以二进制结尾的 10 进行异或运算,它会像这样工作。这就是我认为这些字符串实际上是数字的方式。它们包含所有字母,所以我认为它必须是 base-36。从那里找到 XOR 因子很简单。 谁有 .NET 的转换? 这是我听说过的最疯狂、最随机的无证但从根本上有序的批判有用的行为。我对你 Jakub 表示敬意,因为你弄清楚了这一点。因为对整件事如此漠不关心。【参考方案2】:

此代码适用于新的 Google 表格。

// Conversion of Worksheet Ids to GIDs and vice versa
// od4 > 2
function wid_to_gid(wid) 
    var widval = wid.length > 3 ? wid.substring(1) : wid;
    var xorval = wid.length > 3 ? 474 : 31578;
    return parseInt(String(widval), 36) ^ xorval;

// 2 > od4
function gid_to_wid(gid) 
    var xorval = gid > 31578 ? 474 : 31578;
    var letter = gid > 31578 ? 'o' : '';
    return letter + parseInt((gid ^ xorval)).toString(36);

【讨论】:

【参考方案3】:

我无法在 Wasilewski 的帖子中添加评论,因为显然我缺乏声誉,所以这里是基于 Wasilewski 回答的 javascript 中的两个转换函数:

// Conversion of Worksheet Ids to GIDs and vice versa
// od4 > 2
function wid_to_gid(wid) 
    return parseInt(String(wid),36)^31578

// 2> 0d4
function gid_to_wid(gid) 
    // (gid xor 31578) encoded in base 36
    return parseInt((gid^31578)).toString(36);

【讨论】:

这似乎不再适用于新的 Google 表格。【参考方案4】:

这是 Buho 代码的 Java 改编版本,可与新的 Google 表格和旧版 Google 电子表格一起使用。

// "od4" to 2  (legacy style)
// "ogtw0h0" to 1017661118 (new style)
public static int widToGid(String worksheetId) 

    boolean idIsNewStyle = worksheetId.length() > 3;

    // if the id is in the new style, first strip the first character before converting
    worksheetId = idIsNewStyle ? worksheetId.substring(1) : worksheetId;

    // determine the integer to use for bitwise XOR
    int xorValue = idIsNewStyle ? 474 : 31578;

    // convert to gid
    return Integer.parseInt(worksheetId, 36) ^ xorValue;



// Convert 2 to "od4" (legacy style)
// Convert 1017661118 to "ogtw0h0"  (new style)
public static String gidToWid(int gid) 

    boolean idIsNewStyle = gid > 31578;

    // determine the integer to use for bitwise XOR
    int xorValue = idIsNewStyle ? 474 : 31578;

    // convert to worksheet id, prepending 'o' if it is the new style.
    return 
        idIsNewStyle ? 
        'o' + Integer.toString((worksheetIndex ^ xorValue), 36): 
        Integer.toString((worksheetIndex ^ xorValue), 36);


【讨论】:

太棒了,几年后我才注意到你的新床单支持。【参考方案5】:

这是对 Buho 和 Julie 代码的 Clojure 改编版本,它应该适用于新的 Google 表格和旧版 Google 电子表格。

(defn wid->gid [wid]
  (let [new-wid? (> (.length wid) 3)
        wid      (if new-wid? (.substring wid 1) wid)
        xor-val  (if new-wid? 474 31578)]
    (bit-xor (Integer/parseInt wid 36) xor-val)))

(defn gid->wid [gid]
  (let [new-gid? (> gid 31578)
        xor-val  (if new-gid? 474 31578)
        letter   (if new-gid? "o" "")]
    (str letter (Integer/toString (bit-xor gid xor-val) 36))))

【讨论】:

【参考方案6】:

如果您将 Python 与 gspread 一起使用,请执行以下操作:

wid = worksheet.id
widval = wid[1:] if len(wid) > 3 else wid
xorval = 474 if len(wid) > 3 else 31578
gid = int(str(widval), 36) ^ xorval

我可能会为此打开一个 PR。

【讨论】:

以上是关于如何将 Google 电子表格的工作表字符串 id 转换为整数索引 (GID)?的主要内容,如果未能解决你的问题,请参考以下文章

如何将宏应用于 Google 表格中一个电子表格中的所有表格

无法访问通过 Google 电子表格 API 通过服务帐户创建的工作表

如何使用 Python 中的 API 重命名 Google Sheets 电子表格中的(工作)表?

Google脚本将电子表格中的工作表复制到新电子表格并在特定单元格后命名新电子表格

如何将范围传递给 Google 电子表格中的自定义函数?

如果源在不同的工作表中,Google 电子表格如何插入注释