Skill Level: Intermediate

Understanding of Javascript is recommended but not required

Uses a comma separated string to generate a CSV file that can be downloaded and opened in Excel.


BPM 8.5 or later (8.5.7 used in tutorial)

BPMUI toolkit

Chrome or firefox browser


  1. Introduction + Create a copy of the BPMUI button coach view

    While there are certain 3rd party javascript libraries that will let you generate an excel file on the fly, but sometimes they are not an option, or more often they leave copies on your server file system that later have to be cleaned up/maintained.

    This approach uses nothing but standard BPM libaries and javascript to create/download csv spreadsheets in the users browser, without the need to generate any server-side files.


    The first step is to make a copy of the BPMUI button as a base template. The easiest way to do this in your process app, is to find the BPMUI toolkit dependency in the left side menu, find the button object, right click, and copy into into current process app. This will create an identical button coach view, but one that is no longer read-only

  2. Edit the new coach view object

    Rename coach view to “Excel Download Button” or something similar. Just make sure the name is changed so we can tell it apart from the original object.

  3. Add new Variables

    Specifically, we need to add the 2 configuration variables shown below. The names need to be exact so that the later script that target them correctly. Setting the Group Name is optional, but it lets us find them easier later on.


  4. Update Behavior

    The next step is to add the code in red to the top of the existing Inline Javascript. The bpmext_control_initButton code should already be present, and should not be altered. It should be at the bottom so that our code runs first.



  5. (Optional) For those who like to copy paste (read warning first):

    –Before copying, be aware that developerworks converts ” characters for styling purposes. BPM will not recognize that¬†as a valid character and you will need to replace them with your own doublequotes to avoid errors—



    var _this=this;



    ¬† ¬†if(_this.context.options.fileContents.get(“value”)==null || _this.context.options.fileContents.get(“value”)==””)


    ¬† ¬†var fname=_this.context.options.fileName.get(“value”)+”.csv”;

    ¬† ¬†var fcontent=”data:text/csv;base64,”+btoa(_this.context.options.fileContents.get(“value”);

       var encodedUri=encodeURI(fcontent);

    ¬† ¬†var link=document.createElement(“a”);

    ¬† ¬†link.setAttribute(“href”, encodedUri);

    ¬† ¬†link.setAttribute(“download”,fname);




  6. (Optional) Javascript explained

    So this code does a number of different thing: primary verifying that we provided the script with a data string (fileContents), sticking it into an encoded data URI (beginning with data:text/), and then creating an invisible html anchor tag with the file information we think click programmatically. 


    Base64 was chosen as the prefered encoding because it works with both Chrome and Firefox for all the most common UTF-8 characters. One character that it didn’t work for as¬†(U+2019) which looks like¬†‚Äô. It looks a lot like ‘ or¬†(U+0027), but is not supported. so it is replaced in the last part of the fcontent assignment. There are other symbols that will likely cause similar issues, but this was the only one I encountered on a frequent basis.


    The a element (or anchor) is used instead of simply opening up the data URI in a new tab because by doing it this way we are able to set the “download” attribute and namethe file when it is downloaded.

  7. Next add the button to your coach

    Now that the coach view is created its time to hook it up:

    Drop it in just like any other button and then go into properties > configuration

    Here you can name the file (.csv is already added later), and bind it to the comma seperated string you want to download


  8. Final step:

    The final step, and important if you want the button to do anything, is to add this line of code to the Button’s onClick event:

    Since BPMUI, most script defined actions are cleared out when the button is created, and then overwritten with what is defined in the Properties > Events tab. The downside is we have to put something here everytime we define a new download button, or it will not have any onClick functionality. So to make our jobs easier we defined all that code we did before as a single function, which we call now as shown.



  9. Thing to be aware of


    The entire foundation of this approach is the Data URI we defined above.


    While data URIs are HTML standard, certain “default Microsoft” browsers may have issues. For the most part, the technique above should work for all modern browsers, but be aware that some can handle data URIs differently then others and could cause unexpected behavior. The javascript code will fail silently if at all, so worst case scenario nothing gets downloaded and you get a blurp in the browser javascript console. Just be sure to test your code in a number of different browsers before pushing to production to avoid any unwelcome surprises.


    The most common issue i’ve seen is if the fileContent string contains characters that cannot be base64 encoded, which is relatively rare if the user isn’t copying and pasting the input. If that does happen the encoding fails and nothing is downloaded. UTF-8 encoding was also tried as an alternative to base64, but in that case Firefox truncated any data with a ? character (still not entirely sure why).

Join The Discussion