简体   繁体   English

在angularJS单页面应用程序中使用javascript打印div

[英]Print a div using javascript in angularJS single page application

I have a single page web application using angularJS. 我有一个使用angularJS的单页Web应用程序。 I need to print a div of certain page. 我需要打印某个页面的div。 I tried the following: 我尝试了以下方法:

The page contains few div (print.html) 该页面包含几个div(print.html)

<div>
  <div>
    Do not print
  </div>
  <div id="printable">
    Print this div
  </div>
  <button ng-click="printDiv('printableArea');">Print Div</button>
</div>

The controller has following script: 控制器有以下脚本:

$scope.printDiv = function(divName) {
    var printContents = document.getElementById(divName).innerHTML;
    var originalContents = document.body.innerHTML;        
    document.body.innerHTML = printContents;
    window.print();
    document.body.innerHTML = originalContents;
}

This code prints the desired div but there is a problem. 此代码打印所需的div但存在问题。 the statement document.body.innerHTML = originalContents; 声明document.body.innerHTML = originalContents; replaces the body of the whole application since it is a SPA. 因为它是SPA,所以取代了整个应用程序的主体。 So when I refresh the page or click on print button again, the whole content of the page is erased. 因此,当我刷新页面或再次单击打印按钮时,页面的整个内容都将被删除。

$scope.printDiv = function(divName) {
  var printContents = document.getElementById(divName).innerHTML;
  var popupWin = window.open('', '_blank', 'width=300,height=300');
  popupWin.document.open();
  popupWin.document.write('<html><head><link rel="stylesheet" type="text/css" href="style.css" /></head><body onload="window.print()">' + printContents + '</body></html>');
  popupWin.document.close();
} 

Two conditional functions are needed: one for Google Chrome, and a second for the remaining browsers. 需要两个条件函数:一个用于谷歌浏览器,另一个用于其余浏览器。

$scope.printDiv = function (divName) {

    var printContents = document.getElementById(divName).innerHTML; 

    if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
        var popupWin = window.open('', '_blank', 'width=600,height=600,scrollbars=no,menubar=no,toolbar=no,location=no,status=no,titlebar=no');
        popupWin.window.focus();
        popupWin.document.write('<!DOCTYPE html><html><head>' +
            '<link rel="stylesheet" type="text/css" href="style.css" />' +
            '</head><body onload="window.print()"><div class="reward-body">' + printContents + '</div></body></html>');
        popupWin.onbeforeunload = function (event) {
            popupWin.close();
            return '.\n';
        };
        popupWin.onabort = function (event) {
            popupWin.document.close();
            popupWin.close();
        }
    } else {
        var popupWin = window.open('', '_blank', 'width=800,height=600');
        popupWin.document.open();
        popupWin.document.write('<html><head><link rel="stylesheet" type="text/css" href="style.css" /></head><body onload="window.print()">' + printContents + '</body></html>');
        popupWin.document.close();
    }
    popupWin.document.close();

    return true;
}

您现在可以使用名为angular-print的库

I done this way: 我这样做了:

$scope.printDiv = function (div) {
  var docHead = document.head.outerHTML;
  var printContents = document.getElementById(div).outerHTML;
  var winAttr = "location=yes, statusbar=no, menubar=no, titlebar=no, toolbar=no,dependent=no, width=865, height=600, resizable=yes, screenX=200, screenY=200, personalbar=no, scrollbars=yes";

  var newWin = window.open("", "_blank", winAttr);
  var writeDoc = newWin.document;
  writeDoc.open();
  writeDoc.write('<!doctype html><html>' + docHead + '<body onLoad="window.print()">' + printContents + '</body></html>');
  writeDoc.close();
  newWin.focus();
}

This is what worked for me in Chrome and Firefox! 这对我和Chrome和Firefox都有用! This will open the little print window and close it automatically once you've clicked print. 这将打开小打印窗口,并在您单击打印后自动关闭它。

var printContents = document.getElementById('div-id-selector').innerHTML;
            var popupWin = window.open('', '_blank', 'width=800,height=800,scrollbars=no,menubar=no,toolbar=no,location=no,status=no,titlebar=no,top=50');
            popupWin.window.focus();
            popupWin.document.open();
            popupWin.document.write('<!DOCTYPE html><html><head><title>TITLE OF THE PRINT OUT</title>' 
                                    +'<link rel="stylesheet" type="text/css" href="app/directory/file.css" />' 
                                    +'</head><body onload="window.print(); window.close();"><div>' 
                                    + printContents + '</div></html>');
            popupWin.document.close();

Okay i might have some even different approach. 好吧,我可能会有一些甚至不同的方法。

I am aware that it won't suit everybody but nontheless someone might find it useful. 我知道它不适合所有人,但有人可能会觉得它很有用。

For those who do not want to pupup a new window, and like me, are concerned about css styles this is what i came up with: 对于那些不想创建一个新窗口的人,和我一样,关心css样式,这就是我想出的:

I wrapped view of my app into additional container, which is being hidden when printing and there is additional container for what needs to be printed which is shown when is printing. 我将我的应用程序的视图包装到另外的容器中,该容器在打印时被隐藏,并且还有用于打印时显示的需要打印的容器。

Below working example: 下面的工作示例:

 var app = angular.module('myApp', []); app.controller('myCtrl', function($scope) { $scope.people = [{ "id" : "000", "name" : "alfred" }, { "id" : "020", "name" : "robert" }, { "id" : "200", "name" : "me" }]; $scope.isPrinting = false; $scope.printElement = {}; $scope.printDiv = function(e) { console.log(e); $scope.printElement = e; $scope.isPrinting = true; //does not seem to work without toimeouts setTimeout(function(){ window.print(); },50); setTimeout(function(){ $scope.isPrinting = false; },50); }; }); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="myApp" ng-controller="myCtrl"> <div ng-show="isPrinting"> <p>Print me id: {{printElement.id}}</p> <p>Print me name: {{printElement.name}}</p> </div> <div ng-hide="isPrinting"> <!-- your actual application code --> <div ng-repeat="person in people"> <div ng-click="printDiv(person)">Print {{person.name}}</div> </div> </div> </div> 

Note that i am aware that this is not an elegant solution, and it has several drawbacks, but it has some ups as well: 请注意,我知道这不是一个优雅的解决方案,它有几个缺点,但它也有一些上升:

  • does not need a popup window 不需要弹出窗口
  • keeps the css intact 保持css完好无损
  • does not store your whole page into a var (for whatever reason you don't want to do it) 不会将您的整个页面存储到var中(无论出于何种原因您不想这样做)

Well, whoever you are reading this, have a nice day and keep coding :) 那么,无论你是谁,都有一个美好的一天,并继续编码:)

EDIT: 编辑:

If it suits your situation you can actually use: 如果它适合您的情况,您实际上可以使用:

@media print  { .noprint  { display: none; } }
@media screen { .noscreen { visibility: hidden; position: absolute; } }

instead of angular booleans to select your printing and non printing content 而不是角度布尔值来选择您的打印和非打印内容

EDIT: 编辑:

Changed the screen css because it appears that display:none breaks printiing when printing first time after a page load/refresh. 更改了屏幕css,因为看起来display:none在页面加载/刷新后第一次打印时打破了打印。

visibility:hidden approach seem to be working so far. 可见性:隐藏的方法似乎到目前为止工作。

I don't think there's any need of writing this much big codes. 我认为没有必要编写这么多大代码。

I've just installed angular-print bower package and all is set to go. 我刚刚安装了角度打印的凉亭包,一切都准备好了。

Just inject it in module and you're all set to go Use pre-built print directives & fun is that you can also hide some div if you don't want to print 只需将它注入模块就可以了。使用预先构建的打印指令和有趣的是,如果你不想打印,你也可以隐藏一些div

http://angular-js.in/angularprint/ http://angular-js.in/angularprint/

Mine is working awesome . 我的工作很棒。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM