private final void writePage() throws SAXException {
        if (canvases.size() == 0) {
            return;
        }

        for (Map.Entry<String, List<GlyphRun>> e : canvases.entrySet()) {
            List<GlyphRun> runs = e.getValue();
            if (runs.size() == 0) {
                continue;
            }
            xhml.startElement(DIV, CLASS, CANVAS_SAX);
            //a list of rows sorted by the y of the first element in each row
            List<List<GlyphRun>> rows = buildRows(runs);
            for (List<GlyphRun> row : rows) {
                writeRow(row);
            }
            xhml.endElement(DIV);
        }
        //for now just dump the urls at the end of the page
        //At some point, we could link them back up to their
        //true anchor text.
        if (urls.size() > 0) {
            xhml.startElement(DIV, CLASS, URL_DIV);
            for (String u : urls) {
                xhml.startElement(A, HREF, u);
                xhml.characters(u);
                xhml.endElement(A);
            }
            xhml.endElement(DIV);
        }
        canvases.clear();
    }
Handles an individual page.  For now, this marks up
canvas entities in a &lt;div&gt; tag.  Based on the spec,
it currently relies on order within the xml for order of output
of text to xhtml.  We could do more complex processing of coordinates
for bidi-languages, but the spec implies that we should be able
to rely on storage order.
<p/>
As with our PDFParser, this currently dumps urls at the bottom of the page
and does not attempt to calculate the correct anchor text.
<p/>
TODO: integrate table markup
tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/ooxml/xps/XPSPageContentHandler.java