Working with client generated html

Introduction

Typically, ScriptX is used to print the whole of the document displayed in the current window or frame or a document downloaded from a server.

This sample illustrates the use of the PrintHTML() method to print 'snippets' of HTML or documents constructed using javascript on the client PC rather than a document retrieved from a server.

This can be useful in many scenarios where a 'small' document such as a label is to be printed, or perhaps a section from the displayed page and saves a round-trip to the server.

When the PrintHTML() method is used, headers, footers, papersize etc etc, i.e. all the usual formatting and presentation properties are used to print the given HTML 'snippet'/document:

Compatibility note

ScriptX 8 and ScriptX.Services have a new implementation of PrintHTML() that supports modern content. All the content on this page engage this new behaviour as it is the only mode supported by ScriptX.Services and for ScriptX.Addon the host document is in IE 11 edge mode.

The PrintHTML() method takes an argument of the document URL to print, if the protocol is 'html://' then the document content is included in-line.

So, for example:

factory.printing.PrintHTML(
    "html://<html><body><h1>Hello world</h1></body></html>"
    ,true);

PrintHTMLEx() is PrintHTML() with information

This sample uses the PrintHTMLEx() API as it provides for progress callbacks. The sample uses these to show the progress in the log window. The only difference between the APIs is the addition of the callback function and callback data.

Document snippets

The html to be printed can be dynamically assembled from content on the page so enabling printing of a 'selection' of the content.

This can be a much simpler and useful technique than programmatically setting a selection and then requesting that only the selected text is printed (this can be done with the SetPageRange method).

The above section is printed with the following code:

$("#btnPrintSnippet1").click(function () {
    let html = "<html><head></head><body>";
    html += document.getElementById("sectionToPrint").innerHTML;
    html += "</body></html>";
    MeadCo.ScriptX.Printing.PrintHTML("html://" + html, true);
});

and the problem is, as you will see, that the content is not styled using the style sheet as displayed on screen. It is styled using a browser default sheet.

External resources

There is no usable base URL for the dynamic document being printed (it is about:blank) so external resources must be specified by fully qualified urls or a <base /> element can be used in the <head /> section of the generated document.

The above sample can be extended to use the style sheets from this document, building new link elements to use the full url to the style sheet:

$("#btnPrintSnippetFQStyle").click(function () {
    let html = "<html><head>";
                    
    // get each used style sheet and reconstruct the link elements. browsers helpfully return
    // the full qualified url.
    document.querySelectorAll("link[rel='stylesheet']").forEach(link => {
        html += `<link rel='stylesheet' type='text/css' href='${link.href}' ${link.media ? `media="${link.media}" ` : "" }>`;
    });
                  
    html += "</head><body>";
    html += document.getElementById("sectionToPrint").innerHTML;
    html += "</body></html>";

    MeadCo.ScriptX.Printing.printHTML("html://" + html, false);
});

Alternatively, a base element could be defined in which case the link elements can be copied. The advantage of this method is that content with urls relative to the specified base, such as images will also now print correctly.

Document snippets with images

This section will also be included in the print.

  • A downloaded image file:

    ScriptX logo

  • The same image encoded and included in the page:

    ScriptX logo

$("#btnPrintSnippetWithBase").click(function () {
    let html = "<html><head>";
    const { protocol, hostname, port, pathname } = window.location;
    let base = `${protocol}//${hostname}${port ? `:${port}` : ''}${pathname}`;

    // get each used style sheet and copy the defining element
    // this relies on a <base> element for relative hrefs
    document.querySelectorAll("link[rel='stylesheet']").forEach(link => {
        html += link.outerHTML;
    });
                  
    // inline document styles can be included as well ...
    html += document.getElementById("docStyles").outerHTML;
                     
    html += "</head><body>";
    html += document.getElementById("sectionToPrint").innerHTML;
    html += "<hr />";
    html += document.getElementById("sectionToPrint2").outerHTML;
    html += "</body></html>";

    MeadCo.ScriptX.Printing.PrintHTML("html://" + html, false);
});

Activity log  ::