Skip to main content

Windows Printing (Shopkeeper App)

The shopkeeper Flutter app on Windows prints silently (no dialog) using SumatraPDF CLI. All files are converted to PDF as needed, then sent to the printer with the requested options (copies, duplex, color, paper size).

File to print

Choose converter by extension

PDF (passthrough or convert)

Check printer availability

SumatraPDF CLI (copies, duplex, color)

Printer Queue

Verify print completion (WMI polling)

Confirm to backend (only after verification)

Converter Engine (by file type)

ExtensionConverterNotes
.pdfPassthroughNo conversion; prints as-is
.png, .jpg, .jpegImage→PDFSingle-page PDF, fit to paper (BoxFit.contain), preserves aspect ratio
.doc, .docxWord→PDFVia LibreOffice headless (portable)
.ppt, .pptxPPT→PDFVia LibreOffice headless (portable)
OtherUnsupportedError with clear message
  • ConverterEngine.chooseConverterByExtension(path) picks the converter.
  • ConverterEngine.ensurePdf(path, paperSize: 'A4') returns the PDF path (converting when needed).

Supported File Types (Platform-Wide)

The same formats are supported across:

  • Backend (upload, calculate-cost, file serving)
  • Frontend (customer dashboard upload)
  • Customer Flutter app (upload)
  • Shopkeeper app (print, including conversion)

Supported: PDF, images (PNG/JPG/JPEG), Word (DOC/DOCX), PowerPoint (PPT/PPTX).

SumatraPDF (Required for PDF Print)

Setup

From shopkeeper_app (or repo root):

cd shopkeeper_app
powershell -ExecutionPolicy Bypass -File scripts/setup_sumatra.ps1

Or run build_windows.bat from shopkeeper_app: it runs SumatraPDF setup, verifies windows/runner/bin/SumatraPDF.exe, then optionally LibreOffice setup, then flutter clean, pub get, run -d windows --release.

The script downloads SumatraPDF portable (64-bit) and places SumatraPDF.exe in windows/runner/bin/. The build copies it next to the app exe (build/windows/x64/runner/Release/).

Lookup

The app looks for SumatraPDF in:

  1. Next to the app executable (Release build)
  2. windows/runner/bin/ relative to current directory (e.g. flutter run)

Manual Install

If setup fails (e.g. network): download SumatraPDF-3.5.2-64.zip, extract SumatraPDF.exe into shopkeeper_app/windows/runner/bin/, then:

cd shopkeeper_app
flutter clean
flutter pub get
flutter build windows

LibreOffice (Optional, for Word/PPT)

Setup

cd shopkeeper_app
powershell -ExecutionPolicy Bypass -File scripts/setup_libreoffice.ps1

Or use build_windows.bat — it optionally runs LibreOffice setup after SumatraPDF.

Already Present

Setup is skipped (no download) when LibreOffice is found at windows/runner/bin/ in any of:

  • LibreOffice/App/libreoffice/program/soffice.exe
  • LibreOfficePortable/App/... (renamed to LibreOffice automatically)
  • App/libreoffice/program/soffice.exe directly in bin/ (App, Data, Other are moved into LibreOffice)

The script downloads LibreOffice Portable version 24.8.7 (~200MB) and extracts to windows/runner/bin/LibreOffice/. The build copies the entire LibreOffice/ folder next to the app exe.

Note: The script may use a fallback version (7.6.4) if the primary version is unavailable. Check the script for current versions.

Manual Install

  1. Open LibreOffice Portable versions.
  2. Download LibreOffice Portable Multilingual Standard (.paf.exe).
  3. Run the installer; choose shopkeeper_app/windows/runner/bin/ as extraction folder (installer creates LibreOfficePortable there).
  4. Rename LibreOfficePortable to LibreOffice.
  5. Ensure LibreOffice/App/libreoffice/program/soffice.exe exists. Then clean rebuild.

Note: LibreOffice is optional. If missing, Word/PPT conversion is disabled; PDF and image printing still work.

Build Script: build_windows.bat

From shopkeeper_app:

build_windows.bat

This:

  1. Runs SumatraPDF setup (or skips if present); verifies SumatraPDF.exe.
  2. Runs LibreOffice setup (or skips if present); renames LibreOfficePortableLibreOffice if needed.
  3. Runs flutter clean, flutter pub get, flutter run -d windows --release.

SumatraPDF is required; the script exits with instructions if not found. LibreOffice is optional.

SumatraPDF CLI Options Used

  • -silent: No dialogs
  • -print-to <printer>: Target printer
  • -print-settings "Nx,duplex|simplex,color|monochrome,fit[,paper=A4]": Copies (Nx), sides, color, fit-to-page, optional paper size

Advanced Features

Printer Status Verification

The app verifies print job completion using Windows Management Instrumentation (WMI):

  • Job Tracking: Monitors print jobs via Win32_PrintJob WMI class
  • Status Polling: Checks job status every 2 seconds for up to 60 seconds (90 for batch prints)
  • Error Detection: Detects printer errors (offline, paper jam, out of toner, etc.)
  • Completion Verification: Only confirms to backend after print is verified as completed
  • File Safety: Files are not deleted until print is verified, allowing retry on failure

Status Codes Monitored:

  • 5 (Printed) - Success
  • 4 (Printing), 18 (Processing) - In progress
  • 8 (Error), 9 (Offline), 10 (PaperOut), 12 (PaperProblem), 22 (NoToner) - Errors

The shopkeeper app supports non-blocking print queue:

  • Queue Multiple Jobs: Shopkeeper can queue multiple prints without waiting
  • Per-Job Printer Selection: Each job can be sent to a different printer
  • Real-Time Status: Print buttons show current state:
    • 🟢 Idle (Pink) - Ready to print
    • 🟠 Queued (Orange) - Job queued
    • 🔵 Printing (Blue) - Currently printing
    • 🟣 Verifying (Purple) - Verifying completion
    • 🟢 Completed (Green) - Successfully completed
    • 🔴 Error (Red) - Failed, can retry
  • Background Processing: Jobs process asynchronously, allowing continued work
  • Automatic Cleanup: Completed states clear after 3 seconds

Printer Availability Check

Before sending a print job, the app verifies printer availability:

  • Pre-Print Validation: Checks if printer exists and is online
  • Fast Failure: Prevents sending jobs to unavailable printers
  • Clear Error Messages: Shows which printer is unavailable
  • Retry Capability: Failed jobs can be retried after selecting a different printer

Optimized Printer Loading

Printer list loading is optimized for performance:

  • Caching: Printer list cached for 60 seconds to avoid frequent queries
  • Lazy Loading: Printers loaded asynchronously after UI loads (non-blocking)
  • On-Demand Refresh: Printer list refreshes when dropdown is opened
  • Timeout Protection: 5-second timeout prevents hanging on slow systems
  • Fallback: Uses cached list if refresh fails

Performance Benefits:

  • App startup is faster (printers load in background)
  • Reduced system calls (cached for 60 seconds)
  • Better UX (no blocking during startup)

Troubleshooting

IssueAction
SumatraPDF not foundRun scripts/setup_sumatra.ps1 from shopkeeper_app (with network). Ensure windows/runner/bin/SumatraPDF.exe exists. If setup fails, download the zip manually and extract there. Then flutter clean and rebuild. Use build_windows.bat to verify before building.
LibreOffice not found (Word/PPT)Run scripts/setup_libreoffice.ps1 (with network, ~200MB). Ensure windows/runner/bin/LibreOffice/App/libreoffice/program/soffice.exe exists. Manual install: see above. LibreOffice is optional; PDF and images work without it.
Unsupported file typeSupported: PDF, images (png/jpg/jpeg), Word (doc/docx), PPT (ppt/pptx). Word/PPT require LibreOffice.
Print failsCheck that the selected printer exists, the PDF path is valid, and the printer is online. The app now checks printer availability before printing.
Print verification timeoutIf verification times out (60 seconds), check printer status manually. The job may have completed but verification couldn't confirm. You can retry the print.
Printer not availableThe app checks printer availability before printing. If a printer is unavailable, select a different printer from the dropdown.
LibreOffice conversion failsCheck input file is not corrupted, LibreOffice is properly extracted, and there is enough disk space for the output PDF.

See also: Setup Instructions (Shopkeeper App Windows), Important Features (File Types).