How to convert Google spreadsheet's worksheet string id to integer index (GID)?

前端 未结 6 1825
遇见更好的自我
遇见更好的自我 2020-12-02 17:46

To export google spreadsheet\'s single worksheet to CSV, integer worksheet index(GID) is required to be passed.

https://spreadsheets.google.com/feeds

相关标签:
6条回答
  • 2020-12-02 18:06

    I cannot add a comment to Wasilewski's post because apparently I lack reputation so here are the two conversion functions in Javascript based on Wasilewski's answer:

    // 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);
    }
    
    0 讨论(0)
  • 2020-12-02 18:15

    This code works with the new Google Sheets.

    // 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);
    }
    
    0 讨论(0)
  • 2020-12-02 18:15

    If you're using Python with gspread, here's what you do:

    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
    

    I'll probably open a PR for this.

    0 讨论(0)
  • 2020-12-02 18:20

    This is a Java adaptation of Buho's code which works with both the new Google Sheets and with the legacy Google Spreadsheets.

    // "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);
    
    }
    
    0 讨论(0)
  • 2020-12-02 18:24

    This is a Clojure adaptation of Buho's and Julie's code which should work with both the new Google Sheets and with the legacy Google Spreadsheets.

    (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))))
    
    0 讨论(0)
  • 2020-12-02 18:25

    I found your question looking for a solution to the same problem, and was surprised that those worksheet IDs actually correspond 1:1 to gids - I originally assumed they were assigned independently, instead of being an exercise in obfuscation.

    I was able to find a slightly cleaner solution by reverse-engineering the formula they use to generate worksheet IDs from your table:

    worksheetID = (gid xor 31578) encoded in base 36
    

    So, some Python to go from a worksheet ID to gid:

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

    This is still dirty, but will work for GIDs higher than 99 without requiring giant tables. At least as long as they don't change the generation logic (which they probably won't, as it would break existing IDs that people already use).

    0 讨论(0)
提交回复
热议问题