REAL BUILD · JAVASCRIPT
Build an Invoice Generator with JavaScript and Print to PDF
Turn a list of services into a readable invoice preview, then use the browser print dialog to save a PDF. No PDF API key, upload service or third-party script is required.
Try the working MVP
Sample document only. Enter fictional data while testing. Refreshing clears everything.
Describe the result, then build it
A local invoice draft with business/customer names, issue date, invoice number, editable line items, a configurable demo tax percentage and a printable preview.
- Define the document fields and a single currency. Use a sample invoice number until a server can assign authoritative unique numbers.
- Add or remove line items. Each row has a description, positive quantity and non-negative unit rate.
- Calculate rounded line totals in cents, add them to a subtotal and round the single document-level tax amount.
- Generate the preview, inspect it, then choose Print / Save as PDF. In the browser dialog select the PDF destination and review page size and headers.
Build your version with AI
Copy this prompt into your preferred coding assistant. It is a starting specification, not an assurance that generated code is correct.
Create a vanilla JavaScript invoice draft generator. Include seller, buyer, invoice number, date, removable line items, USD amounts, integer-cent line rounding and a single configurable demo tax percentage. Render all user text safely. Add print CSS and a browser Save as PDF workflow. Reject an empty item list. Do not claim tax compliance or send/store documents.
Review the first draft
Ask next: “Explain each function and its inputs. Identify assumptions that could change the result. Add tests for the edge cases below, then show me the exact files you changed.” Run the tests yourself before replacing the working version.
Understand the important code
invoice() computes a subtotal, tax and total from item data. The renderer creates paragraphs and inserts customer text with textContent, so typed markup remains text. The print stylesheet exposes only #invoice-preview and hides the rest of the tutorial.
The tools share one dependency-free script. Its pure functions also run in Node; browser setup only runs when a document exists. This keeps arithmetic and parsing testable without a server.
Full runnable source
This page is the runnable implementation. Reuse its demo markup, the shared script and stylesheet. No build step, API key or database migration is needed.
Copy the demo HTML
<div data-business-tool="invoice"><p>Sample document only. Enter fictional data while testing. Refreshing clears everything.</p><form id="tool-form"><label>Your business <input id="seller" maxlength="200" required value="Example Studio"></label><label>Customer <input id="buyer" maxlength="200" required value="Example Customer"></label><label>Invoice number <input id="invoice-number" maxlength="50" required value="DEMO-001"></label><label>Issue date <input id="invoice-date" type="date" required></label><table><thead><tr><th>Description</th><th>Quantity</th><th>Unit price (USD)</th><th>Action</th></tr></thead><tbody id="items"></tbody></table><button type="button" id="add-item">Add item</button><label>Demo tax (%) <input id="tax" type="number" min="0" max="100" step="0.01" value="0" required></label><button>Generate preview</button></form><button type="button" id="print-invoice" hidden>Print / Save as PDF</button><div id="invoice-preview" aria-live="polite"></div><p id="tool-status" role="status"></p></div>For a standalone page, place the markup inside a normal HTML document, link business_tools.css in the head, and load business_tools.js with defer. Keep the IDs unchanged; include only one tool per page.
<link rel="stylesheet" href="business_tools.css">
<script src="business_tools.js" defer></script>Test the result before publishing
Two units at USD 50 with a demo tax rate of 10% must produce subtotal 100, tax 10 and total 110. Remove every item and check the error. Type <script> in a name: it must appear as text. Print a long document and inspect every page.
Check keyboard navigation, narrow screens and the browser console. In this repository run node tests/business_tools.test.cjs for the calculation/parser checks and python manage.py test for Django routes and rendering.
Publish it
For a standalone tool, upload your HTML, CSS and JavaScript to a static host, enable HTTPS and test the deployed URL. No backend is needed for these local demos.
For this Django site, merge the reviewed branch, install the pinned requirements in your existing virtual environment, run the commands below from the project root and restart the existing Gunicorn service using its configured service name. Nginx must serve STATIC_ROOT at /static/. No new secrets are required.
python manage.py check
python manage.py test
python manage.py collectstatic --noinputAfter restarting, open /en/tools/invoice-generator/, confirm the script and stylesheet return 200, test the demo and check /sitemap.xml. Keep the previous release available for rollback. These instructions do not deploy the site automatically.
Limits and production decisions
This is a draft document tool, not an accounting or tax-compliance system. It does not issue legally compliant invoices, verify identities, assign unique numbers, collect payments, retain records or send email. Tax is only a user-entered arithmetic example. Printed pagination varies by browser; test long names and many rows before adopting the layout.
This page makes no network request with tool input and does not write it to local storage. Data disappears on refresh. Browser extensions and scripts added by your own deployment may change that boundary; review them before processing sensitive information.
ADAPT THIS FOR YOUR BUSINESS
Need invoices generated from real orders?
Describe your order source, document fields, numbering requirements and accounting destination in the project brief. Ask How2Code to connect a branded document workflow to your existing system.
Describe the adaptation →Tell us what you need. We’ll review your brief and discuss the scope before starting work.