Jump to content

Recommended Posts

  • Moderators

Working on a component which involves printing.

I've used external libraries like jsPDF, which generate printable content and they generally work fine. They also have some drawbacks though. So this component is going to rely on the browsers native 'print' command to print a complete page/form, or part thereof.

1) The print command is tied to a window object (window.print), so the possible implementations are limited to manipulating either

  • the current window
  • an iFrame element, which encapsulates a window object
  • a new pop-up window (or new tab)

Just to try these out, button 1-3 in the code below correspond to these possible implementations. 

  var Button1 : TW3Button := TW3Button.Create(self);
  Button1.Caption := 'this window';
  Button1.OnClick := procedure(sender:TObject)
    var originalContents := browserapi.document.body.innerHTML;
    browserapi.document.body.innerHTML := SrcDoc;
    browserapi.document.body.innerHTML = originalContents;

  var Button2 : TW3Button := TW3Button.Create(self);
  Button2.Caption := 'iframe window';
  var IFrame1 := TW3IFrameHtmlElement.Create(self);
  Button2.OnClick := procedure(sender:TObject)
    IFrame1.handle.srcdoc := SrcDoc;

  var Button3 : TW3Button := TW3Button.Create(self);
  Button3.Caption := 'other window';
  Button3.OnClick := procedure(sender:TObject)
     var mywindow = window.open('', 'PRINT', 'height=400,width=600');
     mywindow.setTimeout(function(){ mywindow.print(); mywindow.close(); }, 1000);

//SrcDoc content : see below

All of these approaches work. However if printable content contains images or other sizable resources, the actual printing must be delayed until all these resources have been downloaded - so either preload or set an appropriate Timeout, as in Button3


2) Screen and print layout differ in a couple of aspects :

  • screens are continuous, paper is not and some elements like tables and images should not be cut in half over page breaks
  • readability of fonts is different on screens and print output
  • hints like blue links on webpages don't translate well to printing
  • many web page elements like menus should not appear on print
  • and more. A good overview is given in this article

A separate print stylesheet can handle some/most/all of these concerns. A generic print stylesheet based on @media print is included below. Probably not the solution for each and every situation, but it handles most of the aspects above

  var SrcDoc : string := #'
      <!DOCTYPE html>
        @media print {

        @page { margin: 2cm }

        body {
          font: 13pt Georgia, "Times New Roman", Times, serif;
          line-height: 1.3;
          background: #fff !important;
          color: #000;

        h1 {
          font-size: 24pt;

        h2, h3, h4 {
          font-size: 14pt;
          margin-top: 25px;

        a {
        blockquote {
          page-break-inside: avoid;
        h1, h2, h3, h4, h5, h6 { page-break-after:avoid;
          page-break-inside:avoid }
        img { page-break-inside:avoid;
          page-break-after:avoid; }
        table, pre { page-break-inside:avoid }
        ul, ol, dl  { page-break-before:avoid }

        a:link, a:visited, a {
          background: transparent;
          color: #520;
          font-weight: bold;
          text-decoration: underline;
          text-align: left;

        a {

        a[href^=http]:after {
          content:" <" attr(href) "> ";

        $a:after > img {
          content: "";

        article a[href^="#"]:after {
          content: "";

        a:not(:local-link):after {
          content:" <" attr(href) "> ";

        nav, .sidebar, .heading
          display: none;

        p, address, li, dt, dd, blockquote {
          font-size: 100%

        code, pre { font-family: "Courier New", Courier, mono}

        ul, ol {
          list-style: square; margin-left: 18pt;
          margin-bottom: 20pt;

        li {
          line-height: 1.6em;

      <CENTER><IMG SRC="res/logo.png"> </CENTER>
      <H1>Header H1</H1>
      <H2>Header H2</H2>
      <P><B>Bold paragraph</B>
      <BR><BR><B><I>This is a sentence with some length, longer than the iframe width,
      in bold italic.</I></B>

This generates a print preview in all major browsers, with options to set paper size, select printer, orientation etc.

see https://www.lynkfs.com/Experiments/ReportWriter/www/reportwriter.html

Next thing to tackle is scaling.



Link to post
Share on other sites
  • Moderators

update :

on Android (Chrome) only the iFrame solution works as expected :

  • Button1 (manipulating the main window object) prints the whole page rather than just the demo html
  • Button3 (popup window) results in a rendering error

see https://www.lynkfs.com/Experiments/ReportWriter/www/reportwriter.html

Going with the IFrame solution

Link to post
Share on other sites
  • Moderators

update 2 :

after some more testing on different platforms, the conclusion is that the window.print() method basically works on all platforms (Windows, MacOs, iOS, Android) and modern browsers (Chrome, FireFox, Safari), but only using the iFrame setup as mentioned in the prev. posts. The other methods may or may not work.

The main exception is Chrome and FireFox on iOS where window.print() doesn't work at all : apparently Apple does not allow printing from Chrome in iOS due to it's policy on using alternative browser engines.

These guys deserve a thumbs down, really



Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...