面试 ~
面试官:
随着软件开发逐渐由 C/S架构 转向 B/S架构,Web端在线打印的需求也日益增加。那如果让你去实现一个Web端在线打印的需求,你会怎么做呢?
小白同学:在 C/S架构的软件中打印确实比较常见,而在 Web 浏览器端,虽然 CSS 技术可以很方便的实现复杂的布局排版,但由于浏览器安全沙箱机制,Web 浏览器端在线打印大概有两种实现方式:
- 直接调用 JS 打印
通过调用浏览器 window 对象内置的 print 方法弹出打印窗口,用户点击确认打印。这种方式是最简单的打印方法。因良好的浏览器兼容性,无需安装程序,且后续更新维护方便,很适用于面向普通消费群体。- 本地程序代理打印
还有一种方式是在本地安装代理程序,由代理提供 Http 服务,网页通过跨域的请求技术提交打印任务并接收反馈。这种方式好处是脱离了浏览器约束,打印排版样式和打印选项相比前者更加完善。但是需要提示用户下载并安装代理程序,同时还涉及本地安装的代理程序与设备系统的兼容性问题。如果设备兼容性问题 OK,那么非常适用于企业客户群体。
面试官:嗯,刚讲解得很详细。我们公司服务群体主要是普通消费群体,所以我们也是采用了你所说的第一种方案 window.print,那你简单介绍下第一种方案,如何定义打印时的页眉页脚、页边距以及布局排版。
小白同学:好的。在 Web 浏览器端,我们可以通过 媒体查询 @media print 和 分页媒体 @page 来定义
@media print { ... } 来指定打印内容的布局排版和样式 ......
@page { ... } 定义打印时的页眉页脚、页边距 ......
面试官: .....小白同学: ......
概述/简介
分页媒体 @page ,和媒体查询一样,同属于 At Rules 大家庭中其中一员。它可以用来指定页面框的各个方面,例如其尺寸、方向和边距等 (不仅限于打印使用) 。
有关媒体查询@media,可以参考这篇文章《讲解 CSS At Rules 媒体查询 @media》,而本篇将主要从如下几个方面讲解使用 分页媒体:
-
语法定义
-
CSS 属性
-
CSS 伪类
-
CSS 规则
-
应用场景 (示范)
-
Web 端 在线打印
-
Web 端 html 转 PDF (借助 docraptor.js)
-
分页媒体 @page
语法定义
css
css
复制代码
/* 例 1 -- 匹配所有页面框 */
@page {
size: A4 portrait; /* 定义 A4 大小, portrait 方向为竖向 */
margin: 0;
padding: 0;
page-orientation: upright;
}
/* 例 2 -- 匹配所有页面框 */
@page {
size: 21.0cm 29.7cm landscape; /* 定义 A4 大小, landscape 方向为横向 */
margin: 0;
padding: 0;
page-orientation: upright;
}
/* 例 3 -- 取决于页面书写方向,如果是从左到右,则 :left 匹配偶数页 */
@page :left {
margin-top: 4in;
}
/* 例 4 -- 取决于页面书写方向,如果是从左到右,则 :right 匹配奇数页 (即匹配第一页) */
@page :right {
size: 11in;
margin-top: 4in;
}
/* 例 5 -- 只匹配 <div id="wide"> 页面框,允许用户创建不同的页面配置 */
@page wide {
size: a4 landscape;
}
@page wide:left {
margin-top: 4in;
}
@page wide:right {
margin-left: 4in;
}
div#wide {
width: 100%;
print-color-adjust: exact;
page: wide; /* 命名新的页面框 wide */
}
div#wide p {
font-size: 16pt;
break-before: page;
break-after: page;
break-inside: avoid;
}
/* 例 6 -- page 内定义页边距框 At 规则,不适用于打印页边框 */
@page {
@top-right {
content: "Page " counter(pageNumber);
}
}
知识点
- @page 只能定义
size
、margin
、padding
、page-orientation
、At 规则
等- @page 内的
At Rule
(如 @top-center) 在打印页面框中无效。具体应用下面会有说明- @page 常用于打印页面框配置选项,所以不建议使用 px,一般用 pt、in、mm 等单位
CSS 伪类
与 @page 相关的伪类有这么几种 :left
、:right
、:first
、:blank
,定义使用详见 语法定义,具体含义如下:
- :left :
表示打印文档的所有左侧页面。给定页面是左还是右取决于文档的主要书写方向。例如,如果第一页的主要书写方向是从左到右,那么它将是一页:right
;如果它的主要书写方向是从右到左,那么它将是一个:left
页面 - :right :
表示打印文档的所有右侧页面。如何适配:right
,其原理同上,取决于页面的书写方向。 - :blank:匹配由于强制分页而出现的内容为空的页面
- :first:匹配文档中的第一张打印页
说明事项:
打印双面文档时,左页和右页的格式通常不同。这种情况下可以通过使用
:left
和:right
伪类来设置不同格式的选项
CSS 属性
-
页面框自身属性 ( @page)
- size: 定义页面框尺寸、方向
- margin:定义页面框外边距
- padding:定义页面框内边距
- page-orientation :定义旋转页面的方向 (查看演示)
a.upright
:不应用任何方向,并且页面的布局和格式正常
b.rotate-left
:页面布局后,页面必须向左旋转四分之一圈(逆时针)显示
c.rotate-right
:页面布局后,页面必须向右旋转四分之一圈(顺时针)显示。
-
页面框内元素属性 (Element)
-
page-break-before/break-before
: 设置是否在指定元素前添加分页符 (查看演示)page-break-before break-before (推荐) 描述说明 auto
auto
允许但不强制 avoid
avoid
尽可能避免 always
page
强制分页 -
page-break-after/break-after
: 设置是否在指定元素后添加分页符 (查看演示)page-break-after break-after (推荐) 描述说明 auto
auto
允许但不强制 avoid
avoid
尽可能避免 always
page
强制分页 -
page-break-inside/break-inside
: 设置是否在指定元素中插入分页符 (查看演示)page-break-inside break-inside (推荐) 描述说明 auto
auto
允许 avoid
avoid
尽可能避免 -
print-color-adjust
: 是否允许浏览器优化输出设备上元素的外观a. economy :允许浏览器优化 (提升渲染性能)
b. exact:不允许浏览器优化,保留原样式外观 (建议打印时配置此选项)
-
CSS 规则
页边距框 At 规则 (如 @top-left-corner ),嵌套在 @page
中使用,可以定义页边框各个方向的页边距,具体有哪些规则,又分别表示什么含义?可参考下图图示:
相关说明:
页边距框 At 规则
并不适用于打印页边框,在 window.print 中无法起效页边距框 At 规则
在下个小节 Web 端 html 转 PDF (范例) 中有具体使用
应用场景 (示范)
-
Web 端 在线打印
- 打印页面全部内容 (window.print)
- 打印指定区域内容 (PrintArea.js)
文章内置的 码上掘金 无法调用 window.print 唤起打印预览页,请单击 码上掘金 的详情,前往演示。
-
Web 端 html 转 PDF
借助 docraptor.js 实现了 html 转 PDF 的需求,同时它也支持 CSS @page 内部 At Rules 对样式的定义 (如
@top-left-corner
、@top-center
等)。 在线调试