How to Create Invoice programmatically in magento 2?

Create and Capture Invoice Programmatically in Magento 2 required an order id.

Given code, a snippet is used to generating an Invoice in Magento, After generating an invoice automatically send the invoice mail to a customer who has placed the order.

I have just given a demo to create an invoice with the specified order id,

<?php
namespace Rbj\Invoice\Block;

class Invoice extends \Magento\Framework\View\Element\Template
{
public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
        \Magento\Sales\Model\Service\InvoiceService $invoiceService,
        \Magento\Framework\DB\TransactionFactory $transactionFactory,
        \Magento\Framework\Message\ManagerInterface $messageManager,
        \Magento\Sales\Model\Order\Email\Sender\InvoiceSender $invoiceSender,
        array $data = []
    ) {
        $this->orderRepository = $orderRepository;
        $this->invoiceService = $invoiceService;
        $this->transactionFactory = $transactionFactory;
        $this->messageManager = $messageManager;
        $this->invoiceSender = $invoiceSender;
        parent::__construct($context, $data);
    }
/**
 * Create Invoice Based on Order Object
 * @param \Magento\Sales\Model\Order $order
 * @return $this
 */
public function generateInvoice($orderId){
    try {
        $order = $this->orderRepository->get($orderId);
        if (!$order->getId()) {
            throw new \Magento\Framework\Exception\LocalizedException(__('The order no longer exists.'));
        }
        if(!$order->canInvoice()) {
            throw new \Magento\Framework\Exception\LocalizedException(
                    __('The order does not allow an invoice to be created.')
                );
        }

        $invoice = $this->invoiceService->prepareInvoice($order);
        if (!$invoice) {
            throw new \Magento\Framework\Exception\LocalizedException(__('We can\'t save the invoice right now.'));
        }
        if (!$invoice->getTotalQty()) {
            throw new \Magento\Framework\Exception\LocalizedException(
                __('You can\'t create an invoice without products.')
            );
        }
        $invoice->setRequestedCaptureCase(\Magento\Sales\Model\Order\Invoice::CAPTURE_OFFLINE);
        $invoice->register();
        $invoice->getOrder()->setCustomerNoteNotify(false);
        $invoice->getOrder()->setIsInProcess(true);
        $order->addStatusHistoryComment('Automatically INVOICED', false);
        $transactionSave = $this->transactionFactory->create()->addObject($invoice)->addObject($invoice->getOrder());
        $transactionSave->save();

        // send invoice emails, If you want to stop mail disable below try/catch code
        try {
            $this->invoiceSender->send($invoice);
        } catch (\Exception $e) {
            $this->messageManager->addError(__('We can\'t send the invoice email right now.'));
        }
    } catch (\Exception $e) {
        
        $this->messageManager->addError($e->getMessage());
    }

    return $invoice;
}

We just need to pass the order id in the generateInvoice($orderId) function in the given code snippet.

Code is checking the Order by order id, validate it, check for the invoice applicable for the order, prepare the Invoice, set qty for the invoice record, set offline capture mode, and finally create a transaction object for the Invoice.

Call function from the specific class,

$orderId = 1;
$this->generateInvoice($orderId);

This is the correct way to check all the possible validation before generating an invoice.