本周来了一个新的需要,须要前端生成打印内容,每一项数据占据一张 A4 纸,抉择多项就是分多张打印,所以须要打印指定内容区域,并且应用 page-break 来管制打印区域的分页。
以前就只应用 CSS 管制过打印时款式,暗藏一些不须要打印的区域,还尝没有试过打印指定区域内容,并且管制打印内容强制分页,所以记录一下。

抉择打印区域

部分打印的形式据我理解到的有三种:

  1. 通过开始、完结标记来管制打印范畴;

    • <!--startprint--><!--endprint-->
  2. 通过把部分内容赋值给body,打印整个页面,而后再把原页面内容反复笼罩回来;
  3. 通过动态创建<iframe>来打印;
    window.print() 部分打印三种形式 - 硅谷工具人



比拟举荐的是第一种第三种办法。不过我抉择去 NPM 上找一个现成的轮子 。
其实也不是我找的,其实小伙伴再之前曾经做完了部分打印性能,只是起初提了新的需要这回要求打印内容的款式,所以由我来接手了。
抉择的库是 vue-print-nb,我看了一下源码其实现形式是下面提到的第三种。

首先通过 documentCreateElement('iframe') 创立一个 <iframe> 元素;再通过 document.getElementById() 拿到须要打印的区域内容,同时把获取到须要打印的区域内容通过 Node.cloneNode() 复制到创立的 <iframe> 当中;最初用 window.print() 这个API关上打印对话框打印以后文档,就能够实现打印原先指定的区域内容了。

更具体的办法能够查看仓库源码或者查看文章尾部的参考资源中的对应文章,我这里就不现学现卖了。

配置页面打印款式

通过 CSS 的 @page 规定能够管制打印时的页面款式,然而可配置的内容不多。

@page 规定用于在打印文档时批改某些 CSS 属性。你不能用 @page 规定来批改所有的 CSS 属性,而是只能批改 margin,orphans,widowpage breaks of the document。对其余属性的批改是有效的。
@page - MDN



临时我能用到的就只有 marginsize 以及 page-break 了,应用形式很简略和失常的CSS一样应用,例如:

@page {    margin: 1cm; // 设置打印页边距;    size: A4 portrait; // 指定打印时纸张大小和方向    break-after: page; // 分页属性}

能够把 @page 规定了解成打印时的对象去设置,并不和 @media print 类似。
并且我在尝试应用 size 指定纸张的大小时(别名), ChromeFireFoxEdge 都没有失效。指定纸张方向是能够的。

  • 应用别名指定纸张大小时, Edge 中甚至影响到了 margin 属性的失效,所以最好 size 只指定方向 (2022 年 7 月 25 日)。
  • 应用具体数值指定纸张大小时,ChromeFireFox 中指定的纸张方向生效了 (2022 年 7 月 25 日)。

简略配置一下页面打印款式,而后开始写打印内容款式。因为实际上能够配置的属性真的不多,而且各浏览器反对的水平也参差不齐,如果高定制化的话会很容易自闭。

页面内容款式

这块内容就是失常写CSS款式了,有一部分在打印时的非凡款式搭配应用 @media print 来匹配就能够了,一遍调整一边应用浏览器的打印预览性能查看实际效果即可,所以就不赘述了。

分页打印内容

分页的话,应用在前文中提到的 page-break,给占据整页/整块区域的内容减少 break-before 或者 break-after 属性即可。
也能够给独自的相似 <hr /> 这样的水平线元素减少 page-break 属性。而后再搭配 @media print 给水平线在打印时暗藏,这样的话能够在查看页面的时候就晓得哪些局部他会分页,并且在打印时也不会印象打印内容排版。

留神:如果要在打印时暗藏 <hr/> 元素并且放弃分页性能,须要应用 visibility: hidden; 来暗藏,不能应用 display:none 不然分页属性不会失效。

遇到问题

1. 应用 page-break-after 是内容分页但在打印时不失效

因为 page-break-afterbreak-after 代替了。绝对应的 page-break-before 也被 break-before 属性代替了。
也有可能是因为你的值设置错了,设置为 page 就好了。

  • 惯例中断值有:auto,avoid,always,all;
  • 分页应用的值有:avoid-page,page,left,right,recto,verso;
  • 分栏应用的值有:avoid-column,column;
  • 分区应用的值有:avoid-region,region;
    《CSS新世界》

我看张鑫旭大佬说 region 相干的属性古代浏览器曾经不再反对了,所以能够疏忽。

2. 设置的背景色没有被打印。

因为默认打印页面时为了节约墨水,所以默认状况下是不会打印背景色的,如果心愿打印的时候保留背景色能够只用 color-adjust 属性来管制。

color-adjust 属性并非一个规范属性,所以在应用时须要查看一下各浏览器的兼容水平。有的浏览器须要减少公有前缀(比方 -webkit-print-color-adjust)。

3. 打印页面的时候,在打印预览窗口抉择了黑白模式然而理论打印进去还是黑白的。

浏览器弹出的打印预览设置了黑白模式,并不一定代表了打印机设置的首选项内是黑白的,能够关上对应的打印机查看首选项设置内的色调模式是否为黑白。
具体步骤为:

  1. 在打印预览弹窗内点击 应用零碎对话框打印

    • 如果没有该项,可在浏览器中应用 Ctrl+Shift+P 的组合键关上
  2. 在弹出的打印窗口中找到对应的打印机设施,点击首选项
  3. 抉择纸张/输入卡片,找到色调模式批改为黑白
  4. 最初点击确定保留并利用设置,再点击打印尝试打印;

序幕

当初很多和打印相干的规定和API还都是草案,很多规定都没有固定下来成为规范,不同的浏览器也有本人的实现形式,有些属性还是局部反对(比方:size 属性)或者须要公有前缀。
尽量先查看一下最新的文档,不要照搬笔记或者文章,因为谁也不晓得啥时候就扭转了,我在写这篇笔记时看到草案的订正工夫是 2022年5月24日,不晓得你们看到的时候会是第几个版本了。

那就这样吧,以上。

参考文档

Paged media - CSS | MDN
@page - CSS | MDN
size - CSS | MDN
page-break-after - CSS | MDN
break-after - CSS | MDN
print-color-adjust - CSS | MDN
window.print - Web API | MDN
CSS Paged Media Module Level 3 | W3C Editor's Draft

page-break | CSS-Tricks - CSS-Tricks
Can I force a page break in HTML printing? - Stack Overflow
CSS 打印 - SegmentFault 思否
记CSS中break-after的一个坑 - 知乎
window.print()部分打印三种形式 - 硅谷工具人 - 博客园
window.print()打印时依据页面高度设置居中显示、设置打印布局(纵向、横向)\_清云青云的博客 - CSDN

本文参加了SegmentFault 思否写作挑战赛,欢送正在浏览的你也退出。