【问题标题】:Print a div using javascript in angularJS single page application在 angularJS 单页应用程序中使用 javascript 打印 div
【发布时间】:2014-04-07 00:38:02
【问题描述】:

我有一个使用 angularJS 的单页 Web 应用程序。我需要打印某个页面的 div。 我尝试了以下方法:

页面包含几个 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>

控制器有以下脚本:

$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;
}

此代码打印所需的 div,但存在问题。 声明 document.body.innerHTML = originalContents; 替换了整个应用程序的主体,因为它是一个 SPA。所以当我刷新页面或再次点击打印按钮时,页面的全部内容都会被删除。

【问题讨论】:

  • 请附上小提琴。

标签: javascript angularjs html printing single-page-application


【解决方案1】:

需要两个条件函数:一个用于 Google Chrome,另一个用于其余浏览器。

$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;
}

【讨论】:

  • 为什么会有onbeforeunloadoriginalContents?此外,您缺少 popupWin.document.write 行中的 &lt;/body&gt; 标记。
  • 非常感谢,只是一个未使用的变量:originalContents
【解决方案2】:

好吧,我可能有一些不同的方法。

我知道它并不适合所有人,但有人可能会觉得它有用。

对于那些不想创建新窗口的人,并且像我一样关心 css 样式,这是我想出的:

我将我的应用程序的视图包装到了额外的容器中,该容器在打印时被隐藏,并且还有一个额外的容器用于需要打印的内容,在打印时会显示出来。

以下工作示例:

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>
	

请注意,我知道这不是一个优雅的解决方案,它有几个缺点,但也有一些缺点:

  • 不需要弹出窗口
  • 保持 CSS 完整
  • 不会将整个页面存储到 var 中(无论出于何种原因,您都不想这样做)

好吧,无论你正在阅读这篇文章,祝你有美好的一天并继续编码:)

编辑:

如果适合你的情况,你可以实际使用:

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

而不是角度布尔值来选择您的打印和非打印内容

编辑:

更改了屏幕 css,因为在页面加载/刷新后第一次打印时显示:无中断打印。

visibility:hidden 方法到目前为止似乎有效。

【讨论】:

    【解决方案3】:

    我认为没有必要编写这么大的代码。

    我刚刚安装了 angular-print bower 包,一切准备就绪。

    只需将其注入模块中即可 使用预先构建的打印指令,有趣的是,如果您不想打印,也可以隐藏一些 div

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

    我的工作很棒。

    【讨论】:

    • 这没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,请提供don't require clarification from the asker 的答案。
    • 感谢您的建议,但我认为答案非常准确。它可以 100% 工作。
    • 也已经有一个和你的基本一样的答案了,所以你的这个帖子并没有添加什么新东西。我什至会说其他答案是无效的,因为它只是一个指向外部源的链接,这可能是题外话,如果该链接破坏了你的答案并且他们的答案都被破坏了,因为你的答案是链接。
    • 这很愚蠢
    【解决方案4】:

    这就是在 Chrome 和 Firefox 中对我有用的方法!这将打开小打印窗口,并在您单击打印后自动关闭。

    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();
    

    【讨论】:

      【解决方案5】:

      我是这样做的:

      $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();
      }
      

      【讨论】:

        【解决方案6】:
        $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();
        } 
        

        【讨论】:

        • 所有$http 在此之后请求刹车... :( 我也无法重新加载页面...只能将网址复制到新标签页...我不明白为什么。 .
        • 这里也一样,所有 $http 请求都会停止,但只有在我关闭新窗口时才会发生在 Chrome 上。 Firefox 或 IE 运行良好
        • 我找到了为什么这个解决方案不起作用,这是答案 - stackoverflow.com/questions/23071291/…
        • 为什么他得到 var originalContents = document.body.innerHTML;他不在任何地方使用 originalContents
        • 对于特定的div转换和下载为pdf文件有这样的功能吗?
        【解决方案7】:

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

        【讨论】:

        • 这个库在不断变化,我会小心在生产中使用它,直到一些问题得到解决
        • @G.Mart 貌似作者这个周末要推major release解决跨浏览器兼容性问题
        • 来自作者,3 天前:“是的,我真的很抱歉缺少多浏览器兼容性的更新。我预计本周末会发布一个支持 chrome、mozilla 和 safari 的新版本. Edge 将主要受支持,但可能仍有一两个错误。chrome、mozilla 和 safari。Edge 将主要受支持,但仍可能有一两个错误。"
        • 所以很遗憾没有引用 IE,edge 将是一个折腾。
        猜你喜欢
        • 1970-01-01
        • 2020-03-24
        • 2015-09-28
        • 2013-08-22
        • 1970-01-01
        • 2018-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多