invoice-maschine
v1.0.0
Published
A powerful TypeScript-based PDF invoice generator that creates professional invoices with QR codes for payment, customizable layouts, and support for multiple fonts and styling options.
Readme
Invoice Maschine
A powerful TypeScript-based PDF invoice generator that creates professional invoices with QR codes for payment, customizable layouts, and support for multiple fonts and styling options.
Features
- 📄 Generate professional PDF invoices
- 💳 QR code generation for easy payment processing
- 🎨 Customizable layouts and styling
- 📊 Flexible table structures for line items and totals
- 🖼️ Logo integration with custom sizing and alignment
- 📝 HTML content support in descriptions and text
- 🏷️ Multiple font options (Source Sans 3, Noto, Montserrat, etc.)
- 📍 Fold marks for professional printing
- 🏦 Bank transfer information with structured data
- 🔧 Configurable meta tables for invoice details
- ⚡ Fast development with TypeScript execution
- 🧪 Comprehensive testing suite
Prerequisites
- Node.js (version 18 or higher)
- npm or yarn
Quick Start
1. Clone and Install
git clone <repository-url>
cd invoice-maschine
npm install2. Development Mode (Recommended)
Run the project in fast development mode:
npm run devThis uses tsx for instant TypeScript execution without build steps. Changes are automatically detected and the application restarts.
3. Testing
Run the comprehensive test suite:
npm testTests cover PDF generation, CLI functionality, and various configuration scenarios.
Installation
Via Git Repository
To install this package directly from the Git repository, add it to your package.json:
{
"dependencies": {
"invoice-maschine": "git+https://github.com/goellner/invoice-maschine.git"
}
}Or install via npm:
npm install git+https://github.com/goellner/invoice-maschine.gitVia Local Path
For local development or private repositories:
{
"dependencies": {
"invoice-maschine": "file:../path/to/invoice-maschine"
}
}Usage
Command Line Interface (CLI)
The package can be used as a command-line tool:
# Use demo data (recommended for testing)
node dist/index.js
# Use custom JSON data
node dist/index.js '{"title": "Custom Invoice", "sender": "My Company"}'
# Use JSON from file
node dist/index.js "$(cat my-invoice.json)"
# Development mode (saves to file)
node dist/index.js "$(cat demo.json)" --devProgrammatic Usage
import { generatePDF } from './src/index.js';
const invoiceData = {
title: "Invoice #001",
sender: "My Company / 123 Business St / City, State",
recipient: "Client Name<br>Client Address<br>City, State",
bankTransferInfo: {
accountHolderName: "My Company",
companyIBAN: "AT572011140014400144",
amount: 100.0,
unstructuredReference: "Invoice #001"
},
mainTable: {
columns: [
{ text: "Item", width: "*" },
{ text: "Qty", width: "12mm" },
{ text: "Price", width: "24mm" }
],
rows: [
["Service A", "1", "100.00 €"]
]
},
totalTableRows: [
["", "Total", "100.00 €"]
]
};
// Generate PDF buffer
const pdfBuffer = await generatePDF(invoiceData, false);
// Or save to file
await generatePDF(invoiceData, true);=======
Usage
Command Line Interface (CLI)
The package can be used as a command-line tool:
# Use demo data (recommended for testing)
node dist/index.js
# Use custom JSON data
node dist/index.js '{"title": "Custom Invoice", "sender": "My Company"}'
# Use JSON from file
node dist/index.js "$(cat my-invoice.json)"
# Development mode (saves to file)
node dist/index.js "$(cat demo.json)" --devProgrammatic Usage
import { generatePDF } from './src/index.js';
const invoiceData = {
title: "Invoice #001",
sender: "My Company / 123 Business St / City, State",
recipient: "Client Name<br>Client Address<br>City, State",
bankTransferInfo: {
accountHolderName: "My Company",
companyIBAN: "AT572011140014400144",
amount: 100.0,
unstructuredReference: "Invoice #001"
},
mainTable: {
columns: [
{ text: "Item", width: "*" },
{ text: "Qty", width: "12mm" },
{ text: "Price", width: "24mm" }
],
rows: [
["Service A", "1", "100.00 €"]
]
},
totalTableRows: [
["", "Total", "100.00 €"]
]
};
// Generate PDF buffer
const pdfBuffer = await generatePDF(invoiceData, false);
// Or save to file
await generatePDF(invoiceData, true);Development Workflow
Modern Development Setup
This project uses modern TypeScript development practices:
tsxfor fast development without build steps- Jest for testing with source files
- Clean builds with automatic dist folder cleanup
- ES modules with proper import/export handling
Available Scripts
| Script | Description |
| ----------------------- | -------------------------------------------------- |
| npm run dev | Fast development mode with tsx watch |
| npm run build | Clean build (clears dist, compiles, copies assets) |
| npm run start | Run the built application |
| npm test | Run Jest tests |
| npm run test:watch | Run tests in watch mode |
| npm run test:coverage | Run tests with coverage report |
| npm run clean | Clean the dist folder |
Build Process
The build process is clean and reliable:
- Clean - Removes the entire
distfolder - Compile - TypeScript compilation with proper ES module support
- Resolve - Fixes path aliases and adds
.jsextensions for ES modules - Copy - Copies assets (fonts, demo.json)
JavaScript Usage
// CommonJS
const { generatePDF } = require('invoice-maschine');
// ES Modules
import { generatePDF } from 'invoice-maschine';
const invoiceData = {
title: "Invoice #001",
sender: "My Company / 123 Business St / City, State",
recipient: "Client Name<br>Client Address<br>City, State",
bankTransferInfo: {
accountHolderName: "My Company",
companyIBAN: "AT572011140014400144",
amount: 100.0,
unstructuredReference: "Invoice #001"
},
mainTable: {
columns: [
{ text: "Item", width: "*" },
{ text: "Qty", width: "12mm" },
{ text: "Price", width: "24mm" }
],
rows: [
["Service A", "1", "100.00 €"]
]
},
totalTableRows: [
["", "Total", "100.00 €"]
]
};
// Generate PDF buffer
const pdfBuffer = await generatePDF(invoiceData, false);
// Save to file
await generatePDF(invoiceData, true);TypeScript Usage
import { generatePDF } from 'invoice-maschine';
interface InvoiceData {
title: string;
sender: string;
recipient: string;
bankTransferInfo: {
accountHolderName: string;
companyIBAN: string;
amount: number;
unstructuredReference: string;
};
mainTable: {
columns: Array<{ text: string; width: string }>;
rows: string[][];
};
totalTableRows: string[][];
}
const invoiceData: InvoiceData = {
title: "Invoice #001",
sender: "My Company / 123 Business St / City, State",
recipient: "Client Name<br>Client Address<br>City, State",
bankTransferInfo: {
accountHolderName: "My Company",
companyIBAN: "AT572011140014400144",
amount: 100.0,
unstructuredReference: "Invoice #001"
},
mainTable: {
columns: [
{ text: "Item", width: "*" },
{ text: "Qty", width: "12mm" },
{ text: "Price", width: "24mm" }
],
rows: [
["Service A", "1", "100.00 €"]
]
},
totalTableRows: [
["", "Total", "100.00 €"]
]
};
// Generate PDF buffer
const pdfBuffer: Buffer = await generatePDF(invoiceData, false);
// Save to file
await generatePDF(invoiceData, true);JavaScript Usage
// CommonJS
const { generatePDF } = require('invoice-maschine');
// ES Modules
import { generatePDF } from 'invoice-maschine';
const invoiceData = {
title: "Invoice #001",
sender: "My Company / 123 Business St / City, State",
recipient: "Client Name<br>Client Address<br>City, State",
bankTransferInfo: {
accountHolderName: "My Company",
companyIBAN: "AT572011140014400144",
amount: 100.0,
unstructuredReference: "Invoice #001"
},
mainTable: {
columns: [
{ text: "Item", width: "*" },
{ text: "Qty", width: "12mm" },
{ text: "Price", width: "24mm" }
],
rows: [
["Service A", "1", "100.00 €"]
]
},
totalTableRows: [
["", "Total", "100.00 €"]
]
};
// Generate PDF buffer
const pdfBuffer = await generatePDF(invoiceData, false);
// Save to file
await generatePDF(invoiceData, true);TypeScript Usage
import { generatePDF } from 'invoice-maschine';
interface InvoiceData {
title: string;
sender: string;
recipient: string;
bankTransferInfo: {
accountHolderName: string;
companyIBAN: string;
amount: number;
unstructuredReference: string;
};
mainTable: {
columns: Array<{ text: string; width: string }>;
rows: string[][];
};
totalTableRows: string[][];
}
const invoiceData: InvoiceData = {
title: "Invoice #001",
sender: "My Company / 123 Business St / City, State",
recipient: "Client Name<br>Client Address<br>City, State",
bankTransferInfo: {
accountHolderName: "My Company",
companyIBAN: "AT572011140014400144",
amount: 100.0,
unstructuredReference: "Invoice #001"
},
mainTable: {
columns: [
{ text: "Item", width: "*" },
{ text: "Qty", width: "12mm" },
{ text: "Price", width: "24mm" }
],
rows: [
["Service A", "1", "100.00 €"]
]
},
totalTableRows: [
["", "Total", "100.00 €"]
]
};
// Generate PDF buffer
const pdfBuffer: Buffer = await generatePDF(invoiceData, false);
// Save to file
await generatePDF(invoiceData, true);Development Workflow
Modern Development Setup
This project uses modern TypeScript development practices:
tsxfor fast development without build steps- Jest for testing with source files
- Clean builds with automatic dist folder cleanup
- ES modules with proper import/export handling
Available Scripts
| Script | Description |
| ----------------------- | -------------------------------------------------- |
| npm run dev | Fast development mode with tsx watch |
| npm run build | Clean build (clears dist, compiles, copies assets) |
| npm run start | Run the built application |
| npm test | Run Jest tests |
| npm run test:watch | Run tests in watch mode |
| npm run test:coverage | Run tests with coverage report |
| npm run clean | Clean the dist folder |
Build Process
The build process is clean and reliable:
- Clean - Removes the entire
distfolder - Compile - TypeScript compilation with proper ES module support
- Resolve - Fixes path aliases and adds
.jsextensions for ES modules - Copy - Copies assets (fonts, demo.json)
Configuration
The invoice generator accepts JSON configuration. See demo.json for a complete example:
Basic Configuration
{
"title": "Invoice",
"sender": "Your Company Name / Address",
"recipient": "Client Name<br>Client Address",
"bankTransferInfo": {
"accountHolderName": "Your Company",
"companyIBAN": "AT572011140014400144",
"amount": 100.0,
"unstructuredReference": "Invoice"
}
}Advanced Configuration Options
| Option | Type | Description |
| ------------------ | ------- | --------------------------------------------- |
| title | string | Invoice title |
| sender | string | Sender information |
| recipient | string | Recipient information (supports HTML) |
| font | string | Font family (SourceSans3, Noto, etc.) |
| logo | object | Logo configuration with URL, width, alignment |
| mainTable | object | Line items table configuration |
| totalTableRows | array | Total calculation rows |
| bankTransferInfo | object | Payment information for QR code |
| foldMarks | boolean | Enable fold marks for printing |
| colors | object | Custom color scheme |
| fontSizes | object | Custom font sizes |
Project Structure
invoice-maschine/
├── src/ # TypeScript source code
│ ├── index.ts # Main entry point and CLI
│ ├── fonts.ts # Font configurations
│ ├── components/ # Reusable components
│ │ ├── footer.ts # Footer component
│ │ ├── foldmarks.ts # Fold marks component
│ │ └── invoiceMetas/ # Meta table components
│ ├── helpers/ # Utility functions
│ │ ├── generateQrCode.ts
│ │ ├── ibanHelper.ts
│ │ ├── mmToPoints.ts
│ │ └── parseHtmlToCustomFormat.ts
│ └── types/ # TypeScript type definitions
├── dist/ # Compiled JavaScript (after build)
├── fonts/ # Font files
├── tests/ # Test files
├── demo.json # Example configuration
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
└── jest.config.js # Jest configurationTesting
The project includes comprehensive tests covering:
- ✅ PDF generation with buffer output
- ✅ File saving functionality
- ✅ CLI JSON parsing and argument handling
- ✅ Custom configurations (logo, font, colors, etc.)
- ✅ HTML content processing
- ✅ Table layouts and structures
- ✅ Error handling and edge cases
Running Tests
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage report
npm run test:coverageDependencies
Production Dependencies
pdfmake- PDF generation librarynode-fetch- HTTP client for fetching logosqrcode- QR code generationhtmlparser2- HTML parsing for contentiban- IBAN validation
Development Dependencies
typescript- TypeScript compilertsx- Fast TypeScript executionjest- Testing frameworkts-jest- TypeScript support for Jest@types/*- Type definitionstsc-alias- TypeScript path alias resolution
Troubleshooting
Common Issues
- Font not found: Ensure the
fonts/directory is present - Logo loading fails: Check the logo URL is accessible
- QR code generation error: Verify bank transfer information is complete
- Build errors: Run
npm run clean && npm run build
Development Tips
- Use
npm run devfor fast development feedback - Tests run against source files for better debugging
- The build process is clean and reliable
- CLI works with both demo data and custom JSON
License
UNLICENSED - Private project
Author
Stefan Göllner
Support
For issues and questions, please create an issue on the GitHub repository.
