javascripthtmlreactjsprintingreact-to-print

How to Disable Print Dialog When Using react-to-print in React?


I'm currently using the react-to-print library in my React application to enable printing functionality for a component. However, whenever I trigger the print action, a print dialog box pops up, which I'd like to disable to streamline the printing process.

import React, { useEffect, useRef } from 'react';
import { useReactToPrint } from 'react-to-print';
import LocalPrintshopIcon from '@mui/icons-material/LocalPrintshop';
import IconButton from '@mui/material/IconButton';
import Tooltip from '@mui/material/Tooltip';
import { findGrandTotal, convertTimestamp } from '../utils/functions';
import { businessDetailsData, invoiceDetailsData } from './data';

export const ViewInvoice = () => {

  const ComponentRef = useRef();
  const handlePrint = useReactToPrint({
    content: () => ComponentRef.current,
    
   });

  const invoiceDetails = invoiceDetailsData;
  const businessDetails = businessDetailsData;

  useEffect(() => {
    const handleHotkey = (event) => {
      if (event.ctrlKey && event.key.toUpperCase() === 'P') {
        event.preventDefault();
        handlePrint()
      }
    };

    document.body.addEventListener('keydown', handleHotkey);

    return () => {
      document.body.removeEventListener('keydown', handleHotkey);
    };
  }, []);


  return (
    <>
      <div className="w-full flex items-center md:justify-start justify-center relative">
        <Tooltip title="Print Invoice">
          <IconButton
            onClick={handlePrint}
            style={{
              position: 'fixed',
              top: '10px',
              right: '30px',
              zIndex: '1000px',
              color: '#F7CCAC',
            }}
          >
            <LocalPrintshopIcon style={{ fontSize: '50px' }} />
          </IconButton>
        </Tooltip>

        <div
          className="w-full md:w-2/3 shadow-xl mx-auto mt-8 rounded"
          ref={ComponentRef}
        >
          <div className="w-full bg-black flex items-center">
            <div className="w-1/2 h-[100%]  p-8 ">
              <img
                src={businessDetails ? businessDetails[0].data.logo : ''}
                alt="Logo"
                className="w-[150px]"
              />
            </div>
            <div className="w-1/2  px-6 py-4">
              <h3 className="text-gray-50 text-2xl mb-8">Invoice</h3>
              <p className="text-gray-50 text-sm mb-1">Invoice ID:</p>

              {invoiceDetails && (
                <p className="text-gray-300 mb-5 text-sm">
                  {invoiceDetails.id.slice(0, 5)}
                </p>
              )}

              <p className="text-gray-50 text-sm mb-1">Date:</p>

              {invoiceDetails && (
                <p className="text-gray-300 text-sm">
                  {convertTimestamp(invoiceDetails.data.timestamp)}
                </p>
              )}
            </div>
          </div>
          <div className="w-full flex items-center">
            {invoiceDetails && (
              <div className="w-1/2 p-8">
                <h3 className="font-medium mb-2">Bill To:</h3>
                <p className="text-sm mb-1">
                  {invoiceDetails.data.customerName}
                </p>
                <p className="text-sm mb-1">
                  {invoiceDetails.data.customerAddress}
                </p>
                <p className="text-sm mb-1">
                  {invoiceDetails.data.customerCity}
                </p>
                <p className="text-sm mb-1">
                  {invoiceDetails.data.customerEmail}
                </p>
              </div>
            )}

            {businessDetails && (
              <div className="w-1/2  p-8">
                <h3 className="font-medium mb-2">Bill From:</h3>
                <p className="text-sm mb-1">
                  {businessDetails[0].data.businessName}
                </p>
                <p className="text-sm mb-1">
                  {businessDetails[0].data.businessAddress},
                </p>
                <p className="text-sm mb-1">
                  {businessDetails[0].data.businessCity}
                </p>
              </div>
            )}
          </div>

          <div className=" p-8">
            <table>
              <thead>
                <th>Item</th>
                <th className="text-right text-sm">Cost</th>
                <th className="text-right text-sm">Qty</th>
                <th className="text-right text-sm">Price</th>
              </thead>
              <tbody>
                {invoiceDetails &&
                  invoiceDetails.data.itemList.map((item) => (
                    <tr key={item.itemName}>
                      <td className="text-xs capitalize">{item.itemName}</td>
                      <td className="text-xs text-right">
                        {Number(item.itemCost).toLocaleString('en-US')}
                      </td>
                      <td className="text-xs text-right">
                        {Number(item.itemQuantity).toLocaleString('en-US')}
                      </td>
                      <td className="text-xs text-right">
                        {(
                          Number(item.itemQuantity) * Number(item.itemCost)
                        ).toLocaleString('en-US')}
                      </td>
                    </tr>
                  ))}

                {invoiceDetails && (
                  <tr>
                    <td colSpan="3" className="text-right font-bold text-sm">
                      TOTAL AMOUNT
                    </td>
                    <td className="font-bold text-right uppercase text-sm">
                      {findGrandTotal(
                        invoiceDetails.data,
                        invoiceDetails.data.currency
                      )}
                    </td>
                  </tr>
                )}
              </tbody>
            </table>
          </div>

          {businessDetails && (
            <div className="w-full p-8">
              <h3 className="font-semibold mb-2">Payment Details</h3>
              <p className="text-sm mb-1 capitalize">
                <span className="font-semibold">Account Name: </span>
                {businessDetails[0].data.accountName}
              </p>
              <p className="text-sm mb-1">
                <span className="font-semibold">Account Number: </span>
                {businessDetails[0].data.accountNumber}
              </p>
              <p className="text-sm mb-1 capitalize">
                <span className="font-semibold">Bank Name: </span>{' '}
                {businessDetails[0].data.bankName}
              </p>
            </div>
          )}

          <footer className="px-8 py-4 bg-gray-200 w-full">
            <p className="text-sm text-center">Thanks for the patronage!</p>
          </footer>
        </div>
      </div>
    </>
  );
};

Issue: The problem arises when I attempt to print using the react-to-print library. Despite my efforts, I haven't been able to find a way to disable the print dialog box that appears each time I initiate printing.

What I've Tried: Investigated the react-to-print documentation for any specific configuration options related to the print dialog. Explored alternative libraries or methods for printing in React. Looked into browser-specific printing options but couldn't find a suitable solution.

I expect to be able to print the component without the print dialog box popping up, providing a seamless printing experience for users. If other library will provide this type of functionality then I can change library also


Solution

  • For right now this functionality is not possible.