HTML页面动态内容打印(文字、图片等)

由于开发框架使用jsp,所以本文以jsp做示例,其他框架遵循框架语法即可,底层都是通过调用浏览器组件打印html
思路:
  1. 需要触发打印的页面添加打印按钮(当然这是废话,从这里开个头吧),和一个iframe

<iframe id="print-cover-iframe" frameborder="0" style="display: none;"></iframe>
  1. 点击按钮时,动态设定当前iframe的src,使得iframe加载并渲染需要打印的html(所以本文讲的是动态获取html并打印,而非打印当前页面已有的一段html)

$("#btn_print").unbind("click").click(function() {
            console.log('点击打印');
            var url = '项目中需要打印的页面(我这里是前后端不分离的jsp,所以是后端的url会自动跳转到jsp页面),如果是前后端分离的,可以直接是html的页面路由';
            var  iframeId = 'print-cover-iframe';
            var  $iframe = $('#' + iframeId);
            $iframe.attr('src', url);

            $iframe.load(function() {
                var HTML = document.getElementById(iframeId);
                HTML.focus();
                HTML.contentWindow.print();
            });
        });
  1. 最后一步,也是最重要的一步:编写需要打印的页面,调起打印的页面样式设定还是有很多坑的,这里直接晒出jsp的页面(注:本文jsp页面是跳转前携带参数,接口分装参数并在jsp页面动态渲染的,前后端分离的项目,这个页面中可以在页面加载方法中触发动态绑定数据)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>

<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
<script src="${pageContext.request.contextPath}/back/angularJs/jquery-2.1.3.min.js" type="text/javascript"></script>
<script src="${pageContext.request.contextPath}/back/angularJs/jquery.qrcode.min.js" type="text/javascript"></script>
<head>
    <meta charset="UTF-8">
    <title>批量打印</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">

    <style type="text/css">
        .qrcode{
            <%--background: url('${ctx}/back/image/img_chaobiao.png')  no-repeat center center;--%>
            /*background-size:100% 100%;*/
            width: 92mm;
            height: 92mm;
            /*margin: 2mm;*/
            margin-left: 4mm;
            z-index: 8;
            position: relative;
            /*margin-top: 5mm;*/
            /*-webkit-print-color-adjust: exact;*/
        }
        .qrcode > img {
            object-fit: contain;
            width: 100%;
            height: 100%;
            position: absolute;
        }
        .qrcode-img{
            z-index: 10;
            top: 22mm;
            left: 23mm;
            /*height: 60mm;*/
            /*width: 55mm;*/
            position: absolute;
        }
        .qrcode-img > canvas{
            width: 42mm;
            height: 42mm;
        }
        .qrcode > img {
            object-fit: contain;
            width: 100%;
            height: 100%;
        }
        .background-img{
            /*position: absolute;*/
            z-index: 5;
        }

        .title-dev{
            /*width: 601px;*/
            /*height: 108px;*/
            overflow-wrap: break-word;
            color: white !important;
            font-family: PingFangSC-Medium;
            text-align: center;

            line-height: 10mm;
            margin-left: 27mm;
            margin-top: 20mm;
            z-index: 10;
            width: 40mm;
            position: absolute;
        }
        @media print {
            .collage_bg {
                background-color: #E6E7E9 !important;
                -webkit-print-color-adjust: exact;
            }
        }
        @media print {
            .print-padding {
                position: absolute;
                padding: 12% 8% 0 3.1%;
                z-index: 10;
            }
            .page-break{
                page-break-after:always;
            }
            .title-dev{
                color: #FFFFFFFF !important;
            }
            body {
                /*此样式可防止打印的字体、背景色与设定的不一样问题*/
                -webkit-print-color-adjust: exact;
            }
        }

        @page {
            margin-top: 0;
            margin-bottom: 0;
            size: portrait;/*(纵向)*/
        }

        #print_box {
            /*position: static;*/
        }

        .qrcode > img {
            /*position: absolute;*/
            z-index: 5;
            object-fit: contain;
            /*margin: 15px -40px;*/
        }

        .table {
            margin-bottom: 5px;
        }


        .box{
            display: flex;
            flex-wrap: wrap;
        }
        .item{
            align-self: auto;
        }

    </style>
</head>

<body>
<%-- 定义一个长度为6的数组,每6个二维码分一页 --%>
<%
    String[] str={"1","2","3","4","5","6"};
    request.setAttribute("str",str);
%>
<%-- 循环渲染二维码,每6个二维码分一页 ps:使用嵌套循环而不用判断当前index取模的方式是因为Edge等浏览器分页符需要在最外层标签才生效--%>
<c:forEach var="item" items="${qrCodes}" step="6" varStatus="status">
    <div class="box">
        <c:forEach items="${str}" var="s"  varStatus="intStatus">
            <c:if test="${(status.index + intStatus.index) < fn:length(qrCodes)}">
                <div class="item">
                    <div class="qrcode">
                        <img src="${ctx}/back/image/img_chaobiao.png" class="visible-print-block background-img"/>
                        <div class="qrcode-img print-padding" id="qrcode_${qrCodes[status.index + intStatus.index].id}"></div>
                        <div class="title-dev">${qrCodes[status.index + intStatus.index].qrCodeName}</div>
                    </div>
                </div>
            </c:if>
        </c:forEach>
    </div>
    <c:if test="${!status.last}">
        <div class="page-break"></div>
    </c:if>
</c:forEach>



<%--<div class="box">
    <c:forEach items="${qrCodes}" var="qrCode" varStatus="status">
        <div class="item">
            <div class="qrcode">
                <img src="${ctx}/back/image/img_chaobiao.png" class="visible-print-block background-img"/>
                <div class="qrcode-img print-padding" id="qrcode_${qrCode.id}"></div>
                <div class="title-dev">${qrCode.qrCodeName}</div>
            </div>
        </div>
        <c:if test="${status.count%6==0 && !status.last}">
            <div class="page-break"></div>
        </c:if>
    </c:forEach>
</div>--%>

<script type="text/javascript">
    <c:forEach var="item" items="${qrCodes}" varStatus="status">
        qrcode('qrcode_${item.id}','${item.id}');
    </c:forEach>

    function qrcode(id,content){
        $("#" + id).qrcode({
            width: 120, //宽度
            height: 120, //高度
            text: utf16to8(content), //内容
            typeNumber: -1,//计算模式
            correctLevel: 1,//二维码纠错级别
            background: "#ffffff",//背景颜色
            foreground: "#000000"  //二维码颜色
        });
    }
    //中文编码格式转换
    function utf16to8(str) {
        var out, i, len, c;
        out = "";
        len = str.length;
        for (i = 0; i < len; i++) {
            c = str.charCodeAt(i);
            if ((c >= 0x0001) && (c <= 0x007F)) {
                out += str.charAt(i);
            } else if (c > 0x07FF) {
                out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
                out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
                out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
            } else {
                out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
                out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
            }
        }
        return out;
    }
</script>

</body>

</html>

最后,晒出效果(灰色块为马赛克):

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老汉的微笑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值