在react-to-print中实现PDF导出每页自定义页眉的问题
解决react-to-print导出PDF每页添加自定义页眉的问题
要实现每页自定义页眉,react-to-print本身没有内置配置,但可以通过CSS打印媒体查询 + @page规则来实现,同时先修正你现有代码里的HTML结构错误(这很可能是之前失效的核心原因之一)。
步骤1:修正无效的表格HTML结构
你原来的ManualHeader组件里,tr直接嵌套div和另一个tr不符合HTML规范,表格的tr只能包含td或th,先把结构改对:
const ManualHeader = () => { return ( <> <tr> <th colSpan="1" className="CatalogSheetProductTitle"> {currentManualItem?.header || ''} </th> </tr> <tr> <th colSpan="1" className="CatalogSheetTitle"> <span className="sheetCatalogTitle">Instalační manual</span> <br /> <span className="metel_logo_css"> METEL<span className="metel_dot">.</span>EU </span> </th> </tr> </> ); };
步骤2:添加打印专用的CSS样式
在样式文件或组件内的style标签中添加打印媒体查询,用@page规则给页面顶部留出页眉空间,再通过伪元素生成每页固定页眉:
/* 打印专用样式 */ @media print { /* 设置页面边距,给页眉预留足够空间 */ @page { margin-top: 4.5cm; margin-bottom: 2cm; } /* 用fixed定位的伪元素生成每页页眉 */ body::before { content: attr(data-print-header); position: fixed; top: 0; left: 0; right: 0; height: 4cm; padding: 1cm; background: #fff; /* 避免被下方内容穿透覆盖 */ text-align: center; display: flex; flex-direction: column; justify-content: center; border-bottom: 1px solid #ccc; } /* 隐藏页面内的重复页眉,只保留打印伪元素的页眉 */ .CatalogSheetProductTitle, .CatalogSheetTitle { display: none; } }
步骤3:调整react-to-print的逻辑与配置
因为useReactToPrint返回的打印函数不支持直接传参,所以需要用状态管理当前要打印的手册项,再配合钩子动态设置页眉内容:
// 新增状态保存当前要打印的手册项 const [currentManualItem, setCurrentManualItem] = React.useState(null); const Manuals = React.useRef(); const handlePrintManual = useReactToPrint({ content: () => Manuals.current, documentTitle: () => `${currentManualItem?.header || 'Manual'}.pdf`, copyStyles: true, onBeforePrint: () => { if (!currentManualItem) return; // 动态设置页眉内容到body的自定义属性 document.body.setAttribute('data-print-header', ` <div class="CatalogSheetProductTitle">${currentManualItem.header}</div> <div class="CatalogSheetTitle"> <span class="sheetCatalogTitle">Instalační manual</span><br> <span class="metel_logo_css">METEL<span class="metel_dot">.</span>EU</span> </div> `); }, onAfterPrint: () => { // 打印完成后清除自定义属性,避免影响正常页面 document.body.removeAttribute('data-print-header'); } });
同时修改点击事件的逻辑:
<a key={manualIndex} className="hover custom-download" onClick={() => { setCurrentManualItem(manualItem); handlePrintManual(); }} > <i className="bx bxs-download"></i>{" "} {manualItem.header} </a>
额外注意事项
- 浏览器打印预览需确保开启“页眉页脚”选项,自定义CSS会覆盖默认页眉样式
- 如果页眉包含图片,要确保图片路径为绝对路径或已提前加载完成
- 表格的
colSpan值需根据你的实际列数调整,保证页眉占满整行
内容的提问来源于stack exchange,提问作者Matěj Musálek
相关产品推荐
相关产品推荐

