Tuesday 13 July 2010

Simple OOXML For OOXML SDK v 2.0 released

The goal of the Simple OOXML project has always been to create documents and spreadsheets using minimum resources, including a server environment. The library provides commonly used functionality whilst hides away the details of creating open xml documents and without a large performance overhead. Documents created with this library and the Open Office SDK can be viewed using Microsoft Excel/Microsoft Word or OpenOffice as well as any third party that supports the format.

 

Getting Started

Simple OOXML adds the DocumentFormat.OpenXml.Extensions namespace to version 2.0 of the Open Office SDK. It allows developers to create spreadsheets and documents either from scratch or using predefined templates. All functionality is represented by static functions for high performance tasks, or higher level wrapper functions can provide simpler code expressions with some minor performance loss. 

The following classes are provided:

  • SpreadsheetReader - manipulation of templates, retrieval of document parts, row and column reference functionality
  • SpreadsheetWriter - writing of document parts and creation of document level attributes. Add or remove spreadsheets.
  • SpreadsheetStyle - encapsulates font, border and fill handing in a spreadsheet.
  • WorsheetReader - retrieves cell and style information from a worksheet
  • WorksheetWriter - allows the pasting or insertion of data and style - using simple value types or DataTables - at a cell or range reference.
  • DocumentReader - retrieval of document templates.
  • DocumentWriter - pastes and saves text and text lists using predefined bookmarks.

Download the source files to view the source code, examples as well as a unit testing library which is a useful reference to all the features of the library. Users of the unsupported ExcelPackage library could consider using this library instead.

Simple OOXML is licensed under the LGPL. Requires .Net Framework 3.5 or later and can be downloaded from CodePlex.

Wednesday 19 May 2010

VS2010 The mappings for the solution could not be found

When trying to open a project with VS 2010 that used Visual SourceSafe, you may receive the following error:

The mappings for the solution could not be found

To fix this problem, go to Tools -> Options -> Source Control -> Plug-in Selection and change to the Visual Sourcesafe plugin from the TFS plugin.

Another reason to switch to svn ...

Monday 19 April 2010

Coming to a browser near you – HTML 5

Found this great web based slide show detailing the changes and additions that make up HTML 5.0

progress webworkers

http://apirocks.com/html5/html5.html#slide1

(Warning – not IE friendly)

Great comparison of web browser performance

 

Jason Gube at sixrevisions.com has posted a great article comparing browser performance. It pretty much echos day to day performance I’m seeing and backs up my decision to switch to Chrome.

Friday 9 April 2010

Hitting the thousand mark on stack overflow

The last few weeks have seen me actively participating in the community of programmer and pundits known as stackoverflow.com.

I set myself a target of reaching 1000 rep in two weeks and Im really glad to say I managed to do it in 11 days, thanks in part to a particularly feisty conversation about team participation vs individualism and how it relates to building and testing software.

My observations are that once a popular user (read user with high reputation or awards) replies to a question, most other users will jump on that band wagon. In practice, choosing other responses that are voted up even only once or twice may be more prudent.

Wednesday 24 February 2010

Javascript Localization using .Net Resource files and jQuery

As a web developer I'm shifting more and more code to the client, and a few weeks ago an interesting situation came up on a multi-lingual project. ie wanted to include translations for validation messages in jQuery code, but stay with the great .Net resource file model.
What I came up with was a pattern using JQuery AJAX and JSON to download the resource file to the browser. The translations are available using the same object notation available on the server eg
// -- Localisation --
var localResources;
var globalResources;

//Sample JSON for javascript resource values eg {TrackDetail:{HideHelp:"Hide Help", ShowHelp:"Show Help"}}
//Usage e.g: alert(localResources.TrackDetail.HideHelp);

//Load Localisation values into variables so that they can be available on the client
//Note that these values are loaded asynchronously, the code in the function will not run until the call has completed.
$.getJSON('Localisation.ashx?files=TrackDetail.aspx.resx&local=true', function(data) { localResources = data});
$.getJSON('Localisation.ashx?files=Errors.resx,Strings.resx', function(data) { globalResources = data});
The code on the server reads the local or global resource file and streams the contents back as a JSON formatted object. Note that I opted to roll my own JSON serialization code instead of using one of the built-in serializers.
Imports System.Web
Imports System.Web.Services
Imports System.Xml
Imports System.Resources
Imports System.Reflection

Public Class Localisation
  Implements System.Web.IHttpHandler

  Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
    Dim files As String = context.Request.QueryString("files")
    Dim local As String = context.Request.QueryString("local")
    Dim isLocal As Boolean
    Dim folder As String = "App_GlobalResources"
  
    context.Response.ContentType = "text/javascript"

    'Write out file as object
    context.Response.Write("{")

    'Determine if local resource file
    If local IsNot Nothing Then
      isLocal = CBool(local)
      If isLocal Then folder = "App_LocalResources"
    End If
    If files Is Nothing OrElse files.Length = 0 Then Throw New ArgumentException("Parameter 'files' was not provided in querystring.")
  
    Dim flag As Boolean = False
    For Each file As String In files.Split(",")
      If flag Then context.Response.Write(",")

      Dim className As String = file.Split(".")(0)
    
      'Write the class (name of the without any extensions) as the object
      context.Response.Write(className)
      context.Response.Write(":{")

      'Open the resx xml file
      Dim filePath As String = context.Server.MapPath("~\" & folder & "\" & file)
      Dim document As New XmlDocument()
      Dim flag2 As Boolean = False
      document.Load(filePath)

      Dim nodes As XmlNodeList = document.SelectNodes("//data")

      For Each node As XmlNode In nodes

        'Write out the comma seperator
        If flag2 Then context.Response.Write(",")

        Dim attr As XmlAttribute = node.Attributes("name")
        Dim resourceKey As String = attr.Value
        context.Response.Write(resourceKey)
        context.Response.Write(":""")

        'Write either the local or global value
        If isLocal Then
        context.Response.Write(HttpContext.GetLocalResourceObject(String.Format("~/{0}",    file.Replace(".resx", "")), resourceKey)) 'Has to be full path to the .aspx page
        Else
          context.Response.Write(HttpContext.GetGlobalResourceObject(className, resourceKey))
        End If
        context.Response.Write("""")

        'Flag that we need a comma seperator
        flag2 = True
      Next

      context.Response.Write("}")
      flag = True
    Next
  
    'End file
    context.Response.Write("}")
  End Sub

  Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
    Get
      Return True
    End Get
  End Property
End Class

Saturday 30 January 2010

jQuery, Google Closure and packing or minifying for performance?

One thing I love about writing jQuery plug-ins is that every line of code counts towards performance. Its like real programming again. There are lots of difference ways in which you can improve performance but one must have is reducing the size of the JavaScript that comes down the wire from the server.

There are two options to use when reducing JavaScript file size – packing and minifying. Packing uses a compression algorithm such as gzip to physical compress the file to it’s smallest possible size, whilst a decent minifyer removes whitespace, renames variables and internal functions and removes unreachable code.

A while ago I came across this post by John Resig pointing out that although packing reduces the file size, it takes longer to ultimately execute, due to the repeated unpacking process every time the script is used.

After reading this I started using the Yahoo YUI Compressor to minify all of my plug-ins, and it worked well, typically reducing file sizes by 70% or more.

Looking through the jQuery 1.4 release notes this week I noticed that the jQuery team have switched to Google Closure Compiler. This really is a great tool, for example it reduced my Exclusive Checkbox plug-in to only 191 211 bytes and the MapReduce plug-in to under 1k in size! You need to be careful when using the compiler with the advanced option (due to the possible renaming of public methods and variables), but this doesn't apply to plug-ins because of the use of a closure – perhaps this is the reason for the name of the compiler.

 Update   I had to abandon the use of the Advanced option for the Exclusive Checkbox plug-in, increasing the size from 191 to 211 bytes ...

Links:

Online YUI compressor
Online Google Closure compiler service

Thursday 28 January 2010

Simple OOXML Updated

Simple OOXML is a helper library that I wrote for the Open XML Format SDK 2.0 to make the creation of Open Office XML documents easier. You can modify or create any .docx or .xlsx document without Microsoft Word or Microsoft Excel or any other software (ideal for server environments).

Version 2.1.3678 has been released over at Codeplex which works with the December CTP of the SDK.

Batch conversion of docx files to pdf

I recently worked on a project where we had over 50 .docx files to convert to .pdf. Now Office 2007 can do this for you, but only one file at a time. Luckily I was able to piece together some code (.net 3.5 csharp) which automated this process. Select a folder and all .doc and .docx files in the folder and any subfolder will be converted to pdf and saved with a .pdf extension.

pdfbatch

You still need Office 2007 or later to do this – download the code here:

http://www.opencomponents.com/downloads/PDF Batch Converter.zip

Disclaimer: Use at own risk. No kittens were harmed during the making of this software.

Monday 25 January 2010

MapReduce plug-in Release Candidate now available

The MapReduce plug-in for jQuery has been uploaded to the following url:

http://plugins.jquery.com/project/MapReduce

The plug-in implements a a type of map/reduce algorithm that executes synchronously or asynchronously in the browse whilst minimising loss in performance. Supports long running operations without script timeout messages.

Add map and reduce functions using the $.map and $.reduce methods and execute the functions using the $.execute method. Nested map and reduce functions are supported.

The download contains two samples of finding the prime numbers in a sequence of numbers, one using a plain javascript function and one using map reduce to calculate this asynchronously without causing script timeout errors in the browser.

Options

The following options can be used when calling the $.execute method:

async: true or false - determines whether the $.execute method runs asynchronously (default false)
race: no of functions to call per iteration when async is true (default 100)
interval: interval in ms between iterations when async is true (default 1ms)

Saturday 23 January 2010

Introduction to Map Reduce using jQuery

(Solved: How to avoid the "A script on this page is causing Internet Explorer to run slowly." message)

When writing the spellayt spell checking plug-in, I came across an interesting problem with long running JavaScript code – the browser would timeout and display a message box to the user with the text "A script on this page is causing Internet Explorer to run slowly." Even worse, the dialog gives the user the option to cancel the script, potentially breaking your page.

The solution was to use a timer to simulate a background thread, but the solution wasn’t generic and felt far from elegant. This week, with the approval of Google’s Distributed MapReduce patent, I realised that a simpler non-distributed map reduce algorithm would enable the running of code both asynchronously and over long periods of time in JavaScript without complex state management and stack issues.

Map reduce works by taking key/value pairs and running them through a function to create intermediate key/value pairs until all the data has been processed (map). The data is then filtered (reduced) to obtain a result. Joel Spolsky (Joel on Software) has a nice article that explains the fundamentals behind map reduce.

Sieve of Eratosthenes

The Sieve of Eratosthenes is an algorithm for finding prime numbers, this Wikipedia article has a  visual explanation of how it works. Its a great example of something that is processor intensive but can be broken up into smaller steps.

A standard JavaScript implementation (using Euler’s optimisation) would look something like this:

function eratosthenesSieve(upperBound) {

   var upperBoundSquareRoot = Math.floor(Math.sqrt(upperBound), 0);
   var isComposite = [];

   for (var m = 2; m <= upperBoundSquareRoot; m++) {

      if (!isComposite[m]) {

         _primes.push(m);

         for(var k = m * m; k <= upperBound; k += m) {
            isComposite[k] = true;
         }
      }
   }

   for(m = upperBoundSquareRoot; m <= upperBound; m++) {
      if (!isComposite[m]) _primes.push(m);
   }
}

The isComposite variable contains an array of boolean indicating whether is element is prime (false) or not (true). The _primes array also contains the prime numbers.

Redefining the problem as a set of Map / Reduce functions

The great thing about map/reduce is that once the problem is defined as a set of functions, it doesn’t matter how the map/reduce is implemented, you should always get the same results. Usually, each for loop will result in a matching $.map or $.reduce function. Reorganising the eratosthenesSieve function to use map reduce requires the following steps:

  • Map an array containing the initial values – in this case the index of the array is the number we are testing, and a boolean will indicate whether it is a prime or composite number.
  • Map each prime up to the square root of the upper bound. For each Map that is a prime, strike out it’s square multiplied by the remaining numbers until the upper bound is reached.
  • Reduce the array by totalling the number of primes (false values) left.
  • Execute the functions to return the result.

The code now looks like this:

function eratosthenesSieve2(upperBound) {

   //Create an array of booleans representing prime = false
   var composites = new Array(upperBound);

   //Set all to prime (false) to start
   $.map(composites, function(index, value) {
      return false;
   });

   //Calculate the sqr root of the upper bound
   var upperBoundSquareRoot = Math.floor(Math.sqrt(upperBound), 0);

   //For each item, calculate the non primes
   $.map(composites, function(index, value) {

      if (index < 2 || index > upperBoundSquareRoot) return value;

      //If the array item is a prime then map all non primes
      if (value == false) {

         var k = index * index;

         $.map(composites, function(index2, value2) {

            if (index2 == k) {

               k += index;
               return true;
            }
            return value2;
         });
      }
      return value;
   });
                
   //Count only the primes
   $.reduce(composites, 0, function(index, value, result) {

      if (index >= 2 && value == false) result++;
      return result;
   });

   return $.execute();
}

The first $.map function initialises the composites array. The second and third map $.map strikes out multiples of primes. The $.reduce function counts the remaining primes by accumulating the result variable. Note the extra work we have to do to simulate the functionality of the for loop and when we haven’t performed any processing we return the same value that was passed into the function.

Finally, we $.execute the functions. If you attach a debugger to the script, you’ll notice the functions only start executing once this method is called.

Download the plug-in code from the Map Reduce plug-in page.

Next time, I’ll dive into the details of implementing the Map Reduce plug-in and the pitfalls encountered along the way.

Object Data Blocks 2.0 Release Candidate

 

Object Data Blocks is object persistence style ORM for new database implementations. Define you data layer using classes to define tables and fields and decorate them with attributes to define keys, indexes, constraints etc. A provider model for a specific relational database (currently sql server 2005 or later) takes care of the rest. Any changes to the assembly can be deployed at runtime seamlessly to the database without any loss of data.

Read more information and view code samples here.

Object Data Blocks is released under the GPL 2.0 licence and is hosted at http://objectdatablocks.codeplex.com