请参见下方翻译的SKILL.md内容(由于长度限制,以下仅提供关键部分翻译,完整内容请参考原始技能文件)
Overview
This skill generates professional PDF invoices from structured data and templates. Create invoices with company branding, itemized lists, tax calculations, and payment details.
How to Use
- Describe what you want to accomplish
- Provide any required input data or files
- I'll execute the appropriate operations
Example prompts:
- "Generate invoices from order data"
- "Create recurring invoices"
- "Batch generate monthly invoices"
- "Customize invoice templates per client"
Domain Knowledge
Invoice Data Structure
invoice_data = {
"invoice_number": "INV-2026-001",
"date": "2026-01-30",
"due_date": "2026-02-28",
"from": {
"name": "Your Company",
"address": "123 Business St",
"email": "billing@company.com"
},
"to": {
"name": "Client Name",
"address": "456 Client Ave",
"email": "client@example.com"
},
"items": [
{"description": "Consulting", "quantity": 10, "rate": 150.00},
{"description": "Development", "quantity": 20, "rate": 100.00}
],
"tax_rate": 0.08,
"notes": "Payment due within 30 days"
}
PDF Generation with ReportLab
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from reportlab.lib.units import inchdef create_invoice(data: dict, output_path: str):
c = canvas.Canvas(output_path, pagesize=letter)
width, height = letter
# Header
c.setFont("Helvetica-Bold", 24)
c.drawString(1inch, height - 1inch, "INVOICE")
# Invoice details
c.setFont("Helvetica", 12)
c.drawString(1inch, height - 1.5inch, f"Invoice #: {data['invoice_number']}")
c.drawString(1inch, height - 1.75inch, f"Date: {data['date']}")
# From/To
y = height - 2.5inch
c.drawString(1inch, y, f"From: {data['from']['name']}")
c.drawString(4inch, y, f"To: {data['to']['name']}")
# Items table
y = height - 4inch
c.setFont("Helvetica-Bold", 10)
c.drawString(1inch, y, "Description")
c.drawString(4inch, y, "Qty")
c.drawString(5inch, y, "Rate")
c.drawString(6inch, y, "Amount")
c.setFont("Helvetica", 10)
subtotal = 0
for item in data['items']:
y -= 0.3inch
amount = item['quantity'] item['rate']
subtotal += amount
c.drawString(1inch, y, item['description'])
c.drawString(4inch, y, str(item['quantity']))
c.drawString(5inch, y, f"${item['rate']:.2f}")
c.drawString(6inch, y, f"${amount:.2f}")
# Totals
tax = subtotal data['tax_rate']
total = subtotal + tax
y -= 0.5inch
c.drawString(5inch, y, f"Subtotal: ${subtotal:.2f}")
y -= 0.25inch
c.drawString(5inch, y, f"Tax ({data['tax_rate']100}%): ${tax:.2f}")
y -= 0.25inch
c.setFont("Helvetica-Bold", 12)
c.drawString(5inch, y, f"Total: ${total:.2f}")
c.save()
return output_path
HTML Template Approach
from weasyprint import HTML
from jinja2 import Templateinvoice_template = """
| Description | Qty | Rate | Amount |
{% for item in items %}
| {{ item.description }} |
{{ item.quantity }} |
${{ "%.2f"|format(item.rate) }} |
${{ "%.2f"|format(item.quantity item.rate) }} |
{% endfor %}
Total: ${{ "%.2f"|format(total) }}
"""def create_invoice_html(data: dict, output_path: str):
template = Template(invoice_template)
# Calculate total
total = sum(i['quantity'] i['rate'] for i in data['items'])
total = (1 + data.get('tax_rate', 0))
data['total'] = total
html = template.render(data)
HTML(string=html).write_pdf(output_path)
return output_path
Best Practices
- Validate required fields before generation
- Use templates for consistent branding
- Auto-calculate totals (don't trust input)
- Include payment instructions and terms*
Installation
# Install required dependencies
pip install python-docx openpyxl python-pptx reportlab jinja2
Resources