For my project I was looking for a simple way to print quotes. At first I tried different PDF plugins, but in the end I went with another approach: I generated an HTML/Tailwind template (with the help of ChatGPT), placed it on a separate page, and passed in the data type with all the information I needed.
In the workflow, I just open that page in a new window, and it gives me the result — no plugin required. The real challenge is getting the HTML template right, but once that’s done, it works well.
It’s a pretty basic solution, but it solved my problem and might help others who are trying to avoid plugins for this use case.
1 Like
Awesome! What’s the process you used? Do you have sample of the code you got from ChatGPT?
Sure, this was the original output.
paste it here - HTML Online Editor (Compiler, Interpreter & Runner)
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Invoice — Demo</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
/* Optional: keep nice print margins */
@page { size: auto; margin: 18mm; }
</style>
</head>
<body class="bg-gray-100 text-gray-900 antialiased">
<main class="mx-auto my-8 max-w-3xl bg-white shadow-sm ring-1 ring-gray-200 print:shadow-none print:ring-0">
<!-- Actions (hidden on print) -->
<div class="flex items-center justify-end gap-2 px-6 py-3 border-b border-gray-200 print:hidden">
<button onclick="window.print()" class="px-3 py-2 text-sm rounded-lg ring-1 ring-gray-300 hover:bg-gray-50">Print</button>
<button id="downloadBtn" class="px-3 py-2 text-sm rounded-lg ring-1 ring-gray-300 hover:bg-gray-50">Download HTML</button>
</div>
<!-- Header -->
<header class="px-6 py-6 border-b border-gray-200">
<div class="flex items-start justify-between gap-6">
<!-- Logo placeholder -->
<div class="h-14 w-40 rounded-xl bg-gray-100 flex items-center justify-center text-xs uppercase tracking-widest text-gray-500">Logo</div>
<div class="text-right">
<h1 class="text-2xl font-semibold tracking-tight">INVOICE</h1>
<p class="mt-1 text-sm text-gray-500"># INV-002718</p>
</div>
</div>
<div class="mt-6 grid grid-cols-1 sm:grid-cols-3 gap-6 text-sm">
<div>
<p class="uppercase tracking-wider text-gray-500">From</p>
<p class="mt-1 font-medium">Demo Company LLC</p>
<p>123 Market Street</p>
<p>Austin, TX 78701</p>
<p>support@democo.test</p>
<p>+1 (512) 555-0199</p>
</div>
<div>
<p class="uppercase tracking-wider text-gray-500">Bill To</p>
<p class="mt-1 font-medium">Acme Industries</p>
<p>Attn: Jane Doe</p>
<p>88 Industrial Way</p>
<p>San Francisco, CA 94105</p>
<p>billing@acme.test</p>
</div>
<div>
<dl class="grid grid-cols-2 gap-x-3 gap-y-2">
<dt class="text-gray-500">Invoice Date</dt>
<dd class="text-right">Sep 13, 2025</dd>
<dt class="text-gray-500">Due Date</dt>
<dd class="text-right">Sep 27, 2025</dd>
<dt class="text-gray-500">Terms</dt>
<dd class="text-right">Net 14</dd>
<dt class="text-gray-500">PO #</dt>
<dd class="text-right">PO-8941</dd>
</dl>
</div>
</div>
</header>
<!-- Line Items -->
<section class="px-6 py-6">
<div class="overflow-hidden rounded-lg ring-1 ring-gray-200">
<table class="min-w-full divide-y divide-gray-200 text-sm">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-4 py-3 text-left font-medium text-gray-600">Item</th>
<th scope="col" class="px-4 py-3 text-right font-medium text-gray-600">Qty</th>
<th scope="col" class="px-4 py-3 text-right font-medium text-gray-600">Rate</th>
<th scope="col" class="px-4 py-3 text-right font-medium text-gray-600">Tax</th>
<th scope="col" class="px-4 py-3 text-right font-medium text-gray-600">Line Total</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100">
<tr>
<td class="px-4 py-3 align-top">
<p class="font-medium">Discovery & Planning</p>
<p class="text-gray-500">Initial workshops, requirements, and timeline definition.</p>
</td>
<td class="px-4 py-3 text-right align-top">1</td>
<td class="px-4 py-3 text-right align-top">$1,500.00</td>
<td class="px-4 py-3 text-right align-top">$0.00</td>
<td class="px-4 py-3 text-right align-top">$1,500.00</td>
</tr>
<tr>
<td class="px-4 py-3 align-top">
<p class="font-medium">Design & Prototyping</p>
<p class="text-gray-500">UI kit, wireframes, and interactive prototype.</p>
</td>
<td class="px-4 py-3 text-right align-top">12</td>
<td class="px-4 py-3 text-right align-top">$85.00</td>
<td class="px-4 py-3 text-right align-top">$97.20</td>
<td class="px-4 py-3 text-right align-top">$1,117.20</td>
</tr>
<tr>
<td class="px-4 py-3 align-top">
<p class="font-medium">Development Sprint</p>
<p class="text-gray-500">Backend integrations and core features.</p>
</td>
<td class="px-4 py-3 text-right align-top">40</td>
<td class="px-4 py-3 text-right align-top">$95.00</td>
<td class="px-4 py-3 text-right align-top">$456.00</td>
<td class="px-4 py-3 text-right align-top">$4,256.00</td>
</tr>
<tr>
<td class="px-4 py-3 align-top">
<p class="font-medium">Quality Assurance</p>
<p class="text-gray-500">Test plan, regression, and UAT support.</p>
</td>
<td class="px-4 py-3 text-right align-top">10</td>
<td class="px-4 py-3 text-right align-top">$70.00</td>
<td class="px-4 py-3 text-right align-top">$56.00</td>
<td class="px-4 py-3 text-right align-top">$756.00</td>
</tr>
</tbody>
</table>
</div>
<!-- Totals -->
<div class="mt-6 grid grid-cols-1 sm:grid-cols-2 gap-6">
<div>
<div class="grid grid-cols-[auto,1fr] gap-x-3 gap-y-2 text-sm">
<span class="text-gray-500">Payment Method</span>
<span>Bank Transfer (ACH)</span>
<span class="text-gray-500">Account</span>
<span>Demo Bank • **** 4321</span>
<span class="text-gray-500">Reference</span>
<span>INV-002718</span>
</div>
<div class="mt-4">
<p class="uppercase tracking-wider text-gray-500 text-xs">Notes</p>
<p class="text-sm">Thank you for your business. Please include the invoice number with your payment.</p>
</div>
<div class="mt-3">
<p class="uppercase tracking-wider text-gray-500 text-xs">Terms</p>
<p class="text-sm">Payment due within 14 days. Late payments may incur a 1.5% monthly fee.</p>
</div>
</div>
<div class="sm:justify-self-end w-full sm:w-80">
<div class="rounded-lg ring-1 ring-gray-200 overflow-hidden">
<dl class="divide-y divide-gray-200 text-sm">
<div class="flex items-center justify-between px-4 py-3">
<dt class="text-gray-600">Subtotal</dt>
<dd class="font-medium">$7,629.20</dd>
</div>
<div class="flex items-center justify-between px-4 py-3">
<dt class="text-gray-600">Discount</dt>
<dd class="font-medium">-$250.00</dd>
</div>
<div class="flex items-center justify-between px-4 py-3">
<dt class="text-gray-600">Tax</dt>
<dd class="font-medium">$609.20</dd>
</div>
<div class="flex items-center justify-between px-4 py-3">
<dt class="text-gray-900">Total</dt>
<dd class="text-lg font-semibold">$7,988.40</dd>
</div>
<div class="flex items-center justify-between px-4 py-3 bg-gray-50">
<dt class="text-gray-600">Amount Paid</dt>
<dd class="font-medium">$0.00</dd>
</div>
<div class="flex items-center justify-between px-4 py-3 bg-gray-50">
<dt class="text-gray-900">Balance Due</dt>
<dd class="text-lg font-semibold">$7,988.40</dd>
</div>
</dl>
</div>
<div class="mt-4 flex items-center gap-3 text-xs text-gray-500">
<div class="h-14 w-14 rounded bg-gray-100 flex items-center justify-center">QR</div>
<p>Scan to view invoice online.</p>
</div>
</div>
</div>
</section>
<!-- Acceptance (optional) -->
<section class="px-6 pb-6">
<div class="mt-4 rounded-lg ring-1 ring-gray-200 p-4 text-sm">
<p class="mb-3 text-gray-700">Acceptance</p>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label class="block text-gray-500 text-xs">Authorized Name</label>
<div class="mt-1 h-9 rounded-md ring-1 ring-gray-200"></div>
</div>
<div>
<label class="block text-gray-500 text-xs">Signature</label>
<div class="mt-1 h-9 rounded-md ring-1 ring-gray-200"></div>
</div>
</div>
<div class="mt-3 grid grid-cols-1 sm:grid-cols-3 gap-4">
<div>
<label class="block text-gray-500 text-xs">Title</label>
<div class="mt-1 h-9 rounded-md ring-1 ring-gray-200"></div>
</div>
<div>
<label class="block text-gray-500 text-xs">Date</label>
<div class="mt-1 h-9 rounded-md ring-1 ring-gray-200"></div>
</div>
<div>
<label class="block text-gray-500 text-xs">Email</label>
<div class="mt-1 h-9 rounded-md ring-1 ring-gray-200"></div>
</div>
</div>
</div>
</section>
<!-- Footer -->
<footer class="px-6 py-6 border-t border-gray-200 text-center text-sm text-gray-500">
<p>www.example-website.test</p>
</footer>
</main>
<script>
// Simple HTML download (current document) for convenience
document.getElementById('downloadBtn')?.addEventListener('click', () => {
const blob = new Blob([document.documentElement.outerHTML], { type: 'text/html' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'invoice-demo.html';
a.click();
URL.revokeObjectURL(url);
});
</script>
</body>
</html>
Thank you. I put it into an HTML element on the page and it looks great!
Cool. Kind of like a movie set.