问题描述
最近遇到一个问题,前端使用 pdfjs 预览 PDF 文件时,在浏览器中执行打印,谷歌浏览器最后一页会出现空白。如下图所示。在火狐浏览器和 Safari 中是正常的,初步判断是某个代码兼容性问题。
pdfjs 官方链接:https://github.com/mozilla/pdf.js
这是火狐团队维护的代码,用于网页中浏览 PDF 文件。
问题查询
查询很多博客后,我先定位到 #printContainer 这个样式问题。
不同的博客给出很多解决方案,例如调节 width height, 或者 transform: scale(0.9) 等方案,我本地设置后无效。
https://blog.youkuaiyun.com/qq_38420994/article/details/129705471
https://blog.youkuaiyun.com/m0_47135993/article/details/129753368
https://stackoverflow.com/questions/28874940/pdf-js-inserting-blank-pages-when-printing
问题解决
最后,我查询 pdfjs 源代码,发现换行应该和下面的 css 相关
#printContainer > .printedPage {
page-break-after: always;
page-break-inside: avoid;
/* The wrapper always cover the whole page. */
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
其中 page-break-after 表示是否分页,源代码中是 always 始终分页,我改成了 auto 即可解决这个问题
#printContainer > .printedPage {
page-break-after: auto; /* 自动分页符(既不强制也不禁止) */
page-break-inside: avoid;
/* The wrapper always cover the whole page. */
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
这个属性的具体参考 MDN 官方介绍:
https://developer.mozilla.org/zh-CN/docs/Web/CSS/page-break-after
反思
pdfjs 这个库发展比较久,不同版本代码不一样,解决的思路也不一样。实际上需要根据自己项目实际的代码版本,定位问题并解决。前几个 优快云 博主的思路,虽然没有直接解决问题,不过给了我解决的方向和思路,向他们表示感谢。
2024-10-11 补充
近期另一个项目也出现了类似的问题:开发环境中 pdfjs 打印正常,生产环境中 pdfjs 会打印出空白页面。
基本分析:这是一个老项目,生产环境中,重复使用的 css,统一打包到 common.bundle.css 公共模块中,可能是公共模块中的 css 和 pdfjs 中的样式冲突,造成了这个问题。
临时解决思路:查看 common.bundle.js 中是否存在冲突的 css 属性,然后避免公共属性影响当前页面的样式(使用更高级别的 css 权重覆盖公共组件样式,或者单独打包等解决)。
根本解决思路:更改打包方式,避免某个模块的样式影响其他模块的样式。严格控制公共模块的样式。