[Ionic Tutorial] Print a current Page/Div with Css applied


#1

Hello,
in this tutorial I explain how you can print a Div/Page and so on in your Browser.

Features:

  • SVG Files Support
  • IMG Files Support
  • Background and Layers also Supported

So lets get started:


First of all you need this NPM Plugin: https://github.com/tsayen/dom-to-image
So do:

npm install dom-to-image

After that create a provider. We call it print-provider. So do:

ionic generate provider print

After that create a print function in your provider like this:

import { Injectable } from '@angular/core';
import domtoimage from 'dom-to-image';

@Injectable()
export class PrintProvider{
  constructor() {}

    print(componentName) {
      var node = document.getElementById(componentName);

      domtoimage.toPng(node)
      .then(function (dataUrl) {
          var popup=window.open();
            popup.document.write('<img src=' + dataUrl + '>');
            popup.document.close();
            popup.focus();
            popup.print();
            popup.close();
      })
      .catch(function (error) {
          console.error('oops, something went wrong!', error);
      });
    }
}

PS: As classname you can name it whatever you want.
So for now your print provider is ready. So then go into your .ts file where you want to print something. I.E. home.ts.

Import your provider like this:

import { PrintProvider} from "../../providers/print/print";

Initialize it in the constructor like this:

constructor(public navCtrl: NavController,
    ...
    private printService: PrintProvider) { }

PS: Be sure to use the same className as in your provider.
Now create a print function like this in your home.ts:

  print(componentName) {
    this.printService.print(componentName);
  }

and finally in your .html file create a button to trigger the print function and a div with content in it which you want to print. In example we put a printer button in the header of the html and a list with the id=“tablelist”.

<ion-header>
  <ion-navbar>
    <button ion-button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title>HomePage</ion-title>
    <ion-buttons end>
      <button ion-button (click)="print('tablelist')">
        <ion-icon name="print"></ion-icon>
      </button>
    </ion-buttons>
  </ion-navbar>
</ion-header>

<ion-content>
  <ion-list id="tablelist">
    <ion-item>
     //some content here
    </ion-item>
  </ion-list>
</ion-content>

So how does it work?
The print button gives the parameter(id of the listview) to the print function in home.ts. This print function gives the parameter to the provider and the provider gets the list through the ID and converts it into a base64. The base64 gets printed in a new page as image and opens the print alert which ask the user how he want to save it.

Why do we use a provider?
Simply because you can now use this print function in every ts file you want.

GitHub Project:
Here is the full and free GitHub Project. Just download and compile it! :slight_smile:

Youtube Showcase:


Best way to print a current Page in WebBrowser
#2

Hi Luke thanks for this tutorial. I noticed in my Ionic app ionic window.print() does not exist, which causes issue with popup.print(). Do I need to include anything else to get window.print() to work?

Also I am having trouble importing dom-to-image the plugin into Ionic. I am trying to use this plugin in my Angular5/Ionic4. I’ve installed the plugin via npm:
npm install dom-to-image --save

I’ve imported plugin into my component:

import domtoimage from 'dom-to-image';

The issue is the app can’t locate/recognise the dom-to-image. In visual studio is shows up in a popup on the link as module ‘*’, meaning it can’t locate the plugin in node_modules. I’ve used and imported other third party plugins including lodash without any issues. My app’s package.json is below, does anyone know what might be the issue? Do I need do any extra steps because it is Ionic?

Appreciate any comments and experience you have on this. thanks in advance

{
  "name": "ourmgmt2-mobile",
  "version": "0.0.1",
  "author": "Ionic Framework",
  "homepage": "http://ionicframework.com/",
  "private": true,
  "scripts": {
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "ionic:build": "node --max-old-space-size=12288 ./node_modules/@ionic/app-scripts/bin/ionic-app-scripts.js build",
    "ionic:serve": "ionic-app-scripts serve"
  },
  "dependencies": {
    "@angular/common": "^5.2.10",
    "@angular/compiler": "^5.2.10",
    "@angular/compiler-cli": "^5.2.10",
    "@angular/core": "^5.2.10",
    "@angular/forms": "^5.2.10",
    "@angular/http": "^5.2.10",
    "@angular/platform-browser": "^5.2.10",
    "@angular/platform-browser-dynamic": "^5.2.10",
    "@angular/tsc-wrapped": "^4.4.7",
    "@auth0/angular-jwt": "^1.1.0",
    "@ionic-native/camera": "4.7.0",
    "@ionic-native/core": "4.7.0",
    "@ionic-native/file": "4.7.0",
    "@ionic-native/file-transfer": "4.7.0",
    "@ionic-native/in-app-browser": "4.7.0",
    "@ionic-native/splash-screen": "4.7.0",
    "@ionic-native/status-bar": "4.7.0",
    "@ionic/storage": "2.1.3",
    "@types/file-saver": "0.0.1",
    "@types/lodash": "^4.14.108",
    "angular2-jwt": "^0.2.3",
    "angular2-uuid": "^1.1.1",
    "aws-sdk": "^2.229.1",
    "blueimp-canvas-to-blob": "^3.14.0",
    "cordova-android": "^6.1.2",
    "cordova-ios": "~4.3.1",
    "cordova-plugin-add-swift-support": "^1.7.2",
    "cordova-plugin-camera": "^2.4.1",
    "cordova-plugin-compat": "^1.2.0",
    "cordova-plugin-console": "1.0.5",
    "cordova-plugin-device": "1.1.4",
    "cordova-plugin-file": "^5.0.0",
    "cordova-plugin-file-transfer": "^1.7.1",
    "cordova-plugin-inappbrowser": "^2.0.2",
    "cordova-plugin-ionic": "^2.0.4",
    "cordova-plugin-splashscreen": "~4.0.1",
    "cordova-plugin-statusbar": "2.2.1",
    "cordova-plugin-whitelist": "1.3.1",
    "cordova-sqlite-storage": "~2.0.3",
    "dom-to-image": "^2.6.0",
    "expr-eval": "^1.2.1",
    "file-saver": "^1.3.8",
    "ionic-angular": "^3.9.2",
    "ionic-plugin-keyboard": "~2.2.1",
    "ionicons": "3.0.0",
    "lodash": "^4.17.10",
    "moment": "^2.22.1",
    "ng-elastic": "^1.0.0-beta.5",
    "ng2-img-max": "^2.1.15",
    "rxjs": "5.5.2",
    "sw-toolbox": "3.6.0",
    "uuid": "^3.2.1",
    "zone.js": "0.8.18"
  },
  "devDependencies": {
    "@ionic/app-scripts": "3.1.9",
    "@types/node": "^8.10.10",
    "typescript": "^2.8.3"
  },
  "description": "An Ionic project",
  "cordova": {
    "platforms": [
      "android",
      "ios"
    ],
    "plugins": {
      "cordova-plugin-console": {},
      "cordova-plugin-device": {},
      "cordova-plugin-splashscreen": {},
      "cordova-plugin-statusbar": {},
      "cordova-plugin-whitelist": {},
      "cordova-sqlite-storage": {},
      "ionic-plugin-keyboard": {},
      "cordova-plugin-ionic": {
        "APP_ID": "bba80768",
        "CHANNEL_NAME": "Ch: Ourmgmt Staging",
        "UPDATE_METHOD": "background",
        "UPDATE_API": "https://api.ionicjs.com",
        "MAX_STORE": "2"
      },
      "cordova-plugin-file-transfer": {},
      "cordova-plugin-camera": {
        "CAMERA_USAGE_DESCRIPTION": " ",
        "PHOTOLIBRARY_USAGE_DESCRIPTION": " "
      },
      "cordova-plugin-inappbrowser": {}
    }
  }
}


#3

This is the correct way to import in current ionic:

import * as domtoimage from ‘dom-to-image’;