3

I have a GWT CellTable that gets populated using somewhat of a complicated and tedious process. I want the user to be able to print or export the data from that table.

I would rather not re-render the table contents for export since it is a tedious process.

How can I get the contents of all the rows from all the pages of my CellTable so I can put together a document for printing or export?

I'd be fine with a method of grabbing the actual HTML of the table, or an algorithm for iterating through and grabbing the rendered contents from cells. If someone has a better suggestion, that'd be appreciated as well.

Churro
  • 4,166
  • 3
  • 25
  • 26

4 Answers4

1

It seems there is no viable way to get the CellTable to give me the data for export without re-rendering contents. Since that would cost the same execution time as doing it myself, I resorted to rendering it myself. I used the following code to render HTML and display it in a new popup for printing. The print() method gets called from my Print button.

/**
 * Print in a new popup.
 * http://www.coderanch.com/t/564198/GWT/GWT-injecting-HTML-text-browser
 */
public static native void printHTMLString(String htmlString)/*-{
    var win = $wnd.open("_blank", "Print", "");
    win.document.open("text/html", "replace");
    win.document.write("<html><head></head><body>" + htmlString + "</body></html>");
    win.document.close();
    win.focus();
    var headID = win.document.getElementsByTagName("head")[0];
    var fileref = win.document.createElement("link");
    fileref.setAttribute("rel", "stylesheet");
    fileref.setAttribute("type", "text/css");
    fileref.setAttribute("href", "tables-min.css");
    headID.appendChild(fileref);
    win.print();
}-*/;

private void print() {
    //get the list from the ColumnSortHandler, so it keeps the sorting on the screen
    if (columnSortHandler.getList() == null || columnSortHandler.getList().isEmpty()) {
        Window.alert("Nothing to print");
        return;
    }

    SafeHtmlBuilder b = new SafeHtmlBuilder();
    b.appendHtmlConstant("<table class=\"pure-table\">"
            + "<thead><tr><th>Timestamp</th><th>Type</th><th>User</th>"
            + "<th>Screen</th><th>Client</th></tr></thead>");
    int count = 1;
    for (Record r : columnSortHandler.getList()) {
        b.appendHtmlConstant("<tr" + (count%2==0 ? ">" : " class='pure-table-odd'>"));

        b.appendHtmlConstant("<td>");
        b.appendEscaped(timestampFormat.format(timeStampColumn.getValue(r)));
        b.appendHtmlConstant("</td>");

        b.appendHtmlConstant("<td>");
        b.appendEscaped(typeColumn.getValue(r));
        b.appendHtmlConstant("</td>");

        b.appendHtmlConstant("<td>");
        b.appendEscaped(userColumn.getValue(r));
        b.appendHtmlConstant("</td>");

        b.appendHtmlConstant("<td>");
        b.appendEscaped(screenColumn.getValue(r));
        b.appendHtmlConstant("</td>");

        b.appendHtmlConstant("<td>");
        b.appendEscaped(clientColumn.getValue(r));
        b.appendHtmlConstant("</td>");


        b.appendHtmlConstant("</tr>");

        count++;
    }
    b.appendHtmlConstant("</table>");
    printHTMLString(b.toSafeHtml().asString());
}
Churro
  • 4,166
  • 3
  • 25
  • 26
1

To export XLS use the class below.

To print use gwt-print-it.

The class below do that without server side.

public class TableToExcel {
    public static final <T> void save(final CellTable<T> table, String filename) {
        final AnchorElement a = Document.get().createAnchorElement();
        a.setHref("data:application/vnd.ms-excel;base64," + base64(table.getElement().getString()));
        a.setPropertyString("download", (filename.endsWith(".xls") || filename.endsWith(".xlsx")) ? filename : filename + ".xls");

        Document.get().getBody().appendChild(a);
        Scheduler.get().scheduleEntry(new ScheduledCommand() {
            @Override
            public void execute() {
                click(a);
                a.removeFromParent();
            }
        });
    }

    private static native void click(Element elem) /*-{
        elem.click();
    }-*/;

    public static native String base64(String data) /*-{
        return btoa(data);
    }-*/;
}
Italo Borssatto
  • 15,044
  • 7
  • 62
  • 88
0

You can use getInnerHTML or getInnerText

for(int i=0; i<cellTable.getRowCount();i++)
{
    TableRowElement rowElement = cellTable.getRowElement(i);
    for(int j =0; j<rowElement.getCells().getLength(); j++)
    {
        //System.out.println( rowElement.getCells().getItem(j).getInnerHTML() );
        System.out.println( rowElement.getCells().getItem(j).getInnerText() );

    }       
}
Spiff
  • 3,873
  • 4
  • 25
  • 50
  • Hi, thanks for the answer. How about the data from the other pages? This gets the data from the currently visible page. – Churro Oct 31 '13 at 20:49
  • The data from other pages might not even be on the browser, and even if they were i don't see how you could get the rendered text of a page that has not been rendered. i guess you need to produce/render all the pages behind the scenes, and then for each page use the code above to get the rendered stuff. – Spiff Oct 31 '13 at 21:12
  • I was hoping there would be some way to iterate through the table's pages and grab the rows, but come to think of it, that would require the same amount of rendering. I will just use the column renderers to manually render the data for a printable page. Thank you for your help. – Churro Nov 01 '13 at 16:49
0

You could try the gwt-table-to-excel module.

The main point is that excel and other modern spreadsheet knows how to render an html table, so just open the dynamically built html table with the correct mime-type, and that's all.

I never used it, but the description sounds good.

Community
  • 1
  • 1
Akkusativobjekt
  • 2,005
  • 1
  • 21
  • 26
  • Hi, thanks for the answer. That lib does look good, but I see it requires passing the HTML of the entire table as a POST request. That doesn't look like a very viable solution. It also doesn't get all the pages of my table. It seems I would just have to re-render a printable page. – Churro Nov 01 '13 at 16:43