当前位置: 首页 > news >正文

CSS打印设置页眉页脚

之前写过一篇文章CSS实现自动分页打印同时每页保留重复的自定义内容,可以实现window.print()打印时多张页面保留相同的内容(如header、footer),但其并不是真正意义上的页眉页脚,footer内容在最后一张页面未撑满时不能置于页面底部。为了实现打印使用CSS自定义页眉页脚,解决之前遗留的问题,本文对之前的办法做了改进,提出了一种解决方案。

效果图

在这里插入图片描述

在这里插入图片描述

基本原理

  1. 在要打印的内容中,页眉页脚元素使用position: fixed,并设定各自的高度。
  2. 正文内容使用table元素,table的开头(thead)和结尾(tfoot)各使用一个设定高度(大于等于页眉页脚高度)的空DOM元素,防止页眉页脚与正文内容重叠。

此时即可实现自定义页眉页脚,调用window.print()时多张页面具有相同的页眉页脚,且页眉页脚可自定义内容,包括插入logo等图片。

示例代码

只打印指定dom内容,要打印的内容在#printDom中,页面在非打印模式不会显示其内容,只有在点击打印按钮调用window.print()时才会显示打印内容。

下方两个示例代码一样,根据个人阅读方式喜好查看。

示例代码-github:github

示例代码:

<html><head><title>print demo</title><meta name="description" content="CSS打印,支持自定义页眉页脚" /><meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /><metaname="viewport"id="WebViewport"content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/><style>@media print {@page {size: A4 portrait;/* 调整页边距 */margin: 1cm 1cm 1cm;}#printDom {display: block !important;}}#printDom {/* 打印区域在非打印时不显示 */display: none;position: relative;font-size: 16px;font-family: SimSun, Songti SC;}#printDom .page-header {/* 页眉高度 */height: 2cm;display: flex;align-items: center;position: fixed;top: 0mm;width: 100%;border-bottom: 1px solid #ddd;z-index: 2000;}#printDom .page-header-space {/* 控制内容区距离顶部的距离,防止与页眉重叠 */height: 2cm;}#printDom .page-footer {/* 页脚高度 */height: 1cm;position: fixed;bottom: 0;width: 100%;border-top: 1px solid grey;z-index: 2000;}#printDom .page-footer-space {/* 控制内容区距离底部的距离,防止与页脚重叠 */height: 1.5cm;}#printDom > table {width: 100%;}#printDom .content table {width: 100%;font-size: 30px;}#printDom .content .header {text-align: center;}</style></head><body><button onclick="handlePrint()">打 印</button><div id="printDom"><!-- 页眉 --><div class="page-header">Logo</div><table><!-- 占位,给页眉留出位置 --><thead><tr><td><div class="page-header-space"></div></td></tr></thead><!-- start: 正文 --><tbody><tr><td><div class="content"><!-- 正文的标题 --><h1 class="header">H1</h1><div><!-- 正文内容,可随意写,demo是表格 --><table><thead><tr><td>Index</td><td>Name</td></tr></thead><tbody id="tableBody"></tbody><tfoot></tfoot></table></div></div></td></tr></tbody><!-- end: 正文 --><!-- 占位,给页脚留出位置 --><tfoot><tr><td><div class="page-footer-space"></div></td></tr></tfoot></table><!-- 页脚 --><div class="page-footer">Footer</div></div><script>/*** 打印指定元素* @param {string} element 需要打印的元素选择器*/function printElement(element) {var printContents = document.querySelector(element).cloneNode(true);var popupWin = window.open('', '_blank');popupWin.document.open();const styles = document.head.innerHTML;popupWin.document.write(`<html><head><title>Print Title</title>${styles}</head><body οnlοad="window.print(); window.close();">`);popupWin.document.body.appendChild(printContents);popupWin.document.write('</body></html>');popupWin.document.close();}function handlePrint() {printElement('#printDom');}const tempTableData = document.querySelector('#tableBody');const tempFragument = document.createDocumentFragment();// mock datafor (let i = 0; i < 30; i++) {const _tr = document.createElement('tr');const _td1 = document.createElement('td');_td1.appendChild(document.createTextNode(`No${i + 1}`));const _td2 = document.createElement('td');_td2.appendChild(document.createTextNode(new Date().getTime()));_tr.appendChild(_td1);_tr.appendChild(_td2);tempFragument.appendChild(_tr);}tempTableData.appendChild(tempFragument);</script></body>
</html>

相关文章:

  • #QT(QCharts绘制曲线)
  • Dify vs Langchain:AI应用开发的全面分析
  • abstract 的 method 是否可同时是 static,是否可同时是 native,是否可同时是 synchronized?
  • SpringBoot快速入门-上
  • 用户需求分析揭秘:最佳实践与策略
  • 计算机网络——传输层重要协议(TCP、UDP)
  • ABBYY 15软件下载-ABBYY FineReader 15中文版下载附加详细安装步骤
  • 鸿蒙实现自定义Tabbar样式,显示数字红点提示
  • 什么是LLM?看这一篇就够了!
  • k8s 1.28 搭建rabbitmq集群
  • 充电学习—2、开关电源基本原理
  • 【ARMv8/ARMv9 硬件加速系列 3 -- SVE 指令语法及编译参数详细介绍】
  • 26 种 prompt 套路,驯服大模型
  • Python 介绍——浔川python社
  • 搭建zookeeper、Kafka集群
  • php的引用
  • $translatePartialLoader加载失败及解决方式
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • 08.Android之View事件问题
  • AHK 中 = 和 == 等比较运算符的用法
  • Cookie 在前端中的实践
  • export和import的用法总结
  • Java 多线程编程之:notify 和 wait 用法
  • java中的hashCode
  • k个最大的数及变种小结
  • Laravel核心解读--Facades
  • MySQL数据库运维之数据恢复
  • mysql中InnoDB引擎中页的概念
  • React中的“虫洞”——Context
  • Vue.js 移动端适配之 vw 解决方案
  • vue-cli在webpack的配置文件探究
  • 编写高质量JavaScript代码之并发
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 离散点最小(凸)包围边界查找
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 七牛云假注销小指南
  • 前端代码风格自动化系列(二)之Commitlint
  • 我有几个粽子,和一个故事
  • 【干货分享】dos命令大全
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • 从如何停掉 Promise 链说起
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • #70结构体案例1(导师,学生,成绩)
  • #define、const、typedef的差别
  • #include到底该写在哪
  • #NOIP 2014# day.1 T2 联合权值
  • (10)ATF MMU转换表
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (11)MATLAB PCA+SVM 人脸识别
  • (NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!
  • (pojstep1.1.2)2654(直叙式模拟)
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表