winbill
v2.1.1
Published
Effortlessly generate professional, beautiful PDF invoices and receipts for your Node.js applications.
Maintainers
Readme
winbill
Effortlessly generate professional, beautiful PDF invoices and receipts for your Node.js applications.
winbill allows you to dynamically generate beautiful, customizable PDFs with zero design headaches. Perfect for e-commerce backends, SaaS billing, and freelancer tooling!
Previews
Installation
npm install winbillFeatures
- Advanced Output: Generate directly to a disk file or directly to a memory
Bufferfor modern web streaming (Express, NestJS, Next.js). - Tax & Discount Engine: Supports stacked global taxes and discounts, categorized product/service groupings, and line-item exemptions.
- Interactive Elements & Payments: Automatically renders clickable payment links, embeds QR codes, and dynamically draws complete "How to Pay" Bank Details blocks!
- Document Watermarks: Fully customizable stamp tool for marking documents as "PAID", "DRAFT", "VOID", etc.
- Strictly Typed & Validated: Full TypeScript support with robust
zodvalidation. Invalid payloads throw immediately! - Internationalization & i18n: Native
Intl.NumberFormatsupport for all ISO currency codes, plus a fulltranslationsdictionary to localize static PDF labels. - Theming & Custom Fonts: Inject your own custom
.ttffont paths and define strict brand colors. - Multiple Layouts: Comes out-of-the-box with
DEFAULT,MODERN,MINIMAL, andTHERMAL(80mm POS) templates. - Extensible Architecture: Need a bespoke design? Implement
ILayoutStrategyand inject your own completely custom layout!
Quick Start
import { Winbill, BillingData, GeneratorOptions } from "winbill";
import * as path from "path";
async function run() {
const winbill = new Winbill();
// Generate a random bill number
const invoiceNumber = winbill.generateBillNumber("INV-");
const data: BillingData = {
companyName: "Acme Corp",
companyAddress: ["123 Business Rd.", "Tech City, CA 90210"],
clientName: "Globex Corporation",
clientAddress: "456 Enterprise Way\nSpringfield, IL 62704",
invoiceNumber: invoiceNumber,
date: new Date(),
dueDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000),
currency: "USD",
locale: "en-US",
// Global Taxes
taxes: [{ name: "State Tax", rate: 0.08 }],
// Item Groupings
categories: [
{
name: "Web Services",
items: [
{ description: "Development", quantity: 40, unitPrice: 150.0 },
{ description: "Hosting (Tax Exempt)", quantity: 1, unitPrice: 50.0, isTaxExempt: true }
],
// Category-specific taxes
taxes: [{ name: "Digital Services Tax", rate: 0.05 }]
}
],
// Interactive & Payment Info
paymentDetails: {
paymentUrl: "https://stripe.com/pay/xyz", // Generates clickable link!
qrCodeUrl: "https://stripe.com/pay/xyz", // Automatically renders QR code!
bankDetails: {
bankName: "Global Tech Bank",
accountNumber: "1234567890",
routingNumber: "098765432"
}
},
// Status Stamp
watermark: { text: "DRAFT", color: "#e0e0e0", opacity: 0.3 },
termsAndConditions: "1. All sales are final.\n2. Payment is due within 30 days." // Spawns an appendix page!
};
const options: GeneratorOptions = {
filePath: path.join(__dirname, "invoice.pdf"),
layout: 'DEFAULT',
theme: {
primaryColor: "#005b96",
translations: { invoice: "FACTURE" } // i18n example
}
};
// Generate a PDF File
await winbill.generateBill(data, options);
// Or generate a memory Buffer to stream directly to web clients!
// const pdfBuffer = await winbill.generateBuffer(data, options);
}
run();API Reference
Winbill Class Methods
generateBill(data: BillingData, options: GeneratorOptions): Promise<void>Generates and saves the PDF file to disk (requiresoptions.filePath).generateBuffer(data: BillingData, options: GeneratorOptions): Promise<Buffer>Generates the PDF in memory and returns a Buffer (perfect for web servers).generateBillNumber(prefix?: string): stringHelper method to generate a randomized, alphanumeric bill number.
Interfaces
BillingData
interface BillingData {
companyName: string;
companyAddress?: string | string[];
clientName: string;
clientAddress?: string | string[];
invoiceNumber: string;
purchaseOrderNumber?: string;
date: Date;
dueDate?: Date;
currency: string;
locale?: string;
// Categorized Items
categories?: BillingCategory[];
// Legacy / Flat Items
items?: BillingItem[];
// Global Modifiers
taxes?: Tax[];
discounts?: BillingDiscount[];
logoPath?: string;
notes?: string;
termsAndConditions?: string;
// Interactive Elements (Not allowed on Receipts)
paymentDetails?: {
paymentUrl?: string;
qrCodeUrl?: string;
bankDetails?: {
accountName?: string;
accountNumber?: string;
bankName?: string;
iban?: string;
swift?: string;
routingNumber?: string;
}
};
watermark?: {
text: string;
color?: string;
opacity?: number;
fontSize?: "xsmall" | "small" | "medium" | "large" | "xlarge";
};
// Convert document into a Receipt
receipt?: ReceiptSettings;
}GeneratorOptions
interface GeneratorOptions {
filePath?: string; // Required for generateBill()
layout?: 'DEFAULT' | 'MODERN' | 'MINIMAL' | 'THERMAL';
theme?: {
primaryColor?: string;
customFontPath?: { regular: string, bold: string }; // Use absolute paths to .ttf
translations?: {
invoice?: string;
receipt?: string;
invoiceNumber?: string;
poNumber?: string;
date?: string;
dueDate?: string;
from?: string;
billTo?: string;
description?: string;
qty?: string;
unitPrice?: string;
total?: string;
subtotal?: string;
};
};
}License
Licensed under GPL-3.0.
