Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Choose a PDF-generation approach based on how your application is built and how you want to author document layouts: use ReportLab for Python drawing and reporting layouts, WeasyPrint when your Python team already works in HTML and CSS, or PDFKit for JavaScript in Node or the browser. Keep calculations and business rules in application code, then render their results into the PDF. None of these libraries makes an invoice legally compliant by itself; verify required fields, tax treatment, numbering, and retention rules for your jurisdiction and business.

Choose the approach that fits your application

There is no universally best PDF library among these options. The key choice is whether you want to place PDF elements directly, describe a flowing document in HTML and CSS, or stay within a JavaScript PDF API. The official documentation describes capabilities and examples, but it does not provide controlled performance comparisons among the libraries.

Option Runtime Authoring model Useful fit Output pattern
ReportLab Python Drawing commands and higher-level layout tools Precisely positioned content, reports with charts and tables, and Python reporting workflows PDF canvas and layout APIs
WeasyPrint Python HTML and CSS templates rendered to PDF Teams that already author documents as HTML/CSS and need flowing layouts Write to a file or writable object, or return PDF bytes
PDFKit JavaScript: Node or browser JavaScript PDF-generation API Applications that need PDF output within a JavaScript codebase Node readable stream; browser has distinct in-memory file and font handling

ReportLab’s documentation describes both low-level drawing and higher-level layout, including charts, tables, and examples of invoices and reports. WeasyPrint takes HTML/CSS input through a Python API. PDFKit uses a stream-oriented model in Node; its browser build has different file and font requirements. Read the respective official guides for the implementation details: ReportLab introduction, WeasyPrint first steps, and PDFKit getting started.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep business data separate from document rendering

Represent report and invoice facts as structured data, and calculate amounts, tax, discounts, and other business rules in the application layer. Pass the resulting values to the renderer; do not make layout code the authority for financial calculations. ReportLab’s demos include a JSON-to-PDF invoice project, while WeasyPrint’s invoice-oriented example says its sample data must be adapted for real invoices.

#1 Best Overall
NDYIN Portable Printers Wireless for Travel, N80 Bluetooth Thermal Printer
  • Wireless Bluetooth Printer: Portable thermal printer compatible with iPhone, Android phones, iPad and tablet computers via Bluetooth. For smartphones, please download the "Nada Print" App. You can also connect to laptops and computers for printing using a USB-C cable. (Note: Laptops and computers can only be connected via USB and require the installation of a driver first. Bluetooth connection is not supported.)
  • No-ink printing: Only supports US Letter and A4 size thermal paper.(Doesn't support regular paper) The no-ink portable thermal printer uses direct thermal technology, requiring no ink, toner or ribbons, making it environmentally friendly, cost-effective and time-saving. The thermal printer package comes with a roll of US Letter thermal printing paper. Note: When installing the paper, remember to switch the paper size switch on APP
  • Clear Print: NDYIN N80 portable thermal printer adopts high-definition printing technology, with a 203DPI resolution to provide you with clear printing results. This mobile printer is compatible with roll paper, folded paper and tattoo transfer paper, supporting printing from your mobile phone PDF, Word, pictures and web pages anytime and anywhere. It is recommended to use our NDYIN thermal paper to achieve good printing quality
  • Portable wireless printer for travel: The thermal printer is equipped with a built-in 1500mAh rechargeable battery, which can print 160 sheets of 8.5" x 11" thermal paper after being fully charged. It weighs only 1.5 pounds and is compact in size. This ink-free portable printer can be easily carried in a backpack or briefcase! It is perfect for business travel, cars, small offices, construction sites, schools and homes. You can print documents, contracts, invoices and boarding passes anytime and anywhere
  • The N80 thermal printer has a wide range of uses. The package includes the N80 printer, a roll of US Letter paper(7m/roll), a user manual, a guide card, a type-C soft cable and a type C adapter. Note: The charging adapter is not included. Special thermal paper is required for use; ordinary paper cannot be used. This ink-free portable thermal printer is suitable for various scenarios such as home, school, travel, office, and outdoor, meeting the printing needs of different groups of people. This tattoo template printer is also compatible with tattoo transfer paper, making it an ideal choice for tattoo art

A minimal invoice data model might include an identifier, issue date, seller and customer details, line-item descriptions, quantities, unit prices, tax values, and totals. The exact fields and computations depend on your business and jurisdiction, so treat this as an application-design example, not a legal checklist.

invoice = {
    "number": "INV-1042",
    "issue_date": "2026-09-29",
    "customer": {"name": "Example Customer"},
    "items": [
        {"description": "Implementation work", "quantity": 3, "unit_price": "125.00"}
    ],
    "subtotal": "375.00",
    "tax": "0.00",
    "total": "375.00"
}

Use an appropriate decimal representation and explicit rounding policy for monetary calculations. The example uses strings to avoid suggesting that binary floating-point values are a suitable accounting representation. Your application should define how it handles currency, rounding, missing information, tax, and adjustments before producing the document.

Create a PDF with ReportLab in Python

ReportLab’s pdfgen canvas is a direct drawing API: issue commands to paint text and shapes, finish each page with showPage(), then finish the document with save(). The default coordinate origin is at the lower-left. Page dimensions are expressed in points, with 72 points per inch. Choose a page size explicitly because A4 and US Letter are not the same size. See the graphics and text guide.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Install and run a small invoice example

The official open-source installation instructions use pip install reportlab. They state that ReportLab has been pure Python since version 4.0, with optional extras for acceleration and graphics functions; confirm any optional requirements for your target environment in the current installation instructions.

python -m pip install reportlab
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas

invoice = {
    "number": "INV-1042",
    "customer": "Example Customer",
    "items": [
        ("Implementation work", 3, "125.00", "375.00"),
    ],
    "total": "375.00",
}

pdf = canvas.Canvas("invoice.pdf", pagesize=A4)
page_width, page_height = A4
left = 48

def draw_heading():
    pdf.setFont("Helvetica-Bold", 18)
    pdf.drawString(left, page_height - 54, "Invoice")
    pdf.setFont("Helvetica", 10)
    pdf.drawString(left, page_height - 76, f"Number: {invoice['number']}")
    pdf.drawString(left, page_height - 92, f"Bill to: {invoice['customer']}")


draw_heading()
y = page_height - 132
pdf.setFont("Helvetica-Bold", 10)
pdf.drawString(left, y, "Description")
pdf.drawRightString(page_width - 170, y, "Qty")
pdf.drawRightString(page_width - 95, y, "Unit price")
pdf.drawRightString(page_width - left, y, "Line total")
y -= 18
pdf.setFont("Helvetica", 10)

for description, quantity, unit_price, line_total in invoice["items"]:
    if y < 72:
        pdf.showPage()
        draw_heading()
        y = page_height - 132
        pdf.setFont("Helvetica", 10)
    pdf.drawString(left, y, description)
    pdf.drawRightString(page_width - 170, y, str(quantity))
    pdf.drawRightString(page_width - 95, y, unit_price)
    pdf.drawRightString(page_width - left, y, line_total)
    y -= 18

pdf.setFont("Helvetica-Bold", 11)
pdf.drawRightString(page_width - left, y - 12, f"Total: {invoice['total']}")
pdf.showPage()
pdf.save()

This example draws a simple table-like arrangement and starts another page when rows reach a chosen vertical threshold. It intentionally does not attempt text wrapping, sophisticated table layout, or jurisdiction-specific invoice rules. For reports or invoices with variable-length content, repeated tables, charts, and more complex pagination, evaluate ReportLab’s higher-level layout facilities and examples rather than adding every layout rule manually. Its official demos include invoice and fund-report projects.

Rank #2
Rongta Bluetooth Shipping Label Printer, Wireless 4x6 Thermal Label Printer for Shipping Packages, Support Phones, Compatible with Windows macOS Android iOS for Small Business
  • Wireless Bluetooth Connectivity for Flexible Use: The RONGTA RP425 Bluetooth thermal shipping label printer is fully compatible with iOS and Android phones/tablets. Simply download the "RONGTA" App from the App Store or Google Play, connect via Bluetooth through the App, and start printing instantly
  • Automatic Label Identification: Rongta shipping label printer automatically detects, grabs, and feeds labels, eliminating manual adjustment hassle. It supports all direct thermal labels with a width range of 0.98" to 4.37", covering common sizes such as 4x6" shipping labels, 2x2" circular labels, 2x1" barcode labels, and 1x1" QR code labels
  • Easy Installation for Multiple Systems: The Windows and Mac driver software is available on Rongta official website for easy setup. Compatible with Windows 7 and newer, Mac OS 10.11 and newer, and Chrome OS
  • Compact and Portable Design: The Rongta thermal label printer features a space-saving compact build with dimensions of 10.2 x 7.4 x 5.3 inches, making it easy to store anywhere on your desk, in a drawer, or during travel
  • High-Speed Printing Performance: Features fast printing speed of up to 150 mm/s with 203dpi resolution and thermal printing method, ensuring efficient label production for warehouses, offices, and on-the-go use

Render HTML and CSS to PDF with WeasyPrint

WeasyPrint is a fit when the document is naturally represented by HTML templates and print-oriented CSS. Its Python API can render HTML from a string and write the result to a PDF file. The docs also describe returning bytes or writing to a writable object. They suggest a long-lived Python process when generating many documents, to avoid repeated startup costs.

Runnable Python example

Install the package in the environment following the official first-steps guide, which also covers platform installation considerations. Then render a small HTML invoice:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
from html import escape
from weasyprint import HTML

invoice = {
    "number": "INV-1042",
    "customer": "Example Customer",
    "items": [
        {"description": "Implementation work", "quantity": 3, "line_total": "375.00"},
    ],
    "total": "375.00",
}

rows = "".join(
    "<tr>"
    f"<td>{escape(item['description'])}</td>"
    f"<td>{escape(str(item['quantity']))}</td>"
    f"<td>{escape(item['line_total'])}</td>"
    "</tr>"
    for item in invoice["items"]
)

html = f"""


  
  


  

Invoice

Number: {escape(invoice['number'])}
Bill to: {escape(invoice['customer'])}

{rows}
DescriptionQtyLine total

Total: {escape(invoice['total'])}

""" HTML(string=html).write_pdf("invoice.pdf")

Escape or otherwise safely encode values inserted into HTML. The documentation warns that untrusted HTML or CSS can create security problems. It also notes that unsupported CSS properties can produce warnings. Do not assume every browser CSS behavior or JavaScript feature is supported: verify the layout and features you need against the current WeasyPrint documentation and rendered output.

Attachments and invoice-related formats

WeasyPrint’s documented common-use case demonstrates rendering invoice HTML, attaching Factur-X XML as associated data, adding XMP metadata, and writing a PDF/A-3 variant. The page explicitly says its sample data must be adapted to real invoices; the example is a technical rendering illustration, not a statement of invoice law in any jurisdiction. See the WeasyPrint common use cases.

Rank #3
Portable Printers Wireless for Travel, A285M Small Inkless Thermal Printer
  • Portable Printers Wireless for Travel [Compact & Space-saving]: The portable printer weighs only 1.5lb and is small in size. This inkless portable printer fits easily into a backpack or briefcase! Ideal for on-the-go printing during business travel, in car or truck, small office, construction site, school and home use. You can print documents, contracts, invoices, receipts, recipes, lists and boarding passes anytime, anywhere
  • Wireless Bluetooth Printer [High Compatibility]: The portable thermal printer compatible with iPhone, Android Phone, iPad, Tablet via Bluetooth. Print documents, pictures, web pages from your phone anytime, anywhere. You can also use the USB-C cable to connect your laptop or computer for printing. (Note: Laptops and computers only work with USB connection, need to download the driver first: a285m.labelife.cc)
  • Thermal Printer [Multi-Size Printing]: The wireless portable printer with built-in paper bin, support thermal roll paper, continuous and single sheet thermal paper. A285M small wireless printer also supports 5 sizes of thermal paper: 8.5“ X 11” US Letter, A4, 4.33'' (110mm), 3.14'' (80mm), 2.08'' (53mm) width thermal paper, can meet most of your needs
  • Inkless Printer [Cost-Effective & Inkless Printing]: The Bluetooth mobile printer adopts advanced thermal technology, no ink, toner, or ribbon required during printing, no clogging and cleaning problems! (Note: Only support the thermal paper, Does not support regular copy paper. Only supports black and white printing.)
  • Mobile Printer [High Quality Printing]: The compact printer is designed for people who work outside. A wireless inkless portable printer is good for mobile notaries, truck drivers, business travelers, office workers, teachers and students. Note: Charging with 5V 2A. Don't use the charger that outputs above 5V

Generate PDFs with PDFKit in JavaScript

PDFKit supports Node and browser use. In Node, a PDFDocument is a readable stream: the documentation shows piping it to a file or HTTP response and calling end() after adding the document content. The first page is created automatically unless disabled; add later pages explicitly.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Node.js example writing a PDF file

Install PDFKit using the package instructions in its getting-started guide, then use a writable stream for the output:

const fs = require('node:fs');
const PDFDocument = require('pdfkit');

const invoice = {
  number: 'INV-1042',
  customer: 'Example Customer',
  items: [
    { description: 'Implementation work', quantity: 3, lineTotal: '375.00' },
  ],
  total: '375.00',
};

const doc = new PDFDocument({ size: 'A4', margin: 48 });
doc.pipe(fs.createWriteStream('invoice.pdf'));

doc.fontSize(20).text('Invoice');
doc.moveDown(0.5);
doc.fontSize(10).text(`Number: ${invoice.number}`);
doc.text(`Bill to: ${invoice.customer}`);
doc.moveDown();

doc.font('Helvetica-Bold');
doc.text('Description', 48, doc.y, { continued: true, width: 260 });
doc.text('Qty', { continued: true, width: 45, align: 'right' });
doc.text('Line total', { align: 'right' });
doc.moveDown(0.5);
doc.font('Helvetica');

for (const item of invoice.items) {
  doc.text(item.description, 48, doc.y, { continued: true, width: 260 });
  doc.text(String(item.quantity), { continued: true, width: 45, align: 'right' });
  doc.text(item.lineTotal, { align: 'right' });
}

doc.moveDown();
doc.font('Helvetica-Bold').text(`Total: ${invoice.total}`, { align: 'right' });
doc.end();

For a web endpoint, pipe to an HTTP response instead of a file stream, and ensure your response handling waits for the stream to finish or reports errors. The library’s stream design makes output integration a key part of the implementation, not an afterthought.

Browser-specific setup is not identical

The browser build cannot read files directly from the file system. The guide demonstrates registering file bytes in memory, and the default font metrics also need registration in the browser build. Follow the browser-specific setup in the official guide rather than copying Node filesystem code unchanged.

Plan pagination, fonts, output, and metadata

Choose layout and output behavior deliberately before relying on generated documents in production. The relevant choices depend on your renderer, but the same review questions apply:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
Sunydog Thermal Printer, Mini Thermal Receipt Printers, Portable USB Receipt Bill Ticket Printer with 58mm Print Paper Roll, Fit for Android for Win, Receipt Printer for Retail Sale Stores Restaurant
  • Before Purchase, Please NOTE: Not supported for OS; Not compatible with Square POS system. NOTE: Applicable smartphone APP - Loyverse (Retail/Clothing), iREAP (Retail/Inventory), CasierStock (Shopping/Inventory Management), Kyte (Mobile Sales), etc.. Please make sure your cellphone is compatible with these softwares.
  • Effortless Connectivity: This thermal printer supports both BT and USB cable connections, fit for Android and fit for Win with maximum flexibility. For smartphones, download the compatible APP, click and enter into the APP and use the BT function to connect to the printer. For computers, please use the USB cable to connect to the computer and download the pionted driver.
  • High-Speed & High-Resolution Printing: Achieve exceptional clarity with 203dpi resolution and swift business operations with a maximum print speed of 70mm/s from this thermal receipt printer, which has been equipped with 58mm wide print paper and 1 USB cable.
  • No-Ink & Cost-Effective Operation: Utilizing an advanced thermal print head, this USB ticket printer requires no ink, toner, or ribbons, ensuring sharp printing and significantly lower long-term costs. which also has been built in with a 1500mAh rechargeable battery, allowing you to print on the go, anytime and anywhere.
  • Universal Application: Ideal for a vast range of businesses including supermarkets, restaurants, retail stores, and more, this versatile thermal printer is an ideal fit for all your receipt printing needs.
  • Page size: set it explicitly. ReportLab documents page dimensions in points and calls out the distinction between A4 and US Letter.
  • Pagination: decide how headings, table headers, long descriptions, totals, and footers behave when content spills across pages. Fixed-coordinate drawing requires you to implement those decisions; layout engines and HTML print styles offer different tools, not automatic correctness.
  • Fonts and characters: select fonts that support the characters in your data and check font registration rules for the chosen runtime. In particular, PDFKit’s browser build has separate font-metric setup.
  • Output destination: choose a file, in-memory bytes, writable object, or stream/HTTP response according to the library and application. WeasyPrint documents files, writable objects, and bytes; PDFKit documents Node streams.
  • Metadata and attachments: determine whether the deliverable needs document metadata, associated data, or a PDF/A variant. WeasyPrint’s documented example covers XMP metadata and an associated Factur-X XML attachment.
  • Input safety: treat user-controlled content as data, not trusted markup. WeasyPrint specifically warns about security risks from untrusted HTML or CSS.

Before release, render representative application inputs and inspect the actual files. Include long descriptions, multiple pages, non-ASCII text, missing or unusual fields, and large data sets. These are implementation checks, not results of a comparative test. The cited documentation describes relevant page-size, font, stream, and metadata capabilities, but does not establish a universal renderer-performance ranking.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot common implementation failures

Content runs off the page or overlaps

With direct drawing, coordinates and available page space are your responsibility. Track the vertical position, wrap or truncate content deliberately, and create a new page before drawing below the margin. With HTML/CSS, inspect the rendered result and warnings, then simplify or replace unsupported styling. Test the longest real descriptions rather than only short sample rows.

The output is the wrong paper size

Set the page size explicitly and confirm the renderer’s units or named-size behavior. A4 and US Letter differ; a layout sized for one can clip or leave unwanted space on the other.

Characters render incorrectly

Review the selected font’s character coverage and how fonts are loaded in the runtime. For PDFKit in a browser, use its documented in-memory font registration and font-metric setup instead of relying on Node file access.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

WeasyPrint emits CSS warnings or unsafe input is involved

A warning can indicate that a CSS property is unsupported; confirm whether the property is necessary and inspect the output. Sanitize or constrain untrusted markup and styles before rendering, because the docs warn that they can create security problems.

Best Value
KNAON Bluetooth Thermal Shipping Label Printer, 4x6 Portable Thermal Address Label Printer for Small Business, Compatible with iPhone,Android,Windows,Mac–Works with Etsy Shopify USPS&More, White
  • Bluetooth Wireless Connection: KNAON Bluetooth shipping label printer enables wireless printing. For Mobile users, download the 'FlashLabel Pro' app from APP Store or Google Play for printing. Also, supports Windows and macOS, and can directly connect to the printer by downloading the 'FlashLabel Pro' App. Windows 7 or later computers can also print via Bluetooth by installing the latest advanced driver. Note: All devices CANNOT be connected directly to Bluetooth, and must be used through the 'FlashLabel Pro' app.
  • USB Cable Connectivity: This printer ensures seamless USB connectivity with macOS, Windows (7 and above), ChromeOS, and Linux. KNAON printer features a built-in USB drive preloaded with drivers and tutorial videos for a fast and hassle-free setup. For ChromeOS, need to install 'FlashLabel' extension to your Google Chrome.
  • Versatile DIY Labeling Options: KNAON Thermal Shipping Label Printer offers a vast selection of pre-designed templates, including 3,000+ templates, 5,000+ icons, and 100+ fonts available in the app. Designed for both professional and personal use, it supports various thermal paper sizes, ensuring effortless customization for all your labeling needs. Ideal for printing DIY shipping labels, barcode labels, thank-you labels, mailing labels, name tags, price tags, and various small thermal labels.
  • Seamless Multi-Platform Compatibility: This Bluetooth shipping label printer works effortlessly with all major platforms, including Amazon, eBay, Shopify, USPS, UPS, Etsy, PayPal, Poshmark, DHL, and more, ensuring smooth and efficient label printing. (Note: Save the logistics label as a PDF file on the shipping platforms, then import it into the 'FlashLabel Pro' app for printing).
  • Portable & Stylish Design: KNAON multi-function thermal label printer offers user-friendly operation in a compact design. Its perfect size (7.17 x 3.9 x 3.43 inches) makes it simple to store anywhere. With a fast printing speed of up to 180 mm/s and support for paper widths from 1.5 to 4.2 inches. The package also includes 10 test printing papers to get you started right away.

Node output is incomplete

PDFKit writes through a stream. Pipe the document to a valid writable destination and call end() after adding content. In an HTTP handler, handle stream errors and completion so the application does not treat a partial response as a finished PDF.

Repeated PDF jobs incur avoidable startup work

For many WeasyPrint documents, the documentation suggests keeping a long-lived Python process to avoid repeated startup costs. This is an operational consideration, not a published comparative benchmark for throughput against other libraries.

Or skip the browser setup

If what you need is a screenshot of a rendered web page rather than a document assembled from application data, ScreenshotNeo offers a website screenshot API and MCP server. It is not a replacement for generating a structured invoice PDF from business records. One GET request can return a screenshot or PDF of a URL:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for request options. Cookie banners, newsletter popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000. Sign up for ScreenshotNeo’s free plan.

Checklist before shipping

  1. Keep the canonical invoice or report data and calculations in application code.
  2. Choose ReportLab, WeasyPrint, or PDFKit based on runtime and preferred layout model.
  3. Set page dimensions, font behavior, pagination, output destination, and metadata requirements explicitly.
  4. Render real edge cases, including long text, multiple pages, non-ASCII characters, missing values, and large data sets.
  5. Check tax, invoice fields, numbering, and retention obligations against the rules for the relevant jurisdiction and business context.

Frequently Asked Questions

Can I use these libraries to generate invoices in a web application?

Yes. ReportLab documents dynamic web PDF generation as a use case, WeasyPrint exposes a Python API, and PDFKit can pipe a Node-generated PDF to an HTTP response. Choose the integration pattern for your runtime and handle output errors and completion.

Which option is fastest?

The cited official documentation does not provide a controlled comparison of ReportLab, WeasyPrint, and PDFKit, so it does not support a speed ranking. Measure representative documents in your own deployment if throughput is a deciding requirement.

Does a generated PDF automatically satisfy invoice laws?

No. Rendering examples demonstrate PDF production, not compliance. Verify required invoice fields, tax handling, numbering, and record-retention obligations for the relevant jurisdiction and business context.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.