文章
问答
冒泡
React中使用react-to-print打印出货单方案

对于打印可定制样式的出货单这种需求,我们可以使用 [https://www.npmjs.com/package/react-to-print](https://www.npmjs.com/package/react-to-print) 这个库来实现。


该库会打印出被创建的React组件,支持css样式的创建。


首先我们引入这个库 npm install --save react-to-print


使用方法非常简单,传入一个触发按钮Icon,再把要打印的组件传入进去就好了,我们使用ref.current传递。其他api可以参考官方文档。

import ReactToPrint from 'react-to-print';
import { PrinterOutlined } from '@ant-design/icons';
const popupContentRef = useRef(null);

<ReactToPrint
    trigger={() => <PrinterOutlined />}
    content={() => popupContentRef.current}
></ReactToPrint>

  <div
                ref={popupContentRef}
                id="popupContentRef"
                className={myStyles.printWrapper}
            ></div>

注意:打印页面可以有单独的css@media print控制:

:global {
    @media print {
        html,
        body {
            height: initial !important;
            overflow: initial !important; 
            -webkit-print-color-adjust: exact;
        }
    }
}

可以实现的效果为:


1726278304460-a750b685-851a-4726-8349-953f78545846.png1726278321967-4e83fe5c-6141-445a-a11c-5b36ae10bab5.png


打印多页:1726278377127-ae87a699-3f73-4806-b7c0-aed61276cfde.png


完整代码如下:

import React, { useRef } from 'react';
import myStyles from './index.module.less';
import ReactToPrint from 'react-to-print';
import { PrinterOutlined } from '@ant-design/icons';
const PrintComponent: React.FC = () => {
    const popupContentRef = useRef(null);
    function generateItems(count: number) {
        return Array.from({ length: count }, (_, i) => ({
            id: i + 1,
            name: `产品${i + 1}`,
            quantity: Math.floor(Math.random() * 5) + 1, // 随机数量
            price: Math.floor(Math.random() * 100) + 10, // 随机价格
        }));
    }

    // 示例:生成10条数据
    const items = generateItems(10);

    const totalAmount = items.reduce(
        (total, item) => total + item.quantity * item.price,
        0
    );

    return (
        <div className={myStyles.wrapper}>
            打印出货单测试
            <div>
                <ReactToPrint
                    trigger={() => <PrinterOutlined />}
                    content={() => popupContentRef.current}
                ></ReactToPrint>
            </div>
            <div
                ref={popupContentRef}
                id="popupContentRef"
                className={myStyles.printWrapper}
            >
                <div style={styles.container}>
                    <h1 style={styles.title}>出货单</h1>
                    <table style={styles.table}>
                        <thead>
                            <tr>
                                <th style={styles.th}>商品</th>
                                <th style={styles.th}>数量</th>
                                <th style={styles.th}>单价</th>
                                <th style={styles.th}>总价</th>
                            </tr>
                        </thead>
                        <tbody>
                            {items.map((item) => (
                                <tr key={item.id}>
                                    <td style={styles.td}>{item.name}</td>
                                    <td style={styles.td}>{item.quantity}</td>
                                    <td style={styles.td}>
                                        {item.price.toFixed(2)}
                                    </td>
                                    <td style={styles.td}>
                                        {(item.quantity * item.price).toFixed(
                                            2
                                        )}
                                    </td>
                                </tr>
                            ))}
                        </tbody>
                    </table>
                    <div style={styles.total}>
                        <strong>总价: {totalAmount.toFixed(2)}</strong>
                    </div>
                </div>
            </div>
        </div>
    );
};
const styles = {
    container: {
        maxWidth: '600px',
        margin: '20px auto',
        padding: '20px',
        border: '1px solid #ccc',
        borderRadius: '8px',
        boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',
        color: 'red',
    } as React.CSSProperties,
    title: {
        textAlign: 'center',
        marginBottom: '20px',
    } as React.CSSProperties,
    table: {
        width: '100%',
        borderCollapse: 'collapse',
        marginBottom: '20px',
    } as React.CSSProperties,
    th: {
        borderBottom: '1px solid #ddd',
        padding: '10px',
        textAlign: 'left',
    } as React.CSSProperties,
    td: {
        borderBottom: '1px solid #ddd',
        padding: '10px',
        textAlign: 'left',
    } as React.CSSProperties,
    total: {
        textAlign: 'right',
        fontSize: '18px',
    } as React.CSSProperties,
};
export default PrintComponent;
react

关于作者

却黑
社恐
获得点赞
文章被阅读