react 打印实现
打印组件内容
使用 react-to-print 库可以轻松实现打印功能。安装依赖后,将需要打印的内容包裹在 ReactToPrint 组件中。通过 trigger 属性指定触发打印的按钮,content 属性绑定需要打印的组件引用。
import React, { useRef } from 'react';
import ReactToPrint from 'react-to-print';
const PrintableComponent = React.forwardRef((props, ref) => {
return <div ref={ref}>需要打印的内容</div>;
});
function App() {
const componentRef = useRef();
return (
<div>
<ReactToPrint
trigger={() => <button>打印</button>}
content={() => componentRef.current}
/>
<PrintableComponent ref={componentRef} />
</div>
);
}
打印样式控制
通过 CSS 的 @media print 规则可以定制打印时的样式。隐藏不需要打印的元素,调整布局以适应纸张尺寸。确保打印内容在 A4 纸张上正确显示,设置合适的边距和字体大小。
@media print {
.no-print {
display: none;
}
body {
margin: 0;
padding: 10mm;
font-size: 12pt;
}
}
打印页面设置
通过 window.print() 方法直接调用浏览器打印功能。在打印前可以动态修改页面内容,打印完成后恢复原始状态。使用 onbeforeprint 和 onafterprint 事件监听打印流程。
function handlePrint() {
const originalContent = document.body.innerHTML;
const printContent = document.getElementById('print-area').innerHTML;
document.body.innerHTML = printContent;
window.print();
document.body.innerHTML = originalContent;
}
打印表格数据
对于表格数据的打印,确保表格宽度适应纸张尺寸。使用 page-break-inside: avoid 防止表格跨页断裂。为表格添加边框和背景色,确保打印效果清晰可读。
const PrintableTable = ({ data }) => (
<table style={{ width: '100%', borderCollapse: 'collapse' }}>
<thead>
<tr>
<th style={{ border: '1px solid black' }}>列名</th>
</tr>
</thead>
<tbody>
{data.map((row) => (
<tr style={{ pageBreakInside: 'avoid' }} key={row.id}>
<td style={{ border: '1px solid black' }}>{row.value}</td>
</tr>
))}
</tbody>
</table>
);
打印多页内容
处理多页内容打印时,使用 CSS 的 page-break-before 或 page-break-after 控制分页。为每个逻辑部分添加分页符,确保内容按预期分页显示。测试不同浏览器的分页兼容性。
.page-break {
page-break-after: always;
}
打印预览功能
实现打印预览功能可以通过创建一个隐藏的 iframe,将内容加载到 iframe 中后调用打印。这种方式不会影响主页面内容,同时提供更接近实际打印效果的预览。
function printPreview(content) {
const frame = document.createElement('iframe');
frame.style.display = 'none';
document.body.appendChild(frame);
frame.contentDocument.write(content);
frame.contentDocument.close();
frame.contentWindow.focus();
frame.contentWindow.print();
setTimeout(() => document.body.removeChild(frame), 1000);
}






