0

I just occur one problem that i want to create invoice but when invoice get item image than it break A4 size so i want to print that if item have image than i want to print a only single product per page so like if i have 3 products and two of them have item image than i want to print two pages with same header and footer of invoice but change in body

Here is my react component

import { useState, useEffect, useRef, useLayoutEffect } from 'react';
import "./invoiceDesign.css";
import image from "../assets/images/nk-header.png"
import footerImage from "../assets/images/nk-footer.png"
import { Row } from "react-bootstrap"
import { Col } from "react-bootstrap"
import { useParams } from 'react-router-dom';
import axios from 'axios'
import ReactLoading from 'react-loading'
import { useReactToPrint } from "react-to-print";
import { MdFileDownload } from 'react-icons/md'
import reactHtmlParser from "react-html-parser"
import converter from "number-to-words"

function IvoiceDesign() {
    const { invoicenumber } = useParams()
    const componentRef = useRef();
    const [data, setData] = useState([])
    const [formattedDate, setFormattedDate] = useState('')
    const [isLoading, setIsLoading] = useState(true)
    const [imageAppears, setImageAppears] = useState(false)



    useEffect(() => {
        axios({
            method: "GET",
            url: `http://localhost:3333/invoice/${invoicenumber}`,
            headers: {
                "Content-Type": 'application/json',
                "Authorization": localStorage.getItem("token")
            }
        }).then((res) => {
            setData(res.data)
            console.log(res.data)
            setIsLoading(false)
        }).catch((err) => {
            console.log(err)
            setIsLoading(false)
        })
    }, []);

    useEffect(() => {
        if (data.invoiceDate) {
            const oldDate = new Date(data.invoiceDate);
            const newDate = oldDate.toLocaleString('en-GB');
            setFormattedDate(newDate.split(',')[0])
        }
    }, [data]);



    const handlePrint = useReactToPrint({
        content: () => componentRef.current
    });

    return (
        <>
            {isLoading ? <ReactLoading type='spin' color='blue' height='3rem' width='3rem' className='text-center m-auto' /> :
                <div className='container' >
                    <div ref={componentRef} className='sub-container'>
                        <div className='invoice-layout-header' >
                            <p className='text-center m-0'>Invoice</p>
                            <div className='invoice-header-image'>
                                <img src={image} alt="image" />
                            </div>
                            <div className='invoice-header-infomation'>
                                <Row className='invoice-header-row m-1'>
                                    <Col sm={8} className='invoice-header-column '>

                                        <Row className='invoice-header-subrows m-1 flex'><span className='p-0'><b>To:</b> {data.customerName}</span></Row>

                                        <Row className='invoice-header-subrows m-1'><span className='p-0'><b>GST No: </b>{data.customerGstNo ? data.customerGstNo : ""}</span></Row>
                                    </Col>
                                    <Col sm={4} className='invoice-header-column'>
                                        <Row className='invoice-header-subrows m-1'><span className='p-0'><b>Bill No :</b> {invoicenumber}</span></Row>
                                        <Row className='invoice-header-subrows m-1'><span className='p-0'><b > Date :</b> {formattedDate.split(",")}</span></Row>
                                    </Col>
                                </Row>
                            </div>
                        </div>
                        <div className='invoice-table-container' >
                            <table id="invoice-table">

                                <colgroup>
                                    <col width="35mm" />
                                    <col />
                                    <col width="60mm" />
                                    <col width="100mm" />
                                    <col width="100mm" />
                                </colgroup>
                                <tr class="invoice_line ">
                                    <th>sr.No</th>
                                    <th>Particurals</th>
                                    <th>Qty</th>
                                    <th>Rate</th>
                                    <th>Amount</th>
                                </tr>
                                {data.invoiceDetails.map((item, i) => {

                                    return (

                                        <tr class="invoice_line">
                                            <td>{i + 1}</td>
                                            <td class="site">
                                                <span className='flex flex-column'>
                                                    <div className='text-black'>{item.title}</div>
                                                    {item.imageName ?
                                                        <img src={`http://localhost:3333/${item.imageName}`} alt="Image}" className='invoice-item-image' />
                                                        :
                                                        <div className='invoice-item-image'></div>
                                                    }
                                                    <div className='text-black'>{reactHtmlParser(item.description)}</div>
                                                </span>
                                            </td>
                                            <td class="amount"><b>{item.quantity}</b></td>
                                            <td class="amount"><b>{item.rate}</b></td>
                                            <td class="amount"><b>{item.itemAmount}</b></td>
                                        </tr>


                                    )
                                })}


                                <tr>
                                    <td>&nbsp;</td>
                                    <td>&nbsp;</td>
                                    <td>&nbsp;</td>
                                    <td>&nbsp;</td>
                                    <td>&nbsp;</td>
                                </tr>
                                <tfoot>
                                    <tr className='mt-5 '>
                                        <td></td>
                                        <td></td>
                                        <td></td>
                                        <td><tr className='t-foot-td'>TOTAL</tr></td>
                                        <td><tr className='t-foot-td'><b>₹ {data.amount}</b></tr></td>
                                    </tr>
                                    {
                                        data.IGST ? <tr className='mt-5 '>
                                            <td></td>
                                            <td></td>
                                            <td></td>
                                            <td className='p-3'><tr className='t-foot-td p-4'>IGST({data.GstRate[0].IGst}%)</tr></td>
                                            <td><tr className='t-foot-td'><b>₹ {data.IGST}</b></tr></td>
                                        </tr> :
                                            <>
                                                <tr className='mt-5 '>
                                                    <td></td>
                                                    <td></td>
                                                    <td></td>
                                                    <td className='p-3'><tr className='t-foot-td p-4'>CGST({data.GstRate[0].CGst}%)</tr></td>
                                                    <td><tr className='t-foot-td'><b>₹ {data.CGST}</b></tr></td>
                                                </tr>
                                                <tr className='mt-5 '>
                                                    <td></td>
                                                    <td></td>
                                                    <td></td>
                                                    <td className='p-3'><tr className='t-foot-td p-4'>SGST({data.GstRate[0].SGst}%)</tr></td>
                                                    <td><tr className='t-foot-td'><b>₹ {data.SGST}</b></tr></td>
                                                </tr>
                                            </>

                                    }

                                    <tr className='mt-5 '>
                                        <td></td>
                                        <td></td>
                                        <td></td>
                                        <td><tr className='t-foot-td'>TOTAL</tr></td>
                                        <td><tr className='t-foot-td'><b>₹ {data.invoiceTotalPrice}</b></tr></td>
                                    </tr>
                                    <tr>
                                        <td colSpan="5" className='price-in-words'><span className='p-0 text-black'><b>In words: {converter.toWords(data.invoiceTotalPrice)}</b></span></td>
                                    </tr>
                                </tfoot>
                            </table>


                        </div >
                        <div className='invoice-footer-image'>
                            <img src={footerImage} alt="image" />
                        </div>

                    </div>

                </div >
            }
            <botton className="print-btn" onClick={handlePrint}>{<MdFileDownload size={30} />}</botton >
        </>
    );
}



export default IvoiceDesign;

Here is my data that come from backend

{
    "companyName": "LTIM",
    "customerName": "Np builders",
    "customerGstNo": "XPDS12344DESF",
    "invoiceDetails": [
        {
            "title": "water cooler",
            "description": "",
            "imageName": "pngwing.com.png",
            "imagePath": "../backend/media/pngwing.com.png",
            "quantity": 1,
            "rate": 12000,
            "itemAmount": 12000,
            "_id": "64dc481938309b30eb6abc5d"
        },
        {
            "title": "router",
            "description": "",
            "imageName": "router.png",
            "imagePath": "../backend/media/router.png",
            "quantity": 1,
            "rate": 12000,
            "itemAmount": 12000,
            "_id": "64dc481938309b30eb6abc5e"
        }
    ],
    "amount": 24000,
    "invoiceTotalPrice": 26880,
    "SGST": 1440,
    "CGST": 1440,
    "GstRate": [
        {
            "_id": "64b4d250ec83c5a4cebcd5bb",
            "IGst": 5,
            "CGst": 2.5,
            "SGst": 2.5,
            "__v": 0
        }
    ],
    "invoiceDate": "2023-08-16T03:52:57.766Z"
}

and here is my invoice route from backend

Router.get("/invoice/:invoicenumber", auth, async (req, res) => {
    const { invoicenumber } = req.params;
    const finalInvoice = {};
    try {
        const rawInvoice = await Invoice.findOne({ invoiceNumber: invoicenumber })
        const company = await Company.findById(rawInvoice.companyID).exec()
        const customer = await Client.findById(rawInvoice.customerID).exec()
        const GSTrate = await GstModel.find({}).exec()


        finalInvoice.companyName = company.companyName;
        finalInvoice.customerName = customer.clientName;
        finalInvoice.customerGstNo = customer.clientGstNo;
        finalInvoice.invoiceDetails = rawInvoice.invoiceDetails;
        finalInvoice.amount = rawInvoice.amount;
        finalInvoice.invoiceTotalPrice = rawInvoice.totalAmount;
        if (customer.state === 'Gujarat') {
            finalInvoice.SGST = rawInvoice.SGST;
            finalInvoice.CGST = rawInvoice.CGST;
        } else {
            finalInvoice.IGST = rawInvoice.IGST;
        }
        finalInvoice.GstRate = GSTrate;
        finalInvoice.invoiceDate = rawInvoice.date;

        res.status(200).send(finalInvoice)

    } catch (err) {
        res.send(err);
    }
})

i got stuck into this problem from last three days i dont get and proper answer.

i just want to try print images on multiple pages

Matthew Herbst
  • 29,477
  • 23
  • 85
  • 128
  • What you're trying to do is possible, but not in an easy manner. Basically, you need to use the `onBeforeGetContent` prop of `react-to-print` to change the layout of the page before printing. During that layout change, for each item in your invoice, you need to create a component like `
    `. Then in CSS you can use page breaks to force a new page for each list item
    – Matthew Herbst Aug 22 '23 at 03:52
  • Thanks for respond but i want to do like css break property ruin my layout of invoice So don't want use that is there any other way to achieve that – Mohan Dhila Aug 24 '23 at 05:06
  • It would only impact your layout during printing, which is what you want no? – Matthew Herbst Aug 24 '23 at 08:56

0 Answers0