Thursday, July 26, 2012

Creating SharePoint 2010 reports with Javascript and Twitter Bootstrap

SharePoint 2010 is a decent CMS out there from Microsoft.  Great for customized document storage, customized data lists, and of course Office Web Apps for cross-browser web based viewers/editors (word, excel, powerpoint, visio, etc).  SharePoint 2010 can also be extended to open source technologies rather easily with its REST services in order to create customized HTML reports rather than viewing through the clunky ribbon interface in SharePoint itself.

In this presentation, I will use NodeJS, Express, Jade, coffee-script, and Twitter's Bootstrap to construct a simple list report generator that page breaks on every item.  We will pretend that the SharePoint 2010 data is a custom list with three required columns and two optional columns that may not contain data:  Title (string), Content (rich text), and Feedback (rich text), TextArea1, TextArea2.  The last two are obviously the optional columns.

Imagine that this custom list contains a lot of text in each column.  Viewing this in SharePoint would show it as a grid, with each associated property listed horizontally (think spreadsheet).  There would be much scrolling or resizing of the browser.  Why cant we view this data like a book or a white paper?  That is what I intend to accomplish in this presentation.

First of all, you'll need to pick up all the tools.  I am using Node 0.8.3 with the following modules:  Express (3.0.0beta7), Jade (0.27.0), coffee-script (1.3.3), and request (2.9.203).  All of the modules are on npm.  See here for instructions on running coffee-script from the command line.

Next, pick up the latest bootstrap and its javascript plugins.  Finally go get jQuery.


$ mkdir reportGenerator
$ cd reportGenerator
$ mkdir public routes views



Now that we have our public folder, lets put the client side stuff in there.

$ mv ~/Downloads/bootstrap ./public
$ mv ~/Downloads/jQuery.min.js ./public/bootstrap/js


Lets setup our web server.

$ vim app.coffee
express = require 'express'
routes = require './routes'
http = require 'http'
app = express()
app.configure ()->
app.set 'port', (process.env.PORT or 3000)
app.set 'views', __dirname + '/views'
app.set 'view engine', 'jade'
app.use express.favicon()
app.use express.logger 'dev'
app.use express.bodyParser()
app.use express.methodOverride()
app.use express.cookieParser 'i sometimes like shrimp'
app.use express.session()
app.use app.router
app.use express.static __dirname + '/public'
app.configure 'development', ()->
app.use express.errorHandler()
app.get '/', routes.index
http.createServer(app).listen app.get('port'), ()->
console.log "Express server listening on port " + app.get('port')
view raw app.coffee hosted with ❤ by GitHub




Now we need to create the route app.coffee depends on.

$ vim ./routes/index.coffee
require 'coffee-script'
request = require 'request'
data =
getData: (cb)->
username = 'someUser'
password = 'somePassword'
proto = 'https://'
site = 'sharepoint.domain.com/_vti_bin/listdata.svc'
config =
url: proto + username + ':' + password + '@' + site + '/' + 'someList?$orderby=someColumn'
json: true
request config, (err, res, body)->
if err
console.log err
cb body.d.results
routes =
index: (req, res)->
data.getData (dataArray)->
options =
title: 'reportGenerator'
layout: 'layout.jade'
items: dataArray
res.render 'index', options
module.exports = routes
view raw index.coffee hosted with ❤ by GitHub



Cool.  So this route renders a Jade template.  Lets make the layout and index templates.

$ vim ./views/layout.jade
doctype 5
html
head
title= title
link(rel='stylesheet', href='/bootstrap/css/bootstrap.min.css')
script(src='/bootstrap/js/jquery-1.7.2.min.js', type='text/javascript')
script(src='/bootstrap/js/bootstrap.min.js', type='text/javascript')
body
block content
view raw layout.jade hosted with ❤ by GitHub


$ vim ./views/index.jade
extends layout
block content
for item in items
.container-fluid(style='page-break-after:always')
.well
.row-fluid
h2 #{item.Title}
hr
h5 Content:
p
!= item.Content
hr
h5 Feedback:
p
!= item.Feedback
hr
- if (item.TextArea1)
h5 TextArea1:
p
!= item.TextArea1
hr
- if (item.TextArea2)
h5 TextField2:
p
!= item.TextArea2
hr
view raw index.jade hosted with ❤ by GitHub




Now that the templates are done, we are ready to rock.  Start it up

$ coffee app.coffee

Print to PDF.  Look at that!  A nice report generated with page breaks on each main topic (item) based on SharePoint 2010 data in a simple yet expressive way.




No comments:

Post a Comment