Files
Document_editor/README.md
2026-06-15 09:18:58 +03:00

4.4 KiB

Document Template Editor

FastAPI + React application for managing Jinja2-annotated .docx document templates.

Features

  • Authentication with JWT (register/login)
  • User roles: user and admin with admin user management panel
  • Initial admin: seeded from .env on startup
  • Template upload: load a .docx file with Jinja2 placeholders
  • Auto-detected form fields: variables become text, textarea, number, date, table cell, or repeating table row fields
  • Style preservation: font, alignment, table cell styles captured from the original document
  • Document preview: render filled template as HTML preview
  • Export: download as .docx or .pdf
  • Reusable templates: fill the same template multiple times

Project Structure

backend/          # FastAPI API
frontend/         # React + Vite UI
samples/          # Sample .docx templates

Quick Start (Docker)

cp .env.example .env
docker compose up --build
Service URL
Frontend http://localhost:5173
Backend http://localhost:8000
API docs http://localhost:8000/docs

Default admin: admin / admin123 (configure in .env).

Stop: docker compose down · Remove data: docker compose down -v

Quick Start (Local)

Requires PostgreSQL running locally (or use Docker only for the database):

docker compose up db -d

Backend

cd backend
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
uvicorn app.main:app --reload --port 8000

Frontend

cd frontend
npm install
npm run dev

Open http://localhost:5173

Create Sample Template

cd backend
source .venv/bin/activate
python ../samples/create_sample_template.py

Jinja2 Syntax in .docx

Use standard Jinja2 in your Word document:

Pattern Purpose
{{ client_name }} Simple text variable
{{ description }} Auto-detected as textarea if name contains "description"
{%tr for item in items %} Repeating table row (docxtpl syntax)
{{ item.product }} Field inside table row loop

Example Table Row

In a Word table row, write:

{%tr for item in items %}
{{ item.name }} | {{ item.qty }} | {{ item.price }}
{%tr endfor %}

The parser detects items as a table_row field and item.name, item.qty, item.price as child table_cell fields with preserved table styles.

API Endpoints

Method Path Description
POST /api/auth/register Register user
POST /api/auth/login Login (OAuth2 form)
GET /api/auth/me Current user
GET /api/users List users (admin)
POST /api/users Create user (admin)
PATCH /api/users/{id} Update user (admin)
DELETE /api/users/{id} Delete user (admin)
GET /api/templates List templates
POST /api/templates Upload template (.docx)
GET /api/templates/{id} Get template with variables
POST /api/documents Create filled document
POST /api/documents/preview Preview without saving
GET /api/documents/{id}/export/docx Export DOCX
GET /api/documents/{id}/export/pdf Export PDF

PDF Export

PDF export uses LibreOffice headless if available:

# ALT Linux / Fedora
sudo apt install libreoffice  # or your distro equivalent

Without LibreOffice, install weasyprint as fallback:

pip install weasyprint

Environment Variables

Create backend/.env:

SECRET_KEY=your-secret-key-here
DATABASE_URL=postgresql+psycopg2://doceditor:doceditor@localhost:5432/doceditor
ADMIN_EMAIL=admin@example.com
ADMIN_USERNAME=admin
ADMIN_PASSWORD=change-me
FRONTEND_URL=http://localhost:5173
CORS_ORIGINS=http://localhost:5173,http://localhost:3000

The admin user is created automatically on startup if it does not exist.

Workflow

  1. Login — use admin credentials from .env, or register as a regular user
  2. Upload Template — select .docx with Jinja2 variables
  3. Fill Form — dynamic form generated from detected variables
  4. Preview — see rendered document with your data
  5. Save & Export — document saved; export as DOCX or PDF
  6. Reuse — use the same template again from Templates list

Tech Stack

  • Backend: FastAPI, SQLAlchemy, docxtpl, python-docx, JWT auth
  • Frontend: React 18, Vite, TypeScript, React Router