{"id":19987125,"url":"https://github.com/lebcit/googleqlwrapper","last_synced_at":"2025-06-19T19:39:34.856Z","repository":{"id":235614974,"uuid":"790843951","full_name":"LebCit/GoogleQLWrapper","owner":"LebCit","description":"A tiny JS wrapper for Google Visualization API Query Language","archived":false,"fork":false,"pushed_at":"2024-04-24T23:09:15.000Z","size":9,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-01T20:47:28.038Z","etag":null,"topics":["google-api","google-sheets","query-language","wrapper","wrapper-api"],"latest_commit_sha":null,"homepage":"https://lebcit.github.io/posts/google-ql-wrapper/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LebCit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-23T16:23:43.000Z","updated_at":"2025-02-09T16:23:04.000Z","dependencies_parsed_at":"2024-11-13T04:33:58.605Z","dependency_job_id":"bc288ede-0dac-4e22-97db-05cf4dbdc616","html_url":"https://github.com/LebCit/GoogleQLWrapper","commit_stats":null,"previous_names":["lebcit/googleqlwrapper"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/LebCit/GoogleQLWrapper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LebCit%2FGoogleQLWrapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LebCit%2FGoogleQLWrapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LebCit%2FGoogleQLWrapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LebCit%2FGoogleQLWrapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LebCit","download_url":"https://codeload.github.com/LebCit/GoogleQLWrapper/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LebCit%2FGoogleQLWrapper/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260818076,"owners_count":23067644,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["google-api","google-sheets","query-language","wrapper","wrapper-api"],"created_at":"2024-11-13T04:33:48.057Z","updated_at":"2025-06-19T19:39:29.835Z","avatar_url":"https://github.com/LebCit.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GoogleQLWrapper\n\nGoogleQLWrapper simplifies [Google's Visualization API Query Language](https://developers.google.com/chart/interactive/docs/querylanguage).\u003cbr /\u003e\n\nTo gain insight into the development and functionality of GoogleQLWrapper, please take a moment to read the article available [here](https://lebcit.github.io/posts/google-ql-wrapper/). This article explains why and how the tool was created, providing a clear understanding of its workings.\n\n\u003e [!IMPORTANT]  \n\u003e GoogleQLWrapper works only on [publicly available spreadsheets](https://support.google.com/docs/answer/183965?hl=en\u0026ref_topic=9083762) that grant at least a **Viewer** permission to anyone on the internet with the link.\n\n# Usage\n\nTo simplify the documentation and illustrate it with concrete examples, I've created a [public multi-sheet document](https://docs.google.com/spreadsheets/d/1FrnOkibXDg7NzxxMx6x3vDzpnV522ObYSSOewuoyiGg/), with some data, that you can use to test this wrapper.\n\nAdd GoogleQLWrapper-min.js to your project.\u003cbr /\u003e\nLoad a module script before the closing `\u003c/body\u003e` tag like the following example (**index.html**):\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\t\u003chead\u003e\n\t\t\u003cmeta charset=\"UTF-8\" /\u003e\n\t\t\u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /\u003e\n\t\t\u003ctitle\u003eGoogle Sheet Data\u003c/title\u003e\n\t\u003c/head\u003e\n\t\u003cbody\u003e\n\t\t\u003ch1\u003eTesting GoogleQLWrapper\u003c/h1\u003e\n\n\t\t\u003c!-- Assuming that index.js is at the same level as index.html in your project --\u003e\n\t\t\u003cscript type=\"module\" src=\"index.js\"\u003e\u003c/script\u003e\n\t\u003c/body\u003e\n\u003c/html\u003e\n```\n\nImport the available methods from **GoogleQLWrapper-min.js** into **index.js**:\n\n```js\n// Import methods from the GoogleQLWrapper-min.js file\nimport { getSheetData, getSourceData } from \"./GoogleQLWrapper-min.js\"\n\n// Retrieving data from a Google Sheet using the getSheetData function\nconst sheetData = await getSheetData(\"1FrnOkibXDg7NzxxMx6x3vDzpnV522ObYSSOewuoyiGg\")\n\n// Retrieving data from the source of the Google Sheet using the getSourceData function\nconst sourceData = await getSourceData(\"1FrnOkibXDg7NzxxMx6x3vDzpnV522ObYSSOewuoyiGg\")\n\n// Logging the retrieved data to the console\nconsole.log(sheetData, sourceData)\n```\n\nLaunch your local server (could be integrated to your IDE/Code Editor or via an extension).\u003cbr /\u003e\nWhen the code gets executed in your browser, open the browser's console (F12) → Console (tab).\u003cbr /\u003e\nYou should see an **empty array** and an **object with some properties**.\n\n# getSheetData(sheetID, queryOptions = {})\n\nAsynchronous function to fetch data from a Google Sheets document and parse it into an array of objects.\u003cbr /\u003e\n`getSheetData` has two parameters\n\n1. `sheetID`, **mandatory** a string representing the ID of a Google Sheet, usually composed of 44 characters (combination of letters, numbers, and special characters, such as hyphens and underscores).\n2. `queryOptions`, **optional**, an object that accepts the following properties:\n    - headers: integer, zero or greater, specifies how many rows are header rows (headers: 1)\n    - gid: integer, id number of a particular sheet in a multi-sheet document (gid: 788760943)\n    - sheet: string, name of a particular sheet in a multi-sheet document (sheet: \"Sheet1\")\n    - range: string, specifies what part of a spreadsheet to use in the query (range: \"A1:F6\")\n    - [Query Language Clauses](https://developers.google.com/chart/interactive/docs/querylanguage#language-clauses) except Format and Options!\n\n\u003e [!NOTE]  \n\u003e You should only use `gid` or `sheet`. I recommend `sheet`!\n\n## getSheetData examples\n\nWhen you open the [public multi-sheet document](https://docs.google.com/spreadsheets/d/1FrnOkibXDg7NzxxMx6x3vDzpnV522ObYSSOewuoyiGg/) that I've made for this documentation, you can see that it has 3 sheets and only the **Employees_Data** sheet contains some data.\u003cbr /\u003e\nLet's modify the previous code in **index.js** and have another look to the browser's console:\n\n```js\nimport { getSheetData, getSourceData } from \"./google-ql-wrapper-min.js\"\n\nconst sheetData = await getSheetData(\"1FrnOkibXDg7NzxxMx6x3vDzpnV522ObYSSOewuoyiGg\", {\n\tsheet: \"Employees_Data\",\n})\n\nconst sourceData = await getSourceData(\"1FrnOkibXDg7NzxxMx6x3vDzpnV522ObYSSOewuoyiGg\")\n\nconsole.log(sheetData, sourceData)\n```\n\nNow that we have required the function to get the data from the sheet named **Employees_Data**, we can see that the browser's console displays an array of objects representing the table's data in this sheet!\n\nLet's use the range and some clauses to understand how it works and see what would be the output.\u003cbr /\u003e\nSuppose that we want to run the following query:\n\n1. Get the data from the sheet named Employees_Data\n2. Work only on the range from A1 to G5 (name to isSenior and 4 rows)\n3. Return only the data in the name, salary and age columns (A, D, F)\n4. Where the employee is a senior\n5. And finally arrange the returned data by ascending order of salary\n\n```js\nimport { getSheetData, getSourceData } from \"./google-ql-wrapper-min.js\"\n\nconst sheetData = await getSheetData(\"1FrnOkibXDg7NzxxMx6x3vDzpnV522ObYSSOewuoyiGg\", {\n\tsheet: \"Employees_Data\",\n\trange: \"A1:G5\",\n\tselect: \"A, D, F\",\n\twhere: \"G=true\",\n\torderBy: \"D asc\",\n})\n\nconst sourceData = await getSourceData(\"1FrnOkibXDg7NzxxMx6x3vDzpnV522ObYSSOewuoyiGg\")\n\nconsole.log(sheetData, sourceData)\n```\n\nThe following response should be displayed in the browser's console for `sheetData`:\n\n```js\n[\n\t{\n\t\tname: \"Ben\",\n\t\tsalary: \"400\",\n\t\tage: \"32\",\n\t},\n\t{\n\t\tname: \"John\",\n\t\tsalary: \"1000\",\n\t\tage: \"35\",\n\t},\n]\n```\n\nObtaining data from a public Google sheet using GoogleQLWrapper is as simple as child's play; all you need to do is familiarize yourself with the [Query Language Clauses](https://developers.google.com/chart/interactive/docs/querylanguage#language-clauses) (except Format and Options) to grasp their purposes and functionalities.\n\n# getSourceData(sheetID, sheetName)\n\nAsynchronous function to retrieve data from a public Google Sheets document.\u003cbr /\u003e\nIt returns a Promise that resolves with the retrieved data as a JavaScript object or rejects with an error.\u003cbr /\u003e\n`getSourceData` has two parameters\n\n1. `sheetID`, **mandatory** a string representing the ID of a Google Sheet, usually composed of 44 characters (combination of letters, numbers, and special characters, such as hyphens and underscores).\n2. `sheetName`, **optional**, a string representing the name of a particular sheet in a multi-sheet document.\n\n## getSourceData example\n\nUntil now, `sourceData` was returning the following object:\n\n```js\n{\n  \"version\": \"0.6\",\n  \"reqId\": \"0\",\n  \"status\": \"ok\",\n  \"sig\": \"1945619023\",\n  \"table\": {\n    \"cols\": [\n      {\n        \"id\": \"Col0\",\n        \"label\": \"\",\n        \"type\": \"string\"\n      }\n    ],\n    \"rows\": [],\n    \"parsedNumHeaders\": 0\n  }\n}\n```\n\nLet's require the **Employees_Data** sheet with `getSourceData`:\n\n```js\nimport { getSheetData, getSourceData } from \"./google-ql-wrapper-min.js\"\n\nconst sheetData = await getSheetData(\"1FrnOkibXDg7NzxxMx6x3vDzpnV522ObYSSOewuoyiGg\", {\n\tsheet: \"Employees_Data\",\n\trange: \"A1:G5\",\n\tselect: \"A, D, F\",\n\twhere: \"G=true\",\n\torderBy: \"D asc\",\n})\n\nconst sourceData = await getSourceData(\"1FrnOkibXDg7NzxxMx6x3vDzpnV522ObYSSOewuoyiGg\", \"Employees_Data\")\n\nconsole.log(sheetData, sourceData)\n```\n\nThe returned object is:\n\n```js\n{\n  \"version\": \"0.6\",\n  \"reqId\": \"0\",\n  \"status\": \"ok\",\n  \"sig\": \"1711726279\",\n  \"table\": {\n    \"cols\": [\n      {\n        \"id\": \"A\",\n        \"label\": \"name\",\n        \"type\": \"string\"\n      },\n      {\n        \"id\": \"B\",\n        \"label\": \"department\",\n        \"type\": \"string\"\n      },\n      {\n        \"id\": \"C\",\n        \"label\": \"lunchTime\",\n        \"type\": \"datetime\",\n        \"pattern\": \"h:mm:ss\"\n      },\n      {\n        \"id\": \"D\",\n        \"label\": \"salary\",\n        \"type\": \"number\",\n        \"pattern\": \"General\"\n      },\n      {\n        \"id\": \"E\",\n        \"label\": \"hireDate\",\n        \"type\": \"date\",\n        \"pattern\": \"yyyy-mm-dd\"\n      },\n      {\n        \"id\": \"F\",\n        \"label\": \"age\",\n        \"type\": \"number\",\n        \"pattern\": \"General\"\n      },\n      {\n        \"id\": \"G\",\n        \"label\": \"isSenior\",\n        \"type\": \"boolean\"\n      },\n      {\n        \"id\": \"H\",\n        \"label\": \"seniorityStartTime\",\n        \"type\": \"datetime\",\n        \"pattern\": \"yyyy-mm-dd h:mm:ss\"\n      }\n    ],\n    \"rows\": [\n      {\n        \"c\": [\n          {\n            \"v\": \"John\"\n          },\n          {\n            \"v\": \"Eng\"\n          },\n          {\n            \"v\": \"Date(1899,11,30,12,0,0)\",\n            \"f\": \"12:00:00\"\n          },\n          {\n            \"v\": 1000,\n            \"f\": \"1000\"\n          },\n          {\n            \"v\": \"Date(2005,2,19)\",\n            \"f\": \"2005-03-19\"\n          },\n          {\n            \"v\": 35,\n            \"f\": \"35\"\n          },\n          {\n            \"v\": true,\n            \"f\": \"TRUE\"\n          },\n          {\n            \"v\": \"Date(2007,11,2,15,56,0)\",\n            \"f\": \"2007-12-02 15:56:00\"\n          }\n        ]\n      },\n      {\n        \"c\": [\n          {\n            \"v\": \"Dave\"\n          },\n          {\n            \"v\": \"Eng\"\n          },\n          {\n            \"v\": \"Date(1899,11,30,12,0,0)\",\n            \"f\": \"12:00:00\"\n          },\n          {\n            \"v\": 500,\n            \"f\": \"500\"\n          },\n          {\n            \"v\": \"Date(2006,3,19)\",\n            \"f\": \"2006-04-19\"\n          },\n          {\n            \"v\": 27,\n            \"f\": \"27\"\n          },\n          {\n            \"v\": false,\n            \"f\": \"FALSE\"\n          },\n          {\n            \"v\": null\n          }\n        ]\n      },\n      {\n        \"c\": [\n          {\n            \"v\": \"Sally\"\n          },\n          {\n            \"v\": \"Eng\"\n          },\n          {\n            \"v\": \"Date(1899,11,30,13,0,0)\",\n            \"f\": \"13:00:00\"\n          },\n          {\n            \"v\": 600,\n            \"f\": \"600\"\n          },\n          {\n            \"v\": \"Date(2005,9,10)\",\n            \"f\": \"2005-10-10\"\n          },\n          {\n            \"v\": 30,\n            \"f\": \"30\"\n          },\n          {\n            \"v\": false,\n            \"f\": \"FALSE\"\n          },\n          {\n            \"v\": null\n          }\n        ]\n      },\n      {\n        \"c\": [\n          {\n            \"v\": \"Ben\"\n          },\n          {\n            \"v\": \"Sales\"\n          },\n          {\n            \"v\": \"Date(1899,11,30,12,0,0)\",\n            \"f\": \"12:00:00\"\n          },\n          {\n            \"v\": 400,\n            \"f\": \"400\"\n          },\n          {\n            \"v\": \"Date(2002,9,10)\",\n            \"f\": \"2002-10-10\"\n          },\n          {\n            \"v\": 32,\n            \"f\": \"32\"\n          },\n          {\n            \"v\": true,\n            \"f\": \"TRUE\"\n          },\n          {\n            \"v\": \"Date(2005,2,9,12,30,0)\",\n            \"f\": \"2005-03-09 12:30:00\"\n          }\n        ]\n      },\n      {\n        \"c\": [\n          {\n            \"v\": \"Dana\"\n          },\n          {\n            \"v\": \"Sales\"\n          },\n          {\n            \"v\": \"Date(1899,11,30,12,0,0)\",\n            \"f\": \"12:00:00\"\n          },\n          {\n            \"v\": 350,\n            \"f\": \"350\"\n          },\n          {\n            \"v\": \"Date(2004,8,8)\",\n            \"f\": \"2004-09-08\"\n          },\n          {\n            \"v\": 25,\n            \"f\": \"25\"\n          },\n          {\n            \"v\": false,\n            \"f\": \"FALSE\"\n          },\n          {\n            \"v\": null\n          }\n        ]\n      },\n      {\n        \"c\": [\n          {\n            \"v\": \"Mike\"\n          },\n          {\n            \"v\": \"Marketing\"\n          },\n          {\n            \"v\": \"Date(1899,11,30,13,0,0)\",\n            \"f\": \"13:00:00\"\n          },\n          {\n            \"v\": 800,\n            \"f\": \"800\"\n          },\n          {\n            \"v\": \"Date(2005,0,10)\",\n            \"f\": \"2005-01-10\"\n          },\n          {\n            \"v\": 24,\n            \"f\": \"24\"\n          },\n          {\n            \"v\": true,\n            \"f\": \"TRUE\"\n          },\n          {\n            \"v\": \"Date(2007,11,30,14,40,0)\",\n            \"f\": \"2007-12-30 14:40:00\"\n          }\n        ]\n      }\n    ],\n    \"parsedNumHeaders\": 1\n  }\n}\n```\n\n`getSourceData` provides us with a lot of useful details regarding the data that we can use to understand how the data is formatted.\n\n# Tip\n\nYou can find a lot of public Google Sheets on [heystack](https://heystacks.com/) to test GoogleQLWrapper and master The Google Visualization API Query Language (GViz).\n\nI sincerely hope that this compact and user-friendly wrapper proves invaluable to anyone seeking to retrieve data from publicly accessible Google Sheets!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flebcit%2Fgoogleqlwrapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flebcit%2Fgoogleqlwrapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flebcit%2Fgoogleqlwrapper/lists"}