Using Base64 to create CSV out of a table

Using Element.toCSV and String.toBase64 you can dynamically create a window with CSV as the content.

HTML

<button id="go">Download CSV</button>
<table id="demo">
    <thead>
        <tr>
            <th axis="date" class="sortedASC">
                Date
            </th>
            <th axis="string" class="">
                Category
            </th>
            <th axis="string" class="">
                Receipt-Description
            </th>
            <th axis="number" class="number">
                Total w/ Tax
            </th>
            <th axis="number" class="number">
                Tax
            </th>
            <th axis="string" class="">
                Invoice
            </th>
            <th axis="string" class="">
                Client - Project
            </th>
            <th axis="string" class="">
                Account
            </th>
        </tr>
    </thead>
    <tbody>
            <tr rel="item:209" class="altRow" name="2009-03-04
                    Lodging
                     Fairfield Inn Chicago
                    110.88
                    
                    36
                    JoeTech 
                    1111 - WF Personal Credit">
                    <td>2009-03-04</td>
                    <td>Lodging</td>
                    <td class="file"><a class="file receipt" href="receipts/12345678/sc0000523a.pdf" target="_blank"></a> Fairfield Inn Chicago</td>
                    <td class="number">110.88</td>
                    <td class="number"></td>
                    <td class="file"><a class="file invoice" href="get_invoice.php?id=209" target="_blank"></a>36</td>
                    <td>JoeTech </td>
                    <td>1111 - WF Personal Credit</td>
                    </tr><tr rel="item:208" class="" name="2009-03-04
                    Rental Cars
                     Ace Rent-a-car Chicago
                    80.49
                    
                    36
                    JoeTech 
                    1111 - WF Personal Credit">
                    <td>2009-03-04</td>
                    <td>Rental...

CSS

table {
    border-collapse: collapse;
    border: solid 1px #ccc;
    font-family: helvetica, arial;
    margin-top: 20px;
    font-size: 10px;
}

td {
    border: solid 1px #ccc;
    padding: 2px 4px;
    white-space: nowrap;
}

JavaScript

window.addEvent('domready', function(){
    
    // convert the table data to CSV
    // then convert that to Base64
    
    var data = $('demo').toCSV('tbody > tr').toBase64();
    
    // open a new window with the data as the content
    $('go').addEvent('click', function(){
        window.open("data:attachment/csv;charset=utf-8;base64,"+data, "csvWindow", "width=400,height=300");
    });
    
});


(function(){
        
        // Base64 string methods taken from http://www.webtoolkit.info/
        var Base64 = {
            
            _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
            
            encode : function (input) {
                var output = "";
                var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
                var i = 0;
                input = Base64._utf8_encode(input);
                while (i < input.length) {
                    chr1 = input.charCodeAt(i++);
                    chr2 = input.charCodeAt(i++);
                    chr3 = input.charCodeAt(i++);
                    enc1 = chr1 >> 2;
                    enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                    enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                    enc4 = chr3 & 63;
                    if (isNaN(chr2)) {
                        enc3 = enc4 = 64;
                    } else if (isNaN(chr3)) {
                        enc4 = 64;
                    };
                    output = output +
                    this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
                        this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
                };
                return output;
            },

            decode : function (input) {
                var output = "";
                var chr1, chr2, chr3;
                var enc1, enc2, enc3, enc4;
                var i = 0;
                input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
                while (i < input.length) {
                 ...