近期拿到一个需求,里面涉及到网页打印,本来以为执行浏览器自带的 window.print() 方法调取打印控件就好了,没想到事情并非那么简单, 打印预览中不仅样式不对,连内容都无法展示全,多页的内容只显示了一页,这明显无法满足项目需求啊!
于是研究了下相关的优化方案,整理如下:
window.print() 默认效果缺陷
1.打印控件默认没给分页,就只显示了一页
2.dom 布局和样式很容易发生错位、丢失
3.我想要局部打印,但默认是获取的整个 body.innerHtml 的内容
打印样式优化
这种方式是通过增加针对打印机及预览才识别的css代码来调整效果,css 引入的方式有下面几种
print 样式加载的4种方式
1.<link rel="stylesheet" href="" media="print">
2.@import url print
概述 @import CSS@规则,用于从其他样式表导入样式规则。这些规则必须先于所有其他类型的规则,@charset 规则除外; 因为它不是一个嵌套语句,@import不能在条件组的规则中使用。 因此,用户代理可以避免为不支持的媒体类型检索资源,作者可以指定依赖媒体的@import规则。这些条件导入在URI之后指定逗号分隔的媒体查询。在没有任何媒体查询的情况下,导入是无条件的。指定所有的媒体具有相同的效果。 语法 @import url; @import url list-of-media-queries;
3.style 内联样式,注意依然要配置 media="print"
4.通过媒体查询 @media
去除页眉页脚
<style> @media print { @page { margin: 0; // 可以控制打印布局(四周边距) } body { border: 1px solid #999; } } </style>
@page 规则用于在打印文档时修改某些CSS属性。你不能用@page规则来修改所有的CSS属性,而是只能修改margin,orphans,widow 和 page breaks of the document。对其他属性的修改是无效的。
@page { margin: 1cm; } @page :first { margin: 2cm; }
控制分页
page-break-before: 控制在指定元素前是否分页
page-break-after: 控制在指定元素后是否分页
page-break-inside 控制指定元素中是否可以插入分页符
可选参数: always | auto | avoid | left | right | inherit
示例:
<style> @media print { @page { margin: 0; } body { border: 1px solid #999; } p { page-break-after: always; } } </style>