一文弄懂window.print 打印

前言window.print() 默认效果缺陷

一、打印样式二、打印指定区域内容1. 对容器进行打印2. 对容器内的部分内容进行打印3. 监听打印前后事件4. iframe

三、强行插入分页四、打印设置五、最佳实践(React)1. 背景:2. 思路:3. 实现:

六、如果干预打印分页七、 window.print去除浏览器默认页眉页脚window.print() 实现A4纸张打印及去掉页眉页脚及打印链接window.print() 去掉页眉页脚及打印链接

八 、IE浏览器打印预览 :使用html 标签引入Webbrowser控件

https://developer.mozilla.org/en-US/docs/Web/API/Window/print

前言

一般信息填写类的需求页面,都会增设「预览」和「打印」功能。我们会通过编写 DOM 及样式来绘制出预览视图,而打印则是基于预览来生成 PDF 文件。

浏览器原生 API window.print() 可以用于打印当前窗口(window.document)视图内容。调用此方法会产生一个打印预览弹框,用户可以根据具体设置来得到打印结果。

window.print() 默认效果缺陷

1.打印控件默认没给分页,就只显示了一页

2.dom 布局和样式很容易发生错位、丢失

3.我想要局部打印,但默认是获取的整个 body.innerHtml 的内容

一、打印样式

默认情况下,基于页面上的内容,会将元素,布局和样式都进行打印;

如果仅想在打印上设置特殊样式,可以通过以下方式: 1.使用打印样式表:

2.使用媒介查询:

@media print {p{color: lavender;background: #ccc;}h1{color: lightblue;background: #ccc;}

}

3.使用内联 media 属性

默认情况下,元素的背景色不会被打印,可通过设置属性来支持:

div{// Chrome、Safari 等 webkit 浏览器内核-webkit-print-color-adjust: exact;// 火狐print-color-adjust: exact;color-adjust: exact;

}

二、打印指定区域内容

默认情况下,调用 window.print() 会对整个 document.body 进行打印,当需要打印指定容器内容时,可以通过以下几种方式:

1. 对容器进行打印

这是一个段落

这是一个标题

2. 对容器内的部分内容进行打印

当只需要打印容器内某一部分内容时,可以通过注释标识进行截取。

这是一个段落

这是一个标题

3. 监听打印前后事件

通过监听打印前后事件window.onbeforeprint、window.onafterprint ,对不需要进行打印的元素进行隐藏和放开隐藏。

这是一个段落

这是一个标题

4. iframe

上面几种方式都在当前窗口进行打印,并且都需要更改 document.body 内容,这会出现视图切换,带来的体验不是太好。

下面我们借助 iframe 来实现打印,并且不影响当前视窗的内容展示。

这是一个段落

这是一个标题

三、强行插入分页

当需要自定义打印分页时机时,可通过如下方式将指定 DOM 设为分割点。

1.在指定元素前添加分页符

@media print {h1 {page-break-before: always;}

}

2.在指定元素后添加分页符

@media print {h1 {page-break-after: always;}

}

四、打印设置

1.设置打印布局

@media print {

@page {

/* 纵向展示(高度展示内容更多) */

/* size: portrait;*/

/* 横向(宽度展示内容更大) */

size: landscape;

/* 打印的边距 上右下左 */

margin: 1cm 2cm 1cm 2cm;

}

}

注意,一旦设置为 size: landscape,在打印时将不能切换展示模式,包括纸张类的设置。

五、最佳实践(React)

1. 背景:

有一个信息填写页面,支持进行预览和打印,预览是一个 Dialog 弹框,打印取自于预览的内容。因此,在打印前,需要将预览内容呈现在 DOM 树上。

2. 思路:

点击打印,将预览 Dialog open state 设置为 true,Dialog 渲染到 DOM 树上;执行 setTimeout 延迟任务,在 Dialog 渲染在 DOM 树上后对其隐藏(disabled: none),目的是实现视图上不展示 Dialog;创建 iframe,并将 Dialog 内容及其样式,写入 iframe.document 中;执行 iframe.contentWindow.print() 进行打印;打印完成后做一些重置处理:移除 iframe、将 Dialog 隐藏逻辑去掉、将 Dialog open state 置为 false; 这样,在不影响现有页面内容的展示,同时实现了打印 Dialog 内容。

3. 实现:

const printFocus = () => {

// 打印事件

// 1.挂载要打印的内容

setPreviewOpen(true);

setTimeout(() => {

// 延迟,等待 Dialog 渲染在 DOM 树上

// 2.隐藏要打印的内容

const container =document.querySelector('.preview-wrapper');

container.setAttribute('style','display: none;');

// 3. 创建

iframeconst iframe =document.createElement('iframe');

const printContent =container.innerHTML;

iframe.setAttribute('style', 'position: absolute; width: 0;height: 0;');

document.body.appendChild(iframe);

const doc =iframe.contentWindow.document;

// 4. 写入内容//

doc.write('');

doc.write(``);

doc.write('

'+ printContent + '
');

const link = doc.getElementsByTagName('link')[0];

link.onload = () => {

// 样式文件加载完毕后打印

// 5.执行打印

iframe.contentWindow.print();

// 6.重置工作

document.body.removeChild(iframe);

setPreviewOpen(false);

container.removeAttribute('style');

}

},0);

}

六、如果干预打印分页

通常我们会遇到这种情况:在打印内容多于一页时会自动进行分页,若分页的分割点恰巧是一行文字,就会出现文字被切割分别显示在上下两页。

尽管我们可以通过 CSS 属性 page-break-before: always; 来干预分页,但页面内容并非固定的,如何将这个属性恰巧应用在分割点的 DOM 元素之上呢?

下面有一个思路可以参考一下:

1.为可能会被分割的元素设置自定义属性,用于查找访问; 2.根据打印视窗的每页高度,粗估一个高度值,作为页面分割的参考; 3.遍历可分割元素,判断它们是否处于页面分割位置(top < pageHeight && botton > pageHeight); 4.若处于页面分割位置,为此 DOM 设置分割属性 page-break-before: always;。 代码实现:

七、 window.print去除浏览器默认页眉页脚

打印时默认有页眉页脚信息,显示在页面外边距范围,我们可以通过去除页面模型page的外边距,使其隐藏页眉页脚信息,再通过设置 body 元素的 margin 来保证打印出来的页面带有外边距

@media print {

@page {

margin: 0;

}

body {

margin: 1cm;

}

}

//打印(兼容IE浏览器)

function webPrint(objId){

var printContent=document.getElementById(objId).innerHTML;//获得需要打印内容的HTML代码

PageSetup_Null();//把页眉页脚设置为空

printWindow=window.open('','_blank');

printWindow.document.write(' ');

//这里是向新建的窗口写入HTML的head信息,可引入自己的js和css,以供打印时样式与网页中显示的一致

printWindow.document.write('

'+printContent+"
");

//这里向新建的窗体中写入BODY的内容,注意,外边加的额外DIV是有必要的,它里面CSS可以控制打印时不会出现空白页

printWindow.document.write("");//这里向新建的窗体写入HTML的结束标记

printWindow.document.close();//关闭新建窗口的文档输出流,否则下面的打印语句无效

printWindow.print();//打印当前新建窗口中的内容

printWindow.close();//关闭新建的窗口

PageSetup_Default();//把页眉页脚恢复为默认

}

//设置网页打印的页眉页脚为空

function PageSetup_Null(){

var HKEY_Root,HKEY_Path,HKEY_Key;

HKEY_Root="HKEY_CURRENT_USER";

HKEY_Path="\\Software\\Microsoft\\Internet Explorer\\PageSetup\\";

try{

var Wsh=new ActiveXObject("WScript.Shell");

HKEY_Key="header";

Wsh.RegWrite(HKEY_Root+HKEY_Path+HKEY_Key,"");

HKEY_Key="footer";

Wsh.RegWrite(HKEY_Root+HKEY_Path+HKEY_Key,"");

}catch(e){}

}

//设置网页打印的页眉页脚为默认值

function PageSetup_Default(){

var HKEY_Root,HKEY_Path,HKEY_Key;

HKEY_Root="HKEY_CURRENT_USER";

HKEY_Path="\\Software\\Microsoft\\Internet Explorer\\PageSetup\\";

try{

var Wsh=new ActiveXObject("WScript.Shell");

HKEY_Key="header";

Wsh.RegWrite(HKEY_Root+HKEY_Path+HKEY_Key,"&w&b页码,&p/&P");

HKEY_Key="footer";

Wsh.RegWrite(HKEY_Root+HKEY_Path+HKEY_Key,"&u&b&d");

}catch(e){}

}

window.print() 实现A4纸张打印及去掉页眉页脚及打印链接

测评表

打印

window.print() 去掉页眉页脚及打印链接

八 、IE浏览器打印预览 :使用html 标签引入Webbrowser控件

最近遇到这么一个需求,需要在IE浏览器上打印的时候,不直接调用打印机,而是先打开打印预览页面,再进行打印操作。 这样,就需要对原本的打印方法进行改写了。使用html 标签引入Webbrowser控件,这种方式优势是在IE下可以弹出打印预览,这是打印很人性化的功能,但是遗憾的是高版本的IE浏览器不支持WebBrowser了。 具体实现如下:

function printall(){

// 打印页面预览

if (!!window.ActiveXObject || "ActiveXObject" in window){//IE浏览器

$(".noprint").css("display","none");

try{

//增加打印预览

printWB.ExecWB(7, 1);

}catch(e){

alert(e);

}finally{

$(".noprint").css("display","");

}

}else{

//需要引入jquery.jqprint-0.3.js

$('#a').jqprint();

}

}

附该对象常用的方法:

下面附上测试的完整代码:

print demo

这些文本将要被打印!

关于这个组件还有其他的用法,列举如下:
WebBrowser.ExecWB(1,1) 打开
Web.ExecWB(2,1) 关闭现在所有的IE窗口,并打开一个新窗口
Web.ExecWB(4,1) 保存网页
Web.ExecWB(6,1) 打印
Web.ExecWB(7,1) 打印预览
Web.ExecWB(8,1) 打印页面设置
Web.ExecWB(10,1) 查看页面属性
Web.ExecWB(15,1) 撤销
Web.ExecWB(17,1) 全选
Web.ExecWB(22,1) 刷新
Web.ExecWB(45,1) 关闭窗体无提示

https://blog.csdn.net/weixin_44867717/article/details/128178668

https://blog.csdn.net/fengshuiyue/article/details/57483057

原文链接: https://blog.csdn.net/Misnice/article/details/100539347 https://juejin.cn/post/7071064879217508366

https://juejin.cn/post/6844903630135361550 https://blog.csdn.net/ylq090324/article/details/121348777 https://blog.csdn.net/ZslLoveMiwa/article/details/80616399 https://segmentfault.com/a/1190000039696670 https://blog.csdn.net/JAVA11429/article/details/112747188 https://www.cnblogs.com/robertfang/articles/1599551.html https://blog.csdn.net/hehyyoulan/article/details/81098814

<