Invoice Generator with HTML, CSS & JavaScript

40 DAYS 40 PROJECT CHALLENGE

Day #04

Project Overview

A modern Invoice Generator built using HTML, CSS, and JavaScript with a clean and responsive interface for creating professional invoices. The application allows users to add item details, quantities, and prices, automatically calculate totals, and generate a printable invoice. It demonstrates frontend concepts such as dynamic table updates, real-time calculations, form handling, and responsive layout, making it a useful project for learning practical billing interface development

Key Features

  • Add multiple items with quantity and price
  • Automatic total and grand total calculations
  • Dynamic invoice table updates
  • Client details input including name and address
  • Printable invoice generation
  • Clean and responsive user interface
  • Real-time calculations using JavaScript
  • Simple billing layout suitable for small businesses

HTML Code

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Invoice Generator</title>
<link rel="stylesheet" href="style.css">
</head>
<body>

<div class="container">
  <h2>Invoice Generator</h2>

  <!-- CLIENT DETAILS -->
  <div class="client-details">
    <input type="text" id="clientName" placeholder="Client Name">
    <input type="text" id="clientAddress" placeholder="Client Address">
    <input type="date" id="invoiceDate">
  </div>

  <!-- ADD ITEM -->
  <div class="add-item">
    <input type="text" id="itemName" placeholder="Item Name">
    <input type="number" id="itemQty" placeholder="Qty">
    <input type="number" id="itemPrice" placeholder="Price">
    <button onclick="addItem()">Add Item</button>
  </div>

  <!-- TABLE -->
  <table>
    <thead>
      <tr>
        <th>Item</th>
        <th>Qty</th>
        <th>Price</th>
        <th>Total</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody id="invoiceItems"></tbody>
  </table>

  <div class="total-section">
    <h3>Grand Total: ₹ <span id="grandTotal">0</span></h3>
  </div>

  <button class="print-btn" onclick="printInvoice()">Print Invoice</button>

</div>

<script src="script.js"></script>
</body>
</html>

CSS Code

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: Arial, sans-serif;
  background: #042354;
}

.container {
  max-width: 900px;
  margin: 40px auto;
  background: #fff;
  padding: 30px;
  border-radius: 10px;
  box-shadow: 0 10px 25px rgba(0,0,0,0.08);
}

h2 {
  text-align: center;
  margin-bottom: 25px;
}

.client-details,
.add-item {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
}

.client-details input,
.add-item input {
  flex: 1;
  padding: 10px;
}

.add-item button {
  padding: 10px 15px;
  cursor: pointer;
  background: #111;
  color: #fff;
  border: none;
}

table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 20px;
}

table th,
table td {
  border: 1px solid #ddd;
  padding: 10px;
  text-align: center;
}

table th {
  background: #f1f1f1;
}

.total-section {
  text-align: right;
  margin-top: 20px;
}

.print-btn {
  margin-top: 20px;
  padding: 12px 20px;
  background: green;
  color: #fff;
  border: none;
  cursor: pointer;
}

/* RESPONSIVE */
@media(max-width: 768px) {
  .client-details,
  .add-item {
    flex-direction: column;
  }
}

Javascript Code

let items = [];
let grandTotal = 0;

function addItem() {
  const name = document.getElementById("itemName").value;
  const qty = parseFloat(document.getElementById("itemQty").value);
  const price = parseFloat(document.getElementById("itemPrice").value);

  if (!name || qty <= 0 || price <= 0) {
    alert("Please enter valid item details");
    return;
  }

  const total = qty * price;

  items.push({ name, qty, price, total });
  updateTable();

  document.getElementById("itemName").value = "";
  document.getElementById("itemQty").value = "";
  document.getElementById("itemPrice").value = "";
}

function updateTable() {
  const tbody = document.getElementById("invoiceItems");
  tbody.innerHTML = "";
  grandTotal = 0;

  items.forEach((item, index) => {
    grandTotal += item.total;

    tbody.innerHTML += `
      <tr>
        <td>${item.name}</td>
        <td>${item.qty}</td>
        <td>₹${item.price}</td>
        <td>₹${item.total}</td>
        <td><button onclick="removeItem(${index})">Remove</button></td>
      </tr>
    `;
  });

  document.getElementById("grandTotal").innerText = grandTotal;
}

function removeItem(index) {
  items.splice(index, 1);
  updateTable();
}

function printInvoice() {
  window.print();
}
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Related Projects

Day 1 : Admin Dashboard UI

User signup and login system with validated credentials and a clean UI.

Concepts: DOM manipulation, form validation, LocalStorage.

Day 2 : Kanban Board (Drag & Drop) 

A drag-and-drop task board to manage tasks across different stages.

Concepts: DOM manipulation, drag & drop API, event handling.

Day 6 : File Upload Progress Bar

File upload interface with a visual progress bar and smooth animation.

Concepts: File API, progress tracking, animations, event handling.