簡體   English   中英

僅使用JavaScript,如何查詢Google工作表並將單個單元格的值分配為JavaScript變量?

[英]Using JavaScript only, how can I query a google sheet and assign the value of a single cell as a JavaScript variable?

我想使用一些Google表格中的數據來驅動網頁。

我已經弄清楚了如何查詢我的工作表,但是數據顯示為數據表,而這並不是我想要的。 我希望能夠獲取查詢單元格值並將其插入HTML代碼。 我還將在另一個查詢中使用該值,以便從其他Google工作表中檢索其他信息。

我有兩個實時頁面: http : //www.bandstand.ca/widget

此頁面是我的項目的入門版本。 我現在已經靜態地對“第5天”進行了編碼和格式化,但要按照以下查詢數據替換它: http//www.bandstand.ca/widget/sas.html

我曾嘗試使用getValue(0,0),但一定不能設置正確的東西。 我對使用查詢完全陌生,還無法弄清JavaScript是否可以對響應的內容做任何事情。 我嘗試隱藏查詢填充的div元素並僅解析數據表的內容,但是同樣,無法找到可行的解決方案。 我嘗試搜索api文檔,但找不到任何看起來正確的東西。 當然,有一種方法可以提取數據並在其他html中使用它。 我並不特別在乎代碼是否干凈(我敢肯定,您可以說,我已經破解了其他人的代碼,以使sas.html文件降至其所在位置。)我只是想要一些可行的方法。

我是一名老師,並認為這是構建一個班級公告頁面的簡單小項目,該頁面可以一直顯示在我的房間中,並可以通過我輕松更新的Google表格在課程表中循環顯示。 到目前為止,還不是那么容易! 如果有人可以幫助調整我的代碼以獲取我的要求,我將不勝感激!

您可以嘗試如下操作:

 function GetCurrentDate() { var currentTime = new Date(); var month = currentTime.getMonth() + 2; var day = currentTime.getDate(); var year = currentTime.getFullYear(); var currentDate = "'" + year + "-" + month + "-" + day + "'"; return currentDate; } function CreateUrl(key, gql) { var gq = 'SELECT '+ gql; var encodedgg = encodeURIComponent(gq); var url = 'https://docs.google.com/spreadsheets/d/' + key + '/gviz/tq?tq=' + encodedgg; return url; } function Request(url, responseFunction) { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var response = this.responseText.substring(this.responseText.IndexOf("(")+1, this.responseText.lastIndexOf(")")); var responseJSON = JSON.parse(response); responseFunction(responseJSON); } }; xmlhttp.open("GET", url, true); xmlhttp.send(); } function preview(elm, url) { fetch(url) .then(data => data.text()) .then(function(response) { var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")")); var response = JSON.parse(responseText); var value = response['table']['rows'][0]['c'][0]['v']; elm.innerHTML = value; }) } var gsKey = '1-dNm_AKv3Iiy-ggLjGJKHPwUqs379QJh0e4SzbEPcJQ'; var currentDate = GetCurrentDate(); var gql = "C WHERE A = DATE " + currentDate; var url = CreateUrl(gsKey, gql); var previewElement = document.getElementById('preview'); preview(previewElement, url); 
 <html> <head> <title>Student Announcement System</title> </head> <body> <div id="preview">initial value</div> </body> </html> 

這是jsbin片段的鏈接。 (由於CORSAccess-Control-Allow-Origin,內聯stackoverflow片段可能無法正常工作。)

格雷格·杜吉德(Greg Duguid)評論編輯

您的代碼存在三個問題:

  1. 您的腳本根本不起作用。 嘗試運行以下代碼段:

 <script> document.write("Text 1") </script> <script language = "text/javascript"> document.write("Text 2") </script> <script type = "text/javascript"> document.write("Text 3") </script> 

當您運行它時,您應該得到類似於Text 1 Text 3 ,這是因為<script language = "text/javascript">是錯誤的並且不起作用,不推薦使用language參數,而應該使用type 同樣在HTML5中,您可以省略type參數,因此最好使用類似<script>document.write("Text")</script>這樣的語法。

  1. 函數preview有語法錯誤:最后一個括號(應為)

 // OLD CODE /* function preview(elm, url) { fetch(url) .then(data => data.text()) .then(function(response) { var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")")); var response = JSON.parse(responseText); var value = response['table']['rows'][0]['c'][0]['v']; //elm.innerHTML = value; DayNumber = value; } ( // ERROR IS IN THIS LINE } */ // NEW CODE function preview(elm, url) { fetch(url) .then(data => data.text()) .then(function(response) { var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")")); var response = JSON.parse(responseText); var value = response['table']['rows'][0]['c'][0]['v']; //elm.innerHTML = value; DayNumber = value; } ) // error WAS in this line } 

  1. 代碼如下:

      <font size="+6" color="#FFFF00">Day <script>document.write(DayNumber);</script></font> 

    當您調用函數document.write(DayNumber)變量DayNumber等於""因為此時函數preview仍未執行。 原因是執行功能preview需要時間。 (因為通常是從工作表或類似的文件中檢索數據,這是從工作表文檔中檢索數據的時間。)javascript中的代碼執行是異步的,這意味着javscript不會等待函數完成執行並繼續執行。 看這個例子:

     function getData() { // some function that takes time to get data from server, ducument, or something else return data; } var data = getData(); document.write(data); 

    在第一行中,調用了getData()函數,但是由於程序不會等待函數getData()返回其值,因此數據將被設置為undefined 因此,函數document.write(data)將不會預覽任何內容。

    (在另一個標簽內使用腳本標簽也是一種不好的做法。因此,應避免將腳本標簽放在字體標簽內,如下所示: <font size="+6" color="#FFFF00">Day <script>document.write(DayNumber);</script></font> 。)

    解決此問題的方法是,將id添加到font標簽中,然后在功能preview中的javascript中更改font標簽中的文本:

 function GetCurrentDate() { var currentTime = new Date(); var month = currentTime.getMonth(); var day = currentTime.getDate() + 1; var year = currentTime.getFullYear(); var currentDate = "'" + year + "-" + month + "-" + day + "'"; return currentDate; } function CreateUrl(key, gql) { var gq = 'SELECT '+ gql; var encodedgg = encodeURIComponent(gq); var url = 'https://docs.google.com/spreadsheets/d/' + key + '/gviz/tq?tq=' + encodedgg; return url; } function Request(url, responseFunction) { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var response = this.responseText.substring(this.responseText.IndexOf("(")+1, this.responseText.lastIndexOf(")")); var responseJSON = JSON.parse(response); responseFunction(responseJSON); } }; xmlhttp.open("GET", url, true); xmlhttp.send(); } function preview(elm, url) { fetch(url) .then(data => data.text()) .then(function(response) { var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")")); var response = JSON.parse(responseText); var value = response['table']['rows'][0]['c'][0]['v']; elm.innerHTML += " " + value; } ) } var gsKey = '1-dNm_AKv3Iiy-ggLjGJKHPwUqs379QJh0e4SzbEPcJQ'; var currentDate = GetCurrentDate(); var gql = "C WHERE A = DATE " + currentDate; var url = CreateUrl(gsKey, gql); var previewElement = document.getElementById('preview'); preview(previewElement, url); 
 <html> <title>Student Announcement System</title> <body> <font size="+6" color="#FFFF00" id="preview">Day</font> </body> </html> 

最后的代碼應該可以解決您的問題。 另外,這里是jsbin片段的鏈接 (因為當您運行它時stackoverflow片段可能不起作用)。

第二個Greg Duguid評論編輯

抱歉,花了一點時間才回答。 問題所在:

var previewElement = document.getElementById('preview');

執行此行時,未找到previewElement並且將其設置為undefined 這是因為腳本標記( <script>...</script> )中的javascript代碼在body標記( <body>...</body> )之前,因此代碼是在body的元素定義之前執行的。 因此,當您的頁面運行時,首先執行javascript代碼,然后定義元素<font id="preview">Day</font> 有一個簡單的解決方案:您需要將script標簽放在正文的末尾,如下所示:

 <html> <head> <style type="text/css"> <!-- body { background-color: #003c66; } --> </style> <title>Student Announcement System</title> </head> <body> <font size="+6" color="#FFFF00" id="preview">Day</font> <script> function GetCurrentDate() { var currentTime = new Date(); var month = currentTime.getMonth()+1; var day = currentTime.getDate(); var year = currentTime.getFullYear(); var currentDate = "'" + year + "-" + month + "-" + day + "'"; return currentDate; } function CreateUrl(key, gql, sheet) { var gq = 'SELECT '+ gql; var encodedgg = encodeURIComponent(gq); var url = 'https://docs.google.com/spreadsheets/d/' + key + '/gviz/tq?tq=' + encodedgg + '&gid=' + sheet; return url; } function Request(url, responseFunction) { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var response = this.responseText.substring(this.responseText.IndexOf("(")+1, this.responseText.lastIndexOf(")")); var responseJSON = JSON.parse(response); responseFunction(responseJSON); } }; xmlhttp.open("GET", url, true); xmlhttp.send(); } function preview(elm, url) { fetch(url) .then(data => data.text()) .then(function(response) { var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")")); var response = JSON.parse(responseText); var value = response['table']['rows'][0]['c'][0]['v']; elm.innerHTML += " " + value; } ) } var gsKey = '1-dNm_AKv3Iiy-ggLjGJKHPwUqs379QJh0e4SzbEPcJQ'; var gsSheet='349215948'; var currentDate = GetCurrentDate(); var gql = "C WHERE A = DATE " + currentDate; var url = CreateUrl(gsKey, gql, gsSheet); var previewElement = document.getElementById('preview'); preview(previewElement, url); </script> </body> </html> 

再次是應該工作的jsbin片段

Greg Duguid的評論之后進行編輯

問題出在您的查詢中:

var PERIODgql = "C WHERE A = " + value + " AND B = " + CurrentPeriod;

CurrentPeriod是字符串,因此您需要像這樣在其周圍添加單引號:

var PERIODgql = "C WHERE A = " + value + " AND B = '" + CurrentPeriod + "'";

創建后, PERIODgql將類似於:

"C WHERE A = 1 AND B = 'P5'"

這些查詢類似於SQL查詢(用於從SQL數據庫獲取數據),您可以在此處閱讀有關此內容的更多信息。

我也注意到你的功能FindCurrentPeriod

function FindCurrentPeriod() {
    var CurrentPeriod;
    var CurrentDate = new Date();

    //////////////////////////////
    //FOR TESTING VARIOUS TIMES
    CurrentDate.setHours(14);
    CurrentDate.setMinutes(0);
    //////////////////////////////


    var CurrentHour = CurrentDate.getHours();
    var CurrentMinute = CurrentDate.getMinutes();
    if (CurrentHour < 8) {
        CurrentPeriod = "Before School";
    }

    if (CurrentHour == 8) {
        if (CurrentMinute < 40) {
            CurrentPeriod = "Before School";
        } else {
            CurrentPeriod = "P1";
        }
    }

    if (CurrentHour == 9) {
        if (CurrentMinute < 40) {
            CurrentPeriod = "P1";
        } else {
            if (CurrentMinute < 45) {
                CurrentPeriod = "B12";
            } else {
                CurrentPeriod = "P2";
            }
        }
    }
    if (CurrentHour == 10) {
        if (CurrentMinute < 37) {
            CurrentPeriod = "P2";
        } else {
            if (CurrentMinute < 47) {
                CurrentPeriod = "B23";
            } else {
                CurrentPeriod = "P3";
            }
        }
    }

    if (CurrentHour == 11) {
        if (CurrentMinute < 39) {
            CurrentPeriod = "P3";
        } else {
            if (CurrentMinute < 44) {
                CurrentPeriod = "B34";
            } else {
                CurrentPeriod = "P4";
            }
        }
    }
    if (CurrentHour == 12) {
        if (CurrentMinute < 36) {
            CurrentPeriod = "P4";
        } else {
            CurrentPeriod = "Lunch";
        }
    }

    if (CurrentHour == 13) {
        if (CurrentMinute < 13) {
            CurrentPeriod = "Lunch";
        } else {
            CurrentPeriod = "P5";
        }
    }

    if (CurrentHour == 14) {
        if (CurrentMinute < 5) {
            CurrentPeriod = "P5";
        } else {
            if (CurrentMinute < 10) {
                CurrentPeriod = "B56";
            } else {
                CurrentPeriod = "P6";
            }
        }
    }

    if (CurrentHour == 15) {
        if (CurrentMinute < 2) {
            CurrentPeriod = "P6";
        } else {
            CurrentPeriod = "After School";
        }
    } else {
        CurrentPeriod = "After School";
    }
    return CurrentPeriod;

}

在這種情況下,它並不是很容易閱讀,並且存在一些重復的條件,因此,如果以后需要更改代碼,將很難做到。 因此,我建議您使用一個函數來幫助您比較時間(以小時和分鍾為單位)。 您可以像這樣添加短函數:

function time(hours, minutes) {
    return hours*60 + minutes;
}

現在,您可以像這樣比較時間10:50和11:25:

if (time(10,50) < time(11,25)) {
    //part when you do what you want if condition is ture
}

因此,您可以這樣編寫函數FindCurrentPeriod

function FindCurrentPeriod() {
    var CurrentPeriod;
    var CurrentDate = new Date();

    //////////////////////////////
    //FOR TESTING VARIOUS TIMES
    CurrentDate.setHours(14);
    CurrentDate.setMinutes(0);
    //////////////////////////////

    var CurrentHour = CurrentDate.getHours();
    var CurrentMinute = CurrentDate.getMinutes();
    var cirrentTime = time(CurrentHour, CurrentMinute);

    if (cirrentTime < time(8, 40)) {
        CurrentPeriod = "Before School";
    }
    else if (cirrentTime < time(9, 40)) {
        CurrentPeriod = "P1";
    }
    else if (cirrentTime < time(9, 45)) {
        CurrentPeriod = "B12";
    }
    else if (cirrentTime < time(10, 37)) {
        CurrentPeriod = "P2";
    }
    else if (cirrentTime < time(10, 47)) {
        CurrentPeriod = "B23";
    }
    else if (cirrentTime < time(11, 39)) {
        CurrentPeriod = "P3";
    }
    else if (cirrentTime < time(11, 44)) {
        CurrentPeriod = "P3";
    }
    else if (cirrentTime < time(12, 36)) {
        CurrentPeriod = "P4";
    }
    else if (cirrentTime < time(13, 13)) {
        CurrentPeriod = "Lunch";
    }
    else if (cirrentTime < time(14, 5)) {
        CurrentPeriod = "P5";
    }
    else if (cirrentTime < time(14, 10)) {
        CurrentPeriod = "B56";
    }
    else if (cirrentTime < time(15, 2)) {
        CurrentPeriod = "P6";
    }
    else {
        CurrentPeriod = "After School";
    }


    return CurrentPeriod;

}

它更短,並且在需要時更易於閱讀和更改。

這是stackoverflow片段中的完整代碼(再次,我將在下面添加jsbin片段,因為由於CORS規則,內聯stackoverflow片段可能不起作用):

 function preview2(elm, url) { fetch(url) .then(data => data.text()) .then(function(response) { var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")")); var response = JSON.parse(responseText); var value = response['table']['rows'][0]['c'][0]['v']; elm.innerHTML = value; }) } function GetCurrentDate() { var currentTime = new Date(); var month = currentTime.getMonth() + 1; var day = currentTime.getDate(); var year = currentTime.getFullYear(); var currentDate = "'" + year + "-" + month + "-" + day + "'"; return currentDate; } function CreateUrl(key, gql, sheet) { var gq = 'SELECT ' + gql; var encodedgg = encodeURIComponent(gq); var url = 'https://docs.google.com/spreadsheets/d/' + key + '/gviz/tq?tq=' + encodedgg + '&gid=' + sheet; return url; } function time(hours, minutes) { return hours*60 + minutes; } function FindCurrentPeriod() { var CurrentPeriod; var CurrentDate = new Date(); ////////////////////////////// //FOR TESTING VARIOUS TIMES CurrentDate.setHours(14); CurrentDate.setMinutes(0); ////////////////////////////// var CurrentHour = CurrentDate.getHours(); var CurrentMinute = CurrentDate.getMinutes(); var cirrentTime = time(CurrentHour, CurrentMinute); if (cirrentTime < time(8, 40)) { CurrentPeriod = "Before School"; } else if (cirrentTime < time(9, 40)) { CurrentPeriod = "P1"; } else if (cirrentTime < time(9, 45)) { CurrentPeriod = "B12"; } else if (cirrentTime < time(10, 37)) { CurrentPeriod = "P2"; } else if (cirrentTime < time(10, 47)) { CurrentPeriod = "B23"; } else if (cirrentTime < time(11, 39)) { CurrentPeriod = "P3"; } else if (cirrentTime < time(11, 44)) { CurrentPeriod = "P3"; } else if (cirrentTime < time(12, 36)) { CurrentPeriod = "P4"; } else if (cirrentTime < time(13, 13)) { CurrentPeriod = "Lunch"; } else if (cirrentTime < time(14, 5)) { CurrentPeriod = "P5"; } else if (cirrentTime < time(14, 10)) { CurrentPeriod = "B56"; } else if (cirrentTime < time(15, 2)) { CurrentPeriod = "P6"; } else { CurrentPeriod = "After School"; } return CurrentPeriod; } function preview1(elm, url) { fetch(url) .then(data => data.text()) .then(function(response) { var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")")); var response = JSON.parse(responseText); var value = response['table']['rows'][0]['c'][0]['v']; elm.innerHTML += " " + value; var CurrentPeriod = FindCurrentPeriod(); var PERIODgsSheet = '618896702'; var PERIODgql = "C WHERE A = " + value + " AND B = '" + CurrentPeriod + "'"; var PeriodURL = CreateUrl(gsKey, PERIODgql, PERIODgsSheet); var periodElement = document.getElementById('period1'); preview2(periodElement, PeriodURL); }) } var gsKey = '1-dNm_AKv3Iiy-ggLjGJKHPwUqs379QJh0e4SzbEPcJQ'; var DAYgsSheet = '349215948'; var currentDate = GetCurrentDate(); var DAYgql = "C WHERE A = DATE " + currentDate; var DayURL = CreateUrl(gsKey, DAYgql, DAYgsSheet); var previewElement = document.getElementById('preview'); preview1(previewElement, DayURL); 
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="refresh" content="600" /> <title>Student Announcement System</title> <style type="text/css"> <!-- body { background-color: #003c66; } --> </style> <!-- CSS Code --> <style type="text/css" scoped> .GeneratedMarquee { font-family:'Arial Black', sans-serif; font-size:8em; font-weight:bold; line-height:2em; text-align:left; color:#ffff00; background-color:#003c66; padding:40pt; } </style> </head> <body> <table width=100%> <tr> <td width=240px> <iframe scrolling="no" frameborder="no" clocktype="html5" style="overflow:hidden;border:0;margin:0;padding:0;width:240px;height:80px;"src="https://www.clocklink.com/html5embed.php?clock=004&timezone=MST&color=white&size=240&Title=&Message=&Target=&From=2018,1,1,0,0,0&Color=white"></iframe> </td> <td nowrap> <center> <font size="80px" color="#FFFF00" id="preview">DAY </font> </center> </td> <td width=100%> <a class="weatherwidget-io" href="https://forecast7.com/en/53d54n113d49/edmonton/" data-label_1="EDMONTON" data-font="Helvetica" data-icons="Climacons Animated" data-days="7" data-theme="original" data-basecolor="#003c66" ></a> <script> !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src='https://weatherwidget.io/js/widget.min.js';fjs.parentNode.insertBefore(js,fjs);}}(document,'script','weatherwidget-io-js'); </script> </td> </tr> </table> <font color="FFFFFF", size="+6"> <script language=javascript> var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }; var today = new Date(); document.write(today.toLocaleDateString("en-US", options)); // Saturday, September 17, 2016 formattedDate = today.toLocaleDateString("en-US", options); </script> </font> <br><font size="80px" color="#FFFF00" id="period1">Class:</font> <script src="sas.js"></script> </body> </html> 

這是jsbin片段

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM