Jquery、Js实现网页打印,及打印样式的自定义

时间:2024-04-05 14:38:18

本来今天准备继续更新webpack的内容的,但是上午修改了一下公司网站的代码,然后就开始研究网页打印的东西了,弄了一下午,搞的整个人都不好了。刚好也来讲一下一些收获,其实也不算什么收获,但是还是来跟大家分享一下。


window.print()



这个是实现网页打印的方法函数,其实针对网页打印,有几个应用场景;

  • 第一种情况,最简单的应用,就是单纯的打印网页的文本内容,没有样式什么的特别需求。
  • 第二种情况,就是根据项目要求,配合特定打印纸张的要求(例如A4纸、银行卡、质保卡、订单信息等),实现特定样式的打印

先来说一下,网站的打印方案有很多,但是讲到的都是第一种情况的打印实现,从我个人来说,作用不是很大,只是简单的介绍了怎样实现打印,但是我们的实际项目不可能说,单纯的把文本内容打印出来,既简单又丑陋。很多时候不论是客户还是公司来说,都希望你打印出来的东西跟你网页上,或者真实的打印单据的格式是一样的。

接下来我们开始讲我们的实现方案:

1、通常采用的是iframe打印方法,不管是实现局部,或者是实现整个页面的打印。当然,你的打印内容如果只是单纯页面上的内容,不需要通过数据交互获取数据之后再打印的除外。那我们先来将最简单的,就是你页面的单纯打印,这里分为整体打印局部打印。
不使用--iframe

整体打印-------直接调用方法就可以了
window.print();
  局部打印-------打印的时候,把需要打印的内容替换成整个body内容(用户会在打印的时候看到变化,用户体验不太好)
<body>

    <!--startprint1-->
    <div id="printBody">

    </div>
    <!--endprint1-->
</body>
JS
<script type="text/javascript">
    var bdhtml;
        sprnstr;
        eprnstr;
        prnhtml;
    bdhtml=window.document.body.innerHTML;//获取当前页的html代码
    sprnstr="<!--startprint1-->";//设置打印开始区域
    eprnstr="<!--endprint1-->";//设置打印结束区域
    prnhtml=bdhtml.substring(bdhtml.indexOf(sprnstr)+18); //从开始代码向后取html
    prnhtml=prnhtml.substring(0,prnhtml.indexOf(eprnstr));//从结束代码向前取html
    window.document.body.innerHTML=prnhtml;
    window.print();
</script>


使用--iframe

   我非常不推荐上面的方法,他只是在你最简单的需求下才可以使用。说下为什么不推荐,上面的方法有几个坑,页面打印过后 会导致页面上所有的按钮,标签等绑定的事件都失效,这个你怕不怕;还有就是毕竟打印的是页面的一部分,看着不清楚也不 方便维护;而且如果是在页面上只有在需要的时候才调出来(例如事先隐藏起来,等到打印的时候再调用出来)有可能会导致 你整个页面样式的崩溃。

好了,转入正题,首先先要在所在的页面中放一个Iframe标签。记住宽和高都是0,这样不会对你的页面有丝毫的影响。
页面1(是需要调用到打印的页面
<body style="text-align: center">

<button type="button" id="printBtn">打印</button>

<iframe frameborder="0" src="" id="printFrame" style="width: 0;height: 0;"></iframe>

<script type="text/javascript" src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
    $("#printBtn").click(function () {
        $("#printFrame").attr('src','./printIframe.html');
    })
</script>
</body>

页面2(printIframe.html页面)
<!DOCTYPE html>
<html lang="en" style="height: 100%">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css" media="print">
        html{
            height: 100%;
            width: 100%;
        }
    </style>
</head>
<body style="padding: 0;margin: 0;height: 100%;width: 100%;">
    <div id="printBody" style="width: 100%;height: 100%;">

    </div>


<script type="text/javascript" src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
    var pdata = [
        {"id":"productId","top":"95","left":"20"},
        {"id":"customer","top":"120","left":"80"},
        {"id":"dfadfa","top":"150","left":"50"}
    ]
    var infoHtml = '';
    for (var i = 0;i<pdata.length;i++){
        var top1 = (pdata[i].top/176)*100+'%';
        var left = (pdata[i].left/261)*100+'%';
        infoHtml += '<span style="display:block;position:absolute;top:'+top1+';left:'+left+';">'+pdata[i].id+'</span>';
    }
    $("#printBody").html(infoHtml);
    window.print();
</script>
</body>
</html>

讲一下,我的本次项目的要求是:打印质保卡,类似于银行卡大小,上面带有背景图案,并且显示相应信息。
      项目开始做了一下面的图片的页面(中间红色边框的背景图是先随意上传的,我们要实现的功能       就是和背景图一样的打印),复选框的选中与否代表着要显示在质保卡上的信息选项。然后出现       在红框内的选项字段是可以拖动的,拖动到确定位置之后,把信息保存下来作为将来打印的模       板。这部分保存的信息有(要显示的字段名称,其相对于红色框所在的位置,这里获取的是相对       于红色框的绝对定位位置,position为absolute的top和left值)。
Jquery、Js实现网页打印,及打印样式的自定义

下面的内容才是今天要讲到的主题,我们在printIframe.html中获取到数据(上面html中的pdata是假数据,跟真数据差不多),之前是直接拿到数据之后,在页面中按照绝对定位的px值进行定位,但是打印页面出来的想过不是预期的那样,我们想要的是上图红色框包含的样式。网页打印预览出来之后信息都出现在了左上角,并没有跟红色框所展现的那样进行布局。


这是因为,我们最初这是红色框的宽和高都是固定的为261px和176px,而打印网页是按照浏览器的window1大小的100%显示的,所以这里我们的打印页面的宽和高都是window的100%大小,所以我们这里的定位就不能直接用px只来定位了,应该用百分比来定位,之后这样才能让相应字段显示在相应位置。这里的一个核心思想就是,打印的布局样式要以打印窗口宽高的100%为基准来进行布局,通过计算出对应元素在页面中的百分比位置或者大小,才能够实现和局部样式一样的效果.