网页打印的通用方法之canvas转换篇
我们做网站,经常需要打印页面指定区域的内容,而网上关于这块的说法很多,各种各样的打印控件也不少。但许多打印方案都不怎么好,至少我不喜欢,要么封装复杂,要么难以维护。 之前写了一个通用打印方法,是基于网上的一个最简洁的打印插件,然后添加了自己的一些内容操作,能满足很多打印需求。 但现在开发环境越来越复杂,要求越来越苛刻,导致有些效果打印不出来,只好继续想办法。终于在网上发现了一个基于canvas的打印插件,终于彻底解决了所有的打印问题。 现在总结下来,以供参考:1.网上找的js打印插件
/** Version 2.4.0 Copyright (C) 2013* Tested in IE 11, FF 28.0 and Chrome 33.0.1750.154* No official support for other browsers, but will TRY to accommodate challenges in other browsers.* Example:* Print Button: <div id="print_button">Print</div>* Print Area : <div class="PrintArea" id="MyId" class="MyClass"> ... html ... </div>* Javascript : <script>* $("div#print_button").click(function(){* $("div.PrintArea").printArea( [OPTIONS] );* });* </script>* options are passed as json (example: {mode: "popup", popClose: false})** {OPTIONS} | [type] | (default), values | Explanation* --------- | --------- | ---------------------- | -----------* @mode | [string] | (iframe),popup | printable window is either iframe or browser popup* @popHt | [number] | (500) | popup window height* @popWd | [number] | (400) | popup window width* @popX | [number] | (500) | popup window screen X position* @popY | [number] | (500) | popup window screen Y position* @popTitle | [string] | ('') | popup window title element* @popClose | [boolean] | (false),true | popup window close after printing* @extraCss | [string] | ('') | comma separated list of extra css to include* @retainAttr | [string[]] | ["id","class","style"] | string array of attributes to retain for the containment area. (ie: id, style, class)* @standard | [string] | strict, loose, (html5) | Only for popup. For html 4.01, strict or loose document standard, or html 5 standard* @extraHead | [string] | ('') | comma separated list of extra elements to be appended to the head tag*/
(function($) {var counter = 0;var modes = { iframe : "iframe", popup : "popup" };var standards = { strict : "strict", loose : "loose", html5 : "html5" };var defaults = {mode : modes.iframe,standard : standards.html5,popHt : 500,popWd : 400,popX : 200,popY : 200,popTitle : '',popClose : false,extraCss : '',extraHead : '',retainAttr: ["id", "class", "style"]};var settings = {};//global settings$.fn.printArea = function( options ){$.extend( settings, defaults, options );counter++;var idPrefix = "printArea_";$( "[id^=" + idPrefix + "]" ).remove();settings.id = idPrefix + counter;var $printSource = $(this);var PrintAreaWindow = PrintArea.getPrintWindow();PrintArea.write( PrintAreaWindow.doc, $printSource );setTimeout( function () { PrintArea.print( PrintAreaWindow ); }, 1000 );};var PrintArea = {print : function( PAWindow ) {var paWindow = PAWindow.win;$(PAWindow.doc).ready(function(){paWindow.focus();paWindow.print();if ( settings.mode == modes.popup && settings.popClose )setTimeout(function() { paWindow.close(); }, 2000);});},write : function ( PADocument, $ele ) {PADocument.open();PADocument.write( PrintArea.docType() + "<html>" + PrintArea.getHead() + PrintArea.getBody( $ele ) + "</html>" );PADocument.close();},docType : function() {if ( settings.mode == modes.iframe ) return "";if ( settings.standard == standards.html5 ) return "<!DOCTYPE html>";var transitional = settings.standard == standards.loose ? " Transitional" : "";var dtd = settings.standard == standards.loose ? "loose" : "strict";return '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01' + transitional + '//EN" "/' + dtd + '.dtd">';},getHead : function() {var extraHead = "";var links = "";var styles = '';if ( settings.extraHead ) settings.extraHead.replace( /([^,]+)/g, function(m){ extraHead += m });$(document).find("link").filter(function () { // Requirement: <link> element MUST have rel="stylesheet" to be considered in print documentvar relAttr = $(this).attr("rel");return ($.type(relAttr) === 'undefined') == false && relAttr.toLowerCase() == 'stylesheet';}).filter(function () { // Include if media is undefined, empty, print or all var mediaAttr = $(this).attr("media");return $.type(mediaAttr) === 'undefined' || mediaAttr == "" || mediaAttr.toLowerCase() == 'print' || mediaAttr.toLowerCase() == 'all'}).each(function () {links += '<link type="text/css" rel="stylesheet" media="print" href="' + $(this).attr("href") + '" />';styles += '@import url("' + $(this).attr("href") + '") print;';});if ( settings.extraCss ) settings.extraCss.replace( /([^,\s]+)/g, function(m){ links += '<link type="text/css" rel="stylesheet" href="' + m + '">' });return '<head><title>' + settings.popTitle + '</title>' + extraHead + links + '<style type="text/css"> @media print{a:link:after {content: ""}}</style></head>';//return "<head><title>" + settings.popTitle + "</title>" + extraHead + links + "</head>";},getBody : function ( elements ) {var htm = "";var attrs = settings.retainAttr;elements.each(function() {var ele = PrintArea.getFormData( $(this) );var attributes = ""for ( var x = 0; x < attrs.length; x++ ){var eleAttr = $(ele).attr( attrs[x] );if ( eleAttr ) attributes += (attributes.length > 0 ? " ":"") + attrs[x] + "='" + eleAttr + "'";}htm += '<div ' + attributes + '>' + $(ele).html() + '</div>';});return "<body>" + htm + "</body>";},getFormData : function ( ele ) {var copy = ele.clone();var copiedInputs = $("input,select,textarea", copy);$("input,select,textarea", ele).each(function( i ){var typeInput = $(this).attr("type");if ($.type(typeInput) === 'undefined') typeInput = $(this).is("select") ? "select" : $(this).is("textarea") ? "textarea" : "";var copiedInput = copiedInputs.eq( i );if ( typeInput == "radio" || typeInput == "checkbox" ) copiedInput.attr( "checked", $(this).is(":checked") );else if ( typeInput == "text" ) copiedInput.attr( "value", $(this).val() );else if ( typeInput == "select" )$(this).find( "option" ).each( function( i ) {if ( $(this).is(":selected") ) $("option", copiedInput).eq( i ).attr( "selected", true );});else if ( typeInput == "textarea" ) copiedInput.text( $(this).val() );});return copy;},getPrintWindow : function () {switch ( settings.mode ){case modes.iframe :var f = new PrintArea.Iframe();return { win : f.contentWindow || f, doc : f.doc };case modes.popup :var p = new PrintArea.Popup();return { win : p, doc : p.doc };}},Iframe : function () {var frameId = settings.id;var iframeStyle = 'border:0;position:absolute;width:0px;height:0px;right:0px;top:0px;';var iframe;try{iframe = document.createElement('iframe');document.body.appendChild(iframe);$(iframe).attr({ style: iframeStyle, id: frameId, src: "#" + new Date().getTime() });iframe.doc = null;iframe.doc = iframe.contentDocument ? iframe.contentDocument : ( iframe.contentWindow ? iframe.contentWindow.document : iframe.document);}catch( e ) { throw e + ". iframes may not be supported in this browser."; }if ( iframe.doc == null ) throw "Cannot find document.";return iframe;},Popup : function () {var windowAttr = "location=yes,statusbar=no,directories=no,menubar=no,titlebar=no,toolbar=no,dependent=no";windowAttr += ",width=" + settings.popWd + ",height=" + settings.popHt;windowAttr += ",resizable=yes,screenX=" + settings.popX + ",screenY=" + settings.popY + ",personalbar=no,scrollbars=yes";var newWin = window.open( "", "_blank", windowAttr );newWin.doc = newWin.document;return newWin;}};
})(jQuery);
2. 打开,下载或引用html2canvas.js。也可以去我的资源下载页面下载:点击打开链接
3. 打印代码样例:
<div id="printArea">test print content</div>
<div id="printFrame"></div>
<script type="text/javascript">var printAreaDiv = document.getElementById('printArea'); //待打印区域dom对象html2canvas(printAreaDiv) //代入打印对象参数,生成canvas图形.then(function (canvas) {//返回canvas对象var dataUrl = canvas.toDataURL();//获取canvas对象图形的外部urlvar newImg = document.createElement("img");//创建img对象newImg.src = dataUrl;//将canvas图形url赋给img对象$('#printFrame').append(newImg).printArea();//打印img,注意不能直接打印img对象,需要包裹一层div$('#printFrame').html(''); //打印完毕释放包裹层内容(图像)});
</script>
是不是觉得超级简单
事实就是这么简单,因为别人都把工具做好了
发布评论