Bulk Document Generator — local Python edition

1. Extract the complete ZIP into a folder.
2. Install Python 3.11 or later.
3. Open a terminal in that folder and run:
   python -m pip install -r requirements.txt
4. Run:
   python server.py
5. The browser opens http://127.0.0.1:8765.

Use the same interface for all 15 workflows. Pandas cleaning, PostgreSQL
connections and direct file moves/renames are enabled by the local server.
Browser document generation and SQLite require no Python API calls.

POSTGRESQL
Enter connection details in the database tool. The database must already exist.
Imports create new tables; existing tables cannot be replaced. Credentials
are sent to the local Python server per request and are not saved. The remote
PostgreSQL server receives the records you explicitly import.

DISK OPERATIONS
Choose a folder using the system dialog, load the Excel mapping, and choose
Review & apply on disk. Only files inside that chosen folder can be used.
The preview must be confirmed before changes are applied. Destinations that
already exist are rejected. Rename and Sort move sources; Create Client Folders
copies originals and adds a record.json file. Missing/ambiguous file matches
are rejected. Source changes since the preview invalidate the plan.

FILE FORMATS AND LIMITS
Up to 200,000 spreadsheet rows across loaded tables. Up to 2,000 individual
documents per batch. Up to 400 MB of generated documents or 500 MB of supporting
files per browser batch. The first row of every worksheet contains headers.
PDF text is rendered as page images to support Unicode and bidirectional text.
Choose Word output for editable text. CSV text cells that look like spreadsheet
formulas receive a leading apostrophe; Excel text cells never become formulas.

PRODUCT IMAGES
Upload PNG/JPEG/WebP/GIF files matching the image column or use HTTP(S) image
URLs. Uploaded images are embedded, so product pages work independently.
URL-based images contact their external host when the exported page is opened.

TEMPLATES
Use {{name}}, {{amount}}, {{date}}, {{course}}, {{grade}}, {{email}}, {{row}}
or any exact spreadsheet column name. Map columns using the tool's dropdowns.
Invalid document rows are listed in generation-errors.csv; valid rows continue.
Email outputs are .eml drafts only. No email is sent by this tool.

SOURCE
Inspired by the return-value example in function_return.py. greet() remains in
server.py; data transformations are implemented with Pandas, Regex and SQLAlchemy.
Third-party libraries and their licenses are in vendor/.
