views:

639

answers:

2

I want to write reusable code that takes an HTML table from a JSP and converts it to Excel format to be exported to the user. I want to take advantage of the HTML DOM Table Object rather than parse the HTML in Java to extract the same information. The biggest advantage to this would be inspecting each cell for checkboxes, buttons, etc. so as to remove them before writing the cells to Excel. In my mind the setup would go something like this:

HTML Table:

< a href="javascript: export();">Export to Excel< /a>
< table id="exportTable">
...
< /table>

JavaScript:

function export() {
var table = document.getElementById("exportTable");
// Send table object to Servlet somehow
}

The JavaScript would go in some sort of common.js so that the concept could be used on any table in any page of the site.

** UPDATE **

JSPs will be using Java objects to generate the table, but the table itself will be different every time. I'm looking for a generic solution whereby I can get the Table's DOM structure, thereby utilizing the table.rows and table.cells that is already done, inspect each cell to remove tags I don't want in the Excel (such as buttons, checkboxes, etc), and write that out to the user with the response type set to excel. Does that make more sense?

A: 

POST the table to the server. If you want to access the DOM like you would in JavaScript, you are going to need Rhino. But I recommend just sticking with something easier to drop in like JDOM. Then echo back the table with the content-type modified in the header to be "application/ms-excel".

geowa4
+1  A: 

I'd serialize the data from the cells into a simple JSON object, then use one of the many JSON libraries available on the Java-side to convert it back into a usable object.

Something like this:

function processTable(tableId) {
    var jsonTable = [];
    var tableObj = document.getElementById(tableId);
    if (tableObj) {
        for (var x=0, y=tableObj.rows.length; x < y; x++) {
            var tableRow = tableObj.rows[x];
            var jsonRow = [];
            for (var i=0, j=tableRow.cells.length; i < j; i++) {
                var tableCell = tableRow.cells[i];
                // removes any line feeds or tabs
                jsonRow.push(tableCell.innerHTML.replace(/\t|\n/g, ""));
            }
            jsonTable.push(jsonRow)
        }
    }
    return JSON.stringify(jsonTable);
}

This uses the Public Domain JSON.stringify() routine, available directly here.

You can now take this string, pass it to a server, and re-hydrate the object in Java-land. You'll get a multidimensional array of values corresponding directly to the contents of the table.

NOTE: This retrieves the entire table. If you just want to get the table's body, you'll have to modify the above code to iterate over the tBodies, like this:

function processTable(tableId) {
    var jsonTable = [];
    var tableObj = document.getElementById(tableId);
    if (tableObj) {
        for (var a=0, b=tableObj.tBodies.length; a < b; a++) {
            var tBody = tableObj.tBodies[a];
            for (var x=0, y=tBody.rows.length; x < y; x++) {
                var tableRow = tableObj.rows[x];
                var jsonRow = [];
                for (var i=0, j=tableRow.cells.length; i < j; i++) {
                    var tableCell = tableRow.cells[i];
                    // removes any line feeds or tabs
                    jsonRow.push(tableCell.innerHTML.replace(/\t|\n/g, ""));
                }
                jsonTable.push(jsonRow)
            }
        }
    }
    return JSON.stringify(jsonTable);
}
Civil Disobedient