Blog

Integrating Microsoft Office Functionality into Your SharePoint Apps

Have you ever come across this snippet of JavaScript before?

try {
   xhr = new XMLHttpRequest();
} catch(e) {
   xhr = new ActiveXObject(ā€œMicrosoft.XMLHTTPā€);
}

If you havenā€™t then not to worry, itā€™s not really the point of this post anyway ā€“ but for the uninitiated this is a snippet of JavaScript that prepares an object that will be used to make an ajax request. Ajax is the mechanism by which a webpage can load more data from the server even after the page itself has finished loading, and you find it all over the place.

The reason I bring it up is because of the tryā€¦ catch construct involved. Essentially it tries to execute the code between the first set of curly braces, and if that fails then it executes the code between the second set instead. In the huge majority of cases the first line of code executes successfully, so why is the second line necessary?

Microsoft. And more specifically, Internet Explorer 6.

For anybody who makes things that live on the web, supporting Internet Explorer 6 is an absolute chore. It does things differently to other (read ā€œstandards complaintā€) browsers, and you end up having to create everything twice and put a bunch of hacks in place to make your site work with it. The block of code above is a prime example: every other browser has the XMLHttpRequest object built into their JavaScript implementation, but for Microsoft you have to use an ActiveX object instead.

More recent versions of Internet Explorer are much better in this regard, and these days frameworks like jQuery take care of any little annoyances like this that remain so itā€™s not as big a deal as it was a decade ago, but thatā€™s not the point of this post either.

The point is that ActiveX remains a part of Internet Explorer to this day, and despite the fact that many web programmers know it primarily as a result of the XMLHttp annoyance described above, it does have its uses. So letā€™s exploit it.

The Downside

If youā€™ve ever created web content then youā€™ll know the importance of standards compliance. Writing compliant markup and code helps to ensure that your site works in whatever browser software your end users happen to be using. Thatā€™s a good thing.

ActiveX exists only within Internet Explorer. If visitors to your SharePoint webapp are using another browser such as Chrome or Firefox then none of the following example code is going to work for them. The best weā€™ll be able to do is detect that it hasnā€™t worked and have our app react in an appropriate way, maybe with a warning message or something similar.

If we were creating something publicly accessible for consumption by a wide variety of internet users then this would be a deal breaker, but in the context of an app built atop SharePoint where all the users are within the four (physical or otherwise) walls of your organization? It might be fine. If your organization is like the one I work for then everybody is using Internet Explorer anyway, because thatā€™s the browser installed on your computer when IT deliver it, and getting them to install an alternative is like pulling teeth.

OK, So What is This ActiveX Thing?

Wikipedia sums it up pretty nicely, including condensing my previous three paragraphs down into a single sentence.

Many Microsoft Windows applications ā€” including many of those from Microsoft itself, such as Internet Explorer, Microsoft Office, Microsoft Visual Studio, and Windows Media Player ā€” use ActiveX controls to build their feature-set and also encapsulate their own functionality as ActiveX controls which can then be embedded into other applications. Internet Explorer also allows the embedding of ActiveX controls in web pages.

However, ActiveX will not work on all platforms, so using ActiveX controls to implement essential functionality of a web page restricts its usefulness.

In other words, one of the things we can use ActiveX for is to take the functionality of a Microsoft application and embed it into a web page. Iā€™m going to put together a fairly simple example, and Iā€™m going to use Excel. Letā€™s dive in!

The HTML

Iā€™m going to build a simple table in HTML. The data in the table could come from anywhere, such as a subset of some SharePoint-based dataset or other pulled together using some of the techniques weā€™ve looked at previously, or a script executed server-side if you have the ability to create such a thing. For the sake of simplicity though, Iā€™m just going to define in a static manner in my markup ā€“ and Iā€™m not going to worry about making it look good.

<table>
   <thead>
      <tr><th>Fruit</th><th>Qty</th></tr>
   </thead>
   <tbody>
      <tr><td>Bananas</td><td>5</td></tr>
      <tr><td>Apples</td><td>7</td></tr>
      <tr><td>Oranges</td><td>2</td></tr>
      <tr><td>Pears</td><td>3</td></tr>
   </tbody>
</table>

image

The Template

Next, Iā€™m going to define an excel template that weā€™ll use to place our data into. This could be as detailed or as simple as necessary, so for the purposes of example Iā€™ve gone with simple again. All Iā€™ve done in mine is put headings at the top of column A and B that match the headings in our HTML.

image

The JavaScript

OK, hereā€™s where the clever bit starts. The first thing weā€™re going to do is create an ActiveX object pointing to excel, and assign it to a variable so we can reference it again further along in the code.

var exApp = new ActiveXObject('Excel.Application');

Next weā€™re going to open a new document in excel, based upon our template. Doing this also returns an object that weā€™ll need again, so weā€™re going to assign this one to a variable too.

var exDoc = exApp.Workbooks.Add('http://192.168.1.102/web/template.xltx');

Itā€™s important to note here that we have to pass in an absolute reference to the template file ā€“ a relative reference is not sufficient because excel has no concept of the location of our webpage. In my test environment the SharePoint server is at 192.168.1.102, but this will undoubtedly be different for you.

At this point, excel is open and has our template loaded, so the next thing to do is iterate over the table in our HTML and plug the data into excel. In general, this is done with the following line of code:

exDoc.ActiveSheet.Cells(1, 1).Value = 'This is row 1, column 1!';

More specifically what weā€™re going to do is use our old friend jQuery to iterate over the table cells in our HTML page and put them into the right place in excel with the help of a couple of simple counter variables: one for the row weā€™re targeting, and one for the column. Donā€™t forget to include a reference to the jQuery library in the document <head> section.

r = 2;
$('table tbody tr').each(function() {
   c = 1;
   $(this).children().each(function() {
      exDoc.ActiveSheet.Cells(r, c).Value = $(this).html();
      c++;
   });
   r++;
});

While weā€™ve been preparing all this, the Excel window has been invisible to the user. The final step is to make it and its newly imported data appear.

exApp.Visible = true;

Done!

Putting it All Together

The full code of our HTML page is as follows:

<!DOCTYPE html>
<html>
<head>
   <title>Export to Excel Example</title>
   /web/js/jquery-1.11.0.min.js
   
      $(document).ready(function() {
         $('input#export').click(function() {
            var exApp = new ActiveXObject('Excel.Application');
            var exDoc = exApp.Workbooks.Add('http://192.168.1.102/web/template.xltx');

            r = 2;
            $('table tbody tr').each(function() {
               c = 1;
               $(this).children().each(function() {
                  exDoc.ActiveSheet.Cells(r, c).Value = $(this).html();
                  c++;
               });
               r++;
            });

            exApp.Visible = true;
         });
      });
   
</head>
<body>
   <table>
      <thead>
         <tr><th>Fruit</th><th>Qty</th></tr>
      </thead>
      <tbody>
         <tr><td>Bananas</td><td>5</td></tr>
         <tr><td>Apples</td><td>7</td></tr>
         <tr><td>Oranges</td><td>2</td></tr>
         <tr><td>Pears</td><td>3</td></tr>
      </tbody>
   </table>

   <input type="button" id="export" value="Export to Excel">
</body>
</html>

Taking it Further

What Iā€™ve put together here is a pretty simple example, but hopefully you can see the value in some of the possibilities this opens up. Getting complex data from a webapp into Excel is actually fairly straightforward.

With a more detailed template to export data into you could prepare webapp data for analysis in excel, create charts, etc, etc.

Enjoy!

Blog

Home Server Refresh

I get paid every other Thursday, or 26 times a year. That mostly means I get paid twice a month, but twice a year there’s a month where I get paid three times, and this is one of those months.

Since a big chunk of our expenses are monthly, getting paid three times in a month means I have some extra cash left over to play with, and this month I’m going to use it to replace our home server.

Above is our existing home server. It’s a pogoplug device that I’ve hacked to run debian linux. It’s primary function is as network attached storage for all the other devices in the house, and the box to its right is a 2tb USB hard-drive. It also runs a LAMP stack for development, and some torrent softwareĀ so it can handle downloading duties without any of the other computers in the house needing be kept on.

It only has 256mb of RAM though, and just occasionally if it’s under heavy load things fall down. The torrent daemon is usually the first victim: sometimes I go to check on the status of a download only to find that the downloading process has run out of resources and shut itself down.

My requirements for a replacement are that it handle all the tasks the existing server does – without the problems caused by the limited memory, uses electricity sparingly, and also gives me room to grow and try new things that I haven’t even thought of yet.

My plan is to replace it with a machine I build based on an Intel NUC.

This thing is a barebones machine (it doesn’t include any RAM or storage in the basic package), but it could be useful for many scenarios (I think it would make a great HTPC, for example) including mine.

I’m going to max it out with 8gb of RAM, and this 32-fold increase over what I have now should allow for a whole host of new possibilities.

I’m going to take advantage of the extra resources by attempting to install vSphere Hypervisor on it and split it into a number of virtual servers. One will be linux-based to replicate the functionality of the existing server, one Windows-based VM, and maybe two extra VMs (one linux, one Windows) so I can separate my playing around from mission-critical server duties.

I’ll be posting more as I work my way through the process.

Blog

Closing The Holes in my Digital Security

A little over three months ago I wrote a post on here called Overhauling My Digital Life, and in it I talked in some detail about two specific things I did to protect my data and my digital identity: enabling two-factor authentication everywhere I could, and signing up for an online file storage service for backup purposes.

These are both smart things to do and four months ago I wasn’t doing them. Doing smart things is, well, smart – but it’s probably secondary to what I’m going to write about today: how I’ve stopped doing two specific things that were just flat-out dumb. One of these has the potential to be a huge gotcha if, like me, you hadn’t taken a high enough level holistic view of your online security, so read on!

Passwords

How many different online services do you use where you’re required to sign in with a username and password? I wouldn’t be surprised if it’s in the hundreds for some of you reading this.

How many different passwords do you have? I wouldn’t be surprised if it was less than five, because I have some research findings from 2012 that tell me that’s the case: 54% of internet users have five passwords or less.

You see what I’m getting at here, right? Everyone is reusing the same password across multiple sites, even though we all probably already know that’s a bad idea. For example, Google is probably (I would like to think) tech-savvy enough to avoid the majority of hacking attempts and, even if somebody did manage to gain access to their servers I strongly suspect personal information like that is fairly well encrypted. Good. Can the same be said of that obscure forum on model aircraft you signed up for that one time because you wanted to ask a single question about the particular shade of red the RCAF painted their T-33’s in the mid-60s?

(Side note: I found some lively discussion on my off the wall example topic, if not a definitive answer, here).

Anyway, my point here is that if you use the same password on multiple sites and just one of those sites suffers a breach of security, then the attacker has your password and that’s that. The chain is only as strong as its weakest link.

But you knew that already, right? And you’re smart (like me!) so you use a different password for each site. Here’s the problem: I don’t know of a human being that can remember hundreds of genuinely different passwords. You probably cut the same corner I did – instead of remembering a common password, you remember a common pattern then somehow plug the name of the site you’re on into that pattern. Genius! Instant unique password.

Here’s the thing: this technique won’t cut it in this day and age. As the general populous becomes more savvy about this kind of stuff, password crackers have to keep up – and keep up they do.

The only secure password is the one you can’t remember.

What good is a password you can’t remember? Well, more than you’d think. Personally I’ve downloaded a piece of software called KeePass. It (or variants of it) is available for windows, linux, MacOS, Android, iPhone and others, and it stores a database of all my unique passwords. It has a built-in password generator for the creation of completely random and unique strong passwords, and it even has functions that will type them for me into the login page of a particular website.

Alternatives are available (LastPass is a popular one), but I chose KeePass specifically because it doesn’t store all my passwords in the cloud somewhere. The downside to this is that I’ve had to come up with a way to keep my password database synchronized across my devices on my own, but the upside is that there’s no online account storing every password I have that itself could potentially be hacked into.

There’s no perfect system here, but in my mind the bottom line is this: if your credentials are in the top 10% of the hardest for an attacker to figure out, it’s fairly likely that they won’t expend the effort on you. Once upon a time using a password pattern put you there, but today it doesn’t. You need to evolve.

Your Email at Your Own Domain

As the clichĆ© I sprouted a few paragraphs above says, a chain is only as strong as its weakest link. When it comes to passwords, there’s little doubt that your email account is a huge metaphorical pair of bolt cutters.

I may have taken the analogy too far, but my point is that if somebody has access to your email account then they can probably go and hit the “reset password” link on any number of sites and gain access to your other accounts.Ā Two-factor authentication is an essential addition to your email account for this reason, gmail and outlook.com both offer it, and if your provider doesn’t you should probably think about switching.

My primary email account is powered by gmail, and I’ve had two-factor authentication enabled there since just before I wrote my original article on it in April.

But there’s a problem.

My email address is not an @gmail.com one, it’s a custom one at my own domain. It looks great on my business cards, but it introduces another link in the chain, and I’m fairly sure that link is weaker than Google. In my case, that link is godaddy. If somebody were to gain access to my godaddy account, they could change my email configuration entirely, directing my mail away from the gmail server that usually handles it and pointing it somewhere else entirely. Worse, at the time of writing godaddy only supports two-factor authentication for customers in the U.S.

Wired.com has a great article on this very subject that goes into detail about how writer Mat Honan’s digital life was held ransom until he relinquished his attractive twitter handle: How Apple and Amazon Security Flaws Led to My Epic Hacking.

I’ve signed up for a secondary email address at outlook.com, using their standard @outlook.com suffix. I give my outlook email address to computers, and my gmail-powered custom email address to people. Aside from the added security, the secondary benefit here is that virtually all the spam I get ends up in my outlook mailbox, which I only ever sign in to if I need to reset a password somewhere.

I’m evolving.

Blog

Channel Your Inner Entrepreneur to Excel at Work

I came across this post on lifehacker last week. It’s by Lauren Berger, and the article she wrote is an accompaniment to her book Welcome to the Real World.

I wrote a blog post back in February that’s very similar to this: Be Your Own Boss (Without Quitting Your Job).

I wrote about it in the context of ROWE, my approach to work in a results only work environment, and why I have no desire (currently, at least) to quit and start a consultancy firm.

Lauren writes about the next link in the chain: how this mindset leads to powerful results and exceptional job performance. It’s worth a quick read.

Channel Your Inner Entrepreneur to Excel at Work