Showing posts with label Google Apps Script. Show all posts
Showing posts with label Google Apps Script. Show all posts

August 27, 2013

How to get all your Google Drive folders and URLs with GAS JSONP servlet




Using all the folders of a Google Drive account as a collaboration point over an external web app sounds pretty convenient under certain scenarios, especially for web-based Centralized Business Management.

Apps Script makes this easy with Drive Services and with very little effort you can make a GAS JSONP servlet that query's and packs all the folder names and URLs in a single JSON string, this is specially useful if you are trying to merge different accounts over a single interface. You can get pretty creative about how to implement this.

To make your own GAS JSONP servlet to handle your G.Drive file names & URLs, create a new Google Apps Script project and copy the following code:


Depending on what you need, you might add more data about the folders, this are the most relevant methods:

1.- getAccess(email): Check the users rights on this folder:

2.- getDateCreated(): To know the date when the folder was created.

3.- getDescription(): To get the folders description.

4.- getId(): This one it's particularly useful when working with JSONP, you can use the padding to tell the servlet to do something to a specific folder using the getFolderById(id) method.

5.- getFiles(): It's possible to add all files inside each folder in our JSON package, just add another While cycle but inside the folder's while cycle, this way you get all the folders name, URLs and with all it's files names and URLs, always use parallel loading when using this, in most cases the servlet will take some time to parse all this data.

6.- getSize(): Get's the number of bytes used to store this folder in Drive, in case you need to calculate loads.

Here is a very basic script to call the servlet from your HTML, for testing purposes the prefix it's set to "alert" so the data will be displayed on a pop-up as soon as it loads. For real-life applications change the "alert" prefix to the name of the Javascript function responsible for parsing the JSON, I also recommend
using AngularJS to handle parallel data loading when calling different servlets.


The HTML already includes the URL of a fully working servlet, feel free to use it for testing, but before you can use it, you need to grant access to the servlet, this is a 1 time requirement and it's done by manually calling the servlet's URL:

https://script.google.com/macros/s/AKfycbyixGlm9VJb9RuK_1ZYbsLrduuee4RX2v27mzKvtiFiTm5WaKRK/exec

Stay tuned for articles with more advanced uses of this approach, feel free to post your ideas, comments or suggestions.

Happy coding!

August 23, 2013

How to backup your FirebaseDB on Google Drive using Apps Script!




I've recently started using Firebase, and I've got to say that it's pretty awesome! Especially if you use AngularJS as your front-end you can start making live Apps in minutes, and thanks to Google Drive HTML hosting you don't even need to waste time looking for a place to host everything.

I really recommend trying the example "Wire up a Backend" found on the home page of the AngularJS project.You won't believe at first that "that was it", it's so fast and easy that I'm sure you will think that there is something else to do before it starts actually working.

Firebase can do a great job as a Live Data back-end, but it's not very appropriate for historical records for a few reasons:

* Storing static backups takes too much space, and it should be used wisely (the free 100 Mb quota can run out quickly if you are not careful).

* Downloading all the data every time you want to make a report consumes a lot of bandwidth quota, especially when you call many backups to make a time graph with Google Charts.

* It's best to save those precious connections, since those comes with a price too if you exceed the free 50 concurrent connections quota.

So, instead, it's best to save a backup of your precious Firebase Data on a safe place, Firebase already  has a button that let's you save a backup of the interface anytime you want... and that's good! but let's make it great by storing it automatically on a specific folder using the date as the file name. Google Drive's free quota it's more than large enough for millions of backups on most applications, no bandwidth limits and it can hold up to 10 requests per second/user, and they give 10,000,000 free requests a day... So feel free to let users query and make those cool graphs all they want from Drive.This way you use only 1 connection, for a very short time and you only need 1 download (usually once a day) to get a copy of your data.

So, how do you communicate both services? Well, using Firebase with Google Apps Script it's a piece of cake thanks to Firebase's REST API, Apps Script URL Fetch Service and Apps Script DocsList Service, let's see how simple it is:


Since Firebase's REST API allows us to get a copy of the DB with a simple URL, we can use it to get all the information directly via URLFetch, in this example we simply store the text inside a specific Google Drive folder, but its also possible to parse and pass the data to ScriptDB, Spreadsheets, Charts, Gmail, etc.

So give it a try, you don't even need to make the example to try this, you can register to Firebase and manually create a DB and some dummy data to work with, Firebase Web interface it's extremely easy to use so you won't have any problems with this.

Promising huh? well, if you want to do some serious data processing, you can use Bigquery or Fusion tables to put all that data together and watch how it evolves through time, also, if anything ever goes wrong, simply upload your most recent backup from drive, Firebase makes this very easy giving an "Import JSON" option.

Looking for a way to communicate your brand-new and super-cool Firebase live DB with your client's "traditional" web server?, you can use Apps Script XML Service, Apps Script JDBC Service, or pass them to ScriptDB and to have a frozen copy that responds to GET or POST requests via Apps Script Content Service, this one it's very usefull to make Charts on web pages using Google Charts Javascript API and some JSONP.

Just keep in mind when you are working with Firebase to be very carefull with your quotas (they are meant to last a month), and use whatever technique you find appropriate to reduce data consumption.

Feel free to let us know your ideas and opinions about this platforms at the bottom of this article and stay tuned for more articles about this great technology combo.

Happy coding!

July 26, 2013

How to send data to Spreadsheets using Apps Script UI.

@reicek

One really cool thing about Google Spreadsheets is that you can effectively use them as an extremely user-friendly cloud Data Base for your WebApps.

Unlike a normal Data Base, spreadsheets can pre-process the information it receives and automatically keep calculated values updated (like total, averages, etc...) they are extremely flexible and with proper planning they can be a great alternative in small-medium applications.

Tip: You can programmatically create new spreadsheets to keep the information light and organized (remember Spreadsheets has a limit quota of about 400,000 cells), its like having a new Database each week/quarter/month. You can even have an extra one that keeps the totals for each year (storing only totals taken from smaller Spreadsheets), and on top of that, a "Global" one that keeps the totals of all the yearly ones... And by being stored that way, creating reports and charts its very easy.

Extra tip: For the "Central" Databases, use Spreadsheets for simple Data, Fusion for advanced central data or Big Query if you need fast processing on very, very large amounts of data.

The easiest way to store and administer the information flow to a Spreadsheet its via Apps Script, and the easiest way to send information to Apps Script it's using UI services. For more advanced applications I suggest the use of servlets, which are basically small Apps Script programs acting as very specialized servers to query, process and deliver specific data to and from your Webapp (using the Content Services) or even JDBC-compliant data base (Google Cloud SQL, MySQL, Microsoft SQL Server, Oracle, étc.) using Jdbc Services, you can call it a "trusted-robot-in-the-middle" approach to make things easier and faster.

Advanced Professional Tip: Properly using Servlets along with your usual JDBC-compliant Database it's extremely useful since it lets you greatly improve performance because Apps Script Servlets has fast, direct access to all Google Services and once authorized, they don't need to deal with oAuth every time they make a request, which is very convenient. Also, when Google makes updates, you don't need to update your server's code to regain functionality, only the servlet and you can do that from virtually any modern browser (even some mobiles!). Also it's easy to identify the servlet that needs updating. Since the output from the servlet will remain constant through time (any text array like JSON or a binary blob), you don't need to worry about updating your servers code. Also, all this parallel processing will greatly reduce the load on your server, saving you a lot of money on hardware and bandwidth. Additionally, Google Spreadsheets, if published, can provide direct RSS or ATOM feed.

So, first let's Manually create a Spreadsheet, for this example I created one called "spreadsheetDatabase" and then I set it's access to "public on the web" so it gets a public URL, you can be more restrictive and allow only specific users to interact with the spreadsheet. For now, you only need the "Key-ID" of the spreadsheet, you get it from the URL in your browser while you have it open, in our example, the key is the part highlighted in red.

https://docs.google.com/spreadsheet/ccc?key=0AvRClkFMLkcpdDZ4VHlGd016cTQ1dUo4LXVaenhYSWc#gid=0

Now we need to pre-fill the spreadsheet with the name of the fields we want to use, it's not necessary for the script to work, but will make your Spreadsheet DB as readable as any normal spreadsheet, it can also be used to automatically apply headers to charts and reports based on the Spreadsheet. For our example we will only need a field for "name" and a field for "comment", its a best practice to delete all the unused rows and columns from your spreadsheet, so it stays as short as possible. Our example will look like this:


So far no sweat right? Ok, then let's hit the code!

So first things first, you need to create a new Google Apps Script project. In it, we are going to need 2 functions, one that's going to create and deliver the Webapp's U.I. and another one to send the data to Google Spreadsheets.

Let's start with the U.I, for this we are going to be using Google Apps Script U.I. Services, our code will look like this:


Note that sendData it's the name we choose for the function() that we will use to send our data to our spreadsheets, let's see how it looks for our example:


Now let me explain a little more about what's going on that last piece of code... First the e you see on sendData(e) is called an event object, we use it to pass information from one function to another.

We start with the .insertRowAfter() method to add a new row to the sheet (so we can keep it always using the exact number of cells we need).

Then we use the .appendRow() method to insert the data carried by the event object (e) data into the new row.

Then we open a Popup telling the user that the information has been sent, this is very important both, for the user to confirm that the information was sent, and secondly to give the Spreadsheet time to process properly the new row.

Important Note:  In this scenario, Spreadsheets are not very good at handling multiple insertions at the same time, ScriptDB and (and JSON) it's a better alternative as described on this other article.

Now let's see it all together:


Tip:  To save you the trouble later, go to File -> Upgrade authorization experience...

Now let's give it a first run so it get's your authorization to access Spreadsheets.

And finally it's time to deploy the app, to do so go to: Publish -> Deploy as Webapp...


Since it's the first time, you are going to need to Save a new version (you can give it any name you like, tip: try to be descriptive with your version names).

Then you need to say the identity the app its going to use when making requests, in this case it need to me as me so the information is sent on my name (and with my permissions!), if you choose that the App is run as the User accessing the app then the spreadsheet will either need to be publicly editable, or only users with edit rights could use the Webapp, pretty convenient huh?

And last but definitely not least, we need to set up who has access to the app, Only myself works great for private apps and beta testing, Anyone means that any user with a Google Account can use the App, this is important if you need to know the user's identity or if your App requires to act on behalf of the other user and finally, Anyone, even anonymous in this case the App will need to run as you to get access rights to Google Services (or you can use a publicly editable spreadsheet).

When you hit the Deploy button you'll get 2 different URLs, the Current webapp URL which is the published version of your webapp, this shows the code saved under the Project Version tag, and a special developer link were it says: Test web app for your latest code, which runs the current version of your script code, this way you can make (and save) changes to the code, and once you get the desired behaviour, you save a new version and change the published version.

The user's will get an instant update of the code when you change the published version! Something went wrong with the latest update to your code? Don't worry, you can always go back to a previous version until you make the necessary changes to the code and save a new version. If necessary, you also get a special link to disable the Webapp, so you can quickly plug it on and off if necessary.

And now its finally time for our first run! Let's take a look at it:


It's probably not so flashy, but it works like a charm, plus you can always use HTML services (for advanced users) or embed the Webapp on a Google Site to add some styling.

Why don't you try out our example and leave me a comment? Here you can see the spreadsheet that stores all the data, remember it gets updated every 5 minutes, so feel free come back later to see your comment on this post!


Remember that besides the embeddable iframe you saw before, Spreadsheets can also be served as (click on the name to launch that versions feed!):









So, I hope you liked using Spreadsheets as Database with Apps Script, feel free to post your doubts, comments, ideas, etc. at the bottom of this article.

Happy Coding!

April 5, 2013

How to parse ScriptDB JSON data into Spreadsheets


Using ScriptDB JSON data is very handy in many scenarios, specially when you need to avoid accidental overwriting when there are two or more instances trying to use the same data.

In "How to share/store Spreadsheeds as JSON data with ScriptDB!" I talked about how to populate your ScriptDB with a Spreadsheet parsed into flat JSON, now let's explore how to put that JSON data back into a Spreadsheet, and this can be done either manually for things like creating an Up-to-this-moment report, or programmatically, so you can keep only your most recent and fast-changing data in ScriptDB and keep a very well organized and readable backups inside Spreadsheets.

Let's take a look at our example Spreadsheet (it's the same one as in the previous article):



You can read an example about how to parse your ScriptDB JSON data into a new sheet in the documentation, so let's use it with a few adjustments so that every time you call the script, it dumps the data inside a sheet whose name is the date of such backup. This is very handy if you plan to use automated reports, doing it manually is very useful for things like "closing" a working shift of a Point of Sales, don't forget to empty the ScriptDB's contents in this scenarios after the data is safe inside the sheet.

Now its time to create a new script, let's get a look at our code:



Everytime we run our script, a new sheet (with the date as name) will be created. Our ScriptDB JSON data looks like this:

{"price":5,"name":"Razor blade","salesToday":0,"onStorage":50}
{"price":2.5,"name":"Toothbrush","salesToday":0,"onStorage":100}
{"price":3,"name":"Liquid Soap","salesToday":0,"onStorage":80}
{"price":3.7,"name":"Shampoo","salesToday":0,"onStorage":80}
{"price":2,"name":"Toothpaste","salesToday":0,"onStorage":150}

And once it's inside a new sheet, it will look like this:



Do note that the order of the rows and/or columns might be different from the original table, so plan your reports accordingly.

Feel free to let us know about your ideas, suggestions, requests, etc. at the bottom of this article.

Happy coding!

April 4, 2013

How to share/store Spreadsheeds as JSON data with ScriptDB!


There are many cases were we want to share data between many Apps, and one of the most popular ways it's to use Google Spreadsheets as a Central DB, and they do a great job on letting you share, download and access the Database in a very human way, but most of the time we want to efficiently query Data, but with Spreadsheets you need to know which cell has your data, filter using the visualization API or do some parsing... this makes it heavy and slow on large Data sets opposed to ScriptDB who is great for querying specific data!

Another limitation of using Spreadsheets is that they are not very good for handling shared accumulators, it's prone to over-writing when two or more users are working with the same cell at the same time, let's imagine the cell's current value its 3, and both client's add a +1, the cell's value its likely to end up as a 4 instead of 5... To prevent this ScriptDB has 2 different kinds of "locks", one public and one private, the difference is that public only allows 1 instance of the APP to run at any given time and the private lock only allows each USER to run 1 instance of the App at any given time.

Each script project get's a "sandboxed" ScriptDB for it's own use, meaning it's isolated from the rest of the users data and other ScriptDB instances from the same user. But were it really shines it's when you use a single ScriptDB for many Apps as a share point, you just need to create a tiny Apps Script webapp and share it as a library to get shared access to it's ScriptDB... not shiny enough? well, you can create many specific ScriptDBs to make everything safer, and organized by simply creating different library's and calling them as needed (creating different library's allows you to limit specific user's access) ... not enough? well, ScriptDB can be easily transferred to a Spreadsheet for a much more readable long term storage of our data. With some careful planning you can make smart data handling that's its fast, efficient and la piece de resistance... it's all free!

So, which are the limits of ScriptDB? According to the Documentation, they are actually  large enough for most cases, the quotas are per-user (so the limit is shared across all user's Apps, or in the case of the library, it goes against the owner of the library) and it depends on the kind of user:

> 50MB for consumer accounts.
> 100MB for Google Apps accounts
> 200MB for Google Apps for Business/Education/Government accounts.

Since it's all Text data wrapped inside JSON objects, this can be quite a lot of data, even for 50MB. So we are usually more limited to the query limits (default 200, maximum 50,000) and the time limit for an Apps Script instance (maximum 6 minutes processing time), in most cases it's a good idea to dump all the ScriptDB's contents inside an Apps Script sheet or sheets for more comfortable future reference and to avoid saturating the ScriptDB's query's responses.

Also keep in mind that ScriptDB it's specially useful with current and fast changing data, and Spreadsheets its better for long-term storage and for making automatic reports. In most scenarios the best approach it's to create a Sheet everyday with the Date as a name and dump the ScriptDB content on it... Also you can start a new Spreadsheet every month, all automatically and, if done properly, you will end up with a Database that your customers will love for being cheap, fast, flexible and the automatic reports are a great plus (you can even send a custom report via e-mail every time ScriptDB is dumped inside a Sheet).

Without more preamble, let's hit the code! We'll start by creating a Library that returns a ScriptDB instance that can be shared between different apps, create a new script and you only need this 3 simple lines of code!

To use this script as a library, remember you need to write down the script's project key, to get it, go to File - > Project properties.


If you plan to share access to this library with other users, remember to set the "Sharing Settings" which can be found in File - > Share...

To import your library, create (or open) a new Apps Script project and go to Resources - > Manage Libraries and write you Library's project key, inside the "Find a library" box.



Now, it's time to put some JSON data inside our library's ScriptDB! in most cases, we want to get our data from a Spreadsheet either because the Data is already on one, or simply because it is easier to write, as an example let's use the following spreadsheet:

The Apps Script code needed to do this, can be found on this part of the documentation, let's see a copy (with a few modifications):



This will make a flat JSON version of our Spreadsheet inside our shared ScriptDB! Flat JSON is very easy to work with, and remember you can put it back or make a copy in a Spreadsheet at any time.

There is a example code in the documentation to make a quick-check of your ScriptDB content, just create a new script with the following code:



Now you can see the ScriptDB's content by checking the Apps Script Log, our example spreadsheet data would look like this:

{"price":5,"name":"Razor blade","salesToday":0,"onStorage":50}
{"price":2.5,"name":"Toothbrush","salesToday":0,"onStorage":100}
{"price":3,"name":"Liquid Soap","salesToday":0,"onStorage":80}
{"price":3.7,"name":"Shampoo","salesToday":0,"onStorage":80}
{"price":2,"name":"Toothpaste","salesToday":0,"onStorage":150}


Feel free to let us know about your ideas, suggestions, requests, etc at the bottom of this article.


Happy coding!

March 16, 2013

Insights about ScriptDB


ScriptDB it's a great way to store and share JSON data for your Apps Script web apps! It's fast, free, flexible, and also provides plenty storage for most cases.

Let's start by pointing out ScriptDB's performance... inserting, updating and deleting data it's very fast and the time basically depends on the amount of objects we are working with regardless of the overall Database size, being consistent in performance from start and until you fill out your quota makes it suitable for many applications were other approach (like querying data from a large Spreadsheet) are just too slow.

ScriptDB does has a quota (limit), and it's set per user, so the quota space is shared by ALL your web apps. However, it is possible to connect to other user's ScriptDB by sharing Script DB libraries.

ScriptDB's query and storage it's quite flexible for storing and retrieving data from your DataBase. You find data by querying a specific subset of the JSON objects and it has methods that resembles the logical AND, OR and NOT, comparison operators and even facilitates sorting and pagination of the results, all this to allow you to adjust the output to your code's needs.

It also allows you to do the results iterations in many ways, and the one you choose mostly depends on your code's needs and your personal style. It has the  next() & hasnext() methods if you like using While loops or you can use the result.getSize() method if you prefer the For loops.

One last thing I'd like to mention about ScriptDB is it has something called "locks" which are used mostly for certain transactions were you don't want two instances running at the same time (to avoid over-writing) like in accumulators. There are two kinds of locks, public and private. In short, the difference is that public only allows 1 instance of the APP to run at any given time and the private lock only allows each USER to run 1 instance of the App at any given time.

Feel free to post your ideas, suggestions, requests, etc at the bottom of this article.

Happy coding!

February 26, 2013

How to integrate Google Charts, Apps Script JSONP, Spreadsheets & Drive hosted HTML/JS



First things first, it's very easy to draw Charts in your public HTML using the Google Visualization API for Javascript, you can even get help with the code using the Code Playground of the Visualization API, and usually we want to get our data from some Google Spreadsheet, piece of cake...

But things get nasty when you want to use all that juicy flexibility and the data comes from different sources and/or it's "heavy" data that requires local filtering and/or parsing (or simply way too big)... The code get's too large for comfort and too heavy on processor and therefore won't run smoothly on most devices/networks, plus it's a pain to debug or update...

Simply try placing many charts and query data like specific strings and numbers (from the Visualization API) to build some super-cool auto-report on a webpage and it WILL get slow on most devices, plus it will expose all your precious algorithms, code and even some of the structure of your (or your client's) data, even if they don't have the proper OAuth token and Google Account rights to see the actual data, they can get a lot of information just by looking at the public code... And nobody wants any of this (except some curious hackers and opportunist crackers).

Ok, ok.... so what changes with Apps Script? How does it help me to solve all this?. Well, let's mention some of the good stuff:

  • Apps Script handles the query's to Spreadsheets and deliver exactly the data you need ready to visualize inside a Chart, and it does it very fast. 
  • You can leverage client-side broadband/processor needs. 
  • You don't expose the code in the servlets! Nor your keys or ID's, also you can choose who can use the servlet, this all greatly enhance security and privacy. 
  • Different charts needs different views of the data and they all usually need some parsing, you can create one Apps Scipt servlet for each chart, this will make your pre-processing run in parallel on the server side! 
  • You can create one (or many if you handle too much data) servlets to query pieces of specific data like names, values, etc. and pack all that information inside a JSONP object that can be easily broken apart with Javascript to distribute the values across your HTML report page, put some CSS3 in the mix and you can code some nice reports. 
  • Apps Script has far better integration with Google APIs than Javascript plus you code from a cloud editor, so you don't need to install anything, and you enjoy of thing like auto-complete. 
  • You can publish some Scripts as Webapps and use them as library's so you can recycle code and debug/update faster (and safer using the versions systems). 
  • You can easily use/change different data feeds, BigQuery, Cloud Storage, Script DB, etc. without touching the HTML and once it's ready, you just change the version and it will be reflected on your sites instantly. 
  • Google Apps Script, Charts, Visualization API, Spreadsheets, hosting HTML/JS/CSS3, etc. it's FREE. 



Quite a bit right? and one could mention a few more, but this are the "highlights" in my opinion...

Let's build an example, to keep it "simple" the source will be the most copies sold top 10 SNES games

First we are going to need the data inside a Google Spreadsheet, and we only need the Key of the Spreadsheet for the servlet, this one correspond the the example we will be using:
0AvRClkFMLkcpdGcyWW1xNm83MzlRNXJZS21WSWR3ZUE

Note. For your own spreadsheet to work properly, don't forget to "Publish to the web"

Now let's create a JSONP servlet to query that data and prepare it (if you are not familiar with delivering JSONP content with Google Apps Script maybe you should consider reading this article first).

To prepare data for charts using GAS JSONP servlets, it's best to pack it using Literal Object Notation, it might be tricky to get right at first, but it's much more flexible since it allows you to use the new Data Roles which helps you to create very customized charts, also the visualization engine process Literal Object Notation faster (on the client side) than other 
methods effectively placing most processing work on the server side so you can process in parallel the data you need for the charts before passing it your HTML (feel free to read more about the JavaScript Literal Initializer for Google Charts in the documentation here and here).

First let's take a look at how our example Spreadsheet would look like once it's transformed into Literal Object notation:


{
cols: [
{id: "null", label: "SNES Game", type: "string"},
{id: "null", label: "Copies sold", type: "string"}
],
rows: [
{c:[{v: "Donkey Kong Country"},{v: "9000000"}]},
{c:[{v: "Donkey Kong Country 2"},{v: "4370000"}]},
{c:[{v: "Killer Instinct"},{v: "3200000"}]},
{c:[{v: "Star Fox"},{v: "4000000"}]},
{c:[{v: "Street Fighter II"},{v: "6300000"}]},
{c:[{v: "Street Fighter II Turbo"},{v: "4100000"}]},
{c:[{v: "Super Mario Kart"},{v: "8000000"}]},
{c:[{v: "Super Mario World"},{v: "20600000"}]},
{c:[{v: "Super Mario World 2"},{v: "4000000"}]},
{c:[{v: "The Legend of Zelda"},{v: "4610000"}]}
]
}


After looking at it, one notices that it will require to be parsed in two different parts, one for cols (which contains the column names) and another for rows (which contains the data inside the cells of each row).


First let's build the code for what I like to call the "canvas" of the Object Literal Notation along with the data we are going to need for the parsing jobs:

function doGet(request) {
 var ss = SpreadsheetApp.openById('0AvRClkFMLkcpdGcyWW1xNm83MzlRNXJZS21WSWR3ZUE');
 
 var data = ss.getSheetByName('SNES top 10');
 var columnsContent = [];
 var rowsContent = [];
 var columnsNumber = data.getLastColumn();
 var rowsNumber = data.getLastRow();
 
 return ContentService.createTextOutput(
   request.parameters.prefix + '({ cols: [' + columnsContent + '], rows: [' + rowsContent + '] })')
   .setMimeType(ContentService.MimeType.JSON);
}


This would parse the following output (the "canvas" for Object Literal Notation):

undefined({ cols: [], rows: [] })

Now let's build the code for parsing the cols:


// Columns
for (var i = 1; i <= columnsNumber; i++) {
var columnContent = [];
columnContent = '{id: "null", label: "' + data.getRange(1, i).getValue() + '", type: "string"}';
columnsContent.push(columnContent);

}


This would parse the following output for our example:


{id: "null", label: "SNES Game", type: "string"},
{id: "null", label: "Copies sold", type: "string"}


Now let's build the code for parsing the rows:






// Rows
 for (var i = 2; i <= rowsNumber; i++) {
   var rowObjects = [];
   for (var j = 1; j <= columnsNumber; j++) {
     var cellContent = [];
     var cellContent = '{v: "' +  data.getRange(i, j).getValue() + '"}';
     rowObjects.push(cellContent);
   }
   var rowContent = [];
   rowContent = '{c:[' + rowObjects + ']}';
   rowsContent.push(rowContent);
 }


This would parse the following output for our example:

{c:[{v: "Donkey Kong Country"},{v: "9000000"}]},
{c:[{v: "Donkey Kong Country 2"},{v: "4370000"}]},
{c:[{v: "Killer Instinct"},{v: "3200000"}]},
{c:[{v: "Star Fox"},{v: "4000000"}]},
{c:[{v: "Street Fighter II"},{v: "6300000"}]},
{c:[{v: "Street Fighter II Turbo"},{v: "4100000"}]},

{c:[{v: "Super Mario Kart"},{v: "8000000"}]},
{c:[{v: "Super Mario World"},{v: "20600000"}]},
{c:[{v: "Super Mario World 2"},{v: "4000000"}]},
{c:[{v: "The Legend of Zelda"},{v: "4610000"}]}


Now let's put it all together and see how it looks: 


function doGet(request) {
var ss = SpreadsheetApp.openById('0AvRClkFMLkcpdGcyWW1xNm83MzlRNXJZS21WSWR3ZUE');
 var data = ss.getSheetByName('SNES top 10');
 var columnsContent = [];
 var rowsContent = [];
 var columnsNumber = data.getLastColumn();
 var rowsNumber = data.getLastRow();

// Columns
 for (var i = 1; i <= columnsNumber; i++) {
var columnContent = [];
columnContent = '{id: "null", label: "' + data.getRange(1, i).getValue() + '", type: "string"}';
columnsContent.push(columnContent);
 }

// Rows
 for (var i = 2; i <= rowsNumber; i++) {
   var rowObjects = [];
   for (var j = 1; j <= columnsNumber; j++) {
     var cellContent = [];
     var cellContent = '{v: "' +  data.getRange(i, j).getValue() + '"}';
     rowObjects.push(cellContent);
   }
   var rowContent = [];
   rowContent = '{c:[' + rowObjects + ']}';
   rowsContent.push(rowContent);
 }

 return ContentService.createTextOutput(
   request.parameters.prefix + '({ cols: [' + columnsContent + '], rows: [' + rowsContent + '] })')
   .setMimeType(ContentService.MimeType.JSON);
}


And that's it! You can check the output of our example if you click on it's published link:

https://script.google.com/macros/s/AKfycbwFbraExcWCt9dBWdG2th8M_AaBXY_YJEli7pFYVDytxPRcUYGg/exec

Since the Google Visualization API supports Object Literal Notation natively, there is no need for parsing, just pass the data to a function and put it inside a DataTable for charts to draw, for example:

Javascript:


function OLNtoChart(OLNdata){
var data = new google.visualization.DataTable(OLNdata);
var tableChart = new google.visualization.Table(document.getElementById('tableChart'));
tableChart.draw(data, {showRowNumber: true});
}


HTML:

<id="tableChart"></>
<script type="text/javascript" src="https://script.google.com/macros/s/AKfycbwFbraExcWCt9dBWdG2th8M_AaBXY_YJEli7pFYVDytxPRcUYGg/exec?prefix=OLNtoChart"></script>


You can check how to draw more interesting charts in the Google Charts webpage. Feel free to post your ideas, suggestions, requests, etc at the bottom of this article.


Here you can see a fully working example published on Google Drive HTML hosting:



Happy coding!