Skip to content

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FormForge

Fill scanned paper forms from a template. Upload a blank form image, draw boxes where text or marks should go, save it as a reusable template, then generate filled copies one at a time or in bulk from an Excel sheet. Arabic (right to left, properly shaped) and English work in the same box.

FormForge demo

Features

  • Visual editor: draw field boxes directly on your form image.
  • Field types:
    • Text (Arabic or English, direction detected automatically)
    • Date (one box with separate day / month / year slots, so you fill printed cells without a hardcoded separator)
    • Multiple choice (places a mark on the selected option; styles: x, check, circle, dot)
    • Number cells (one digit per box, for ID or phone numbers)
  • Per box font and color pickers, so you can see and change what each box uses.
  • 3D depth: drag a box's corner handles to tilt the text into the page's plane (perspective warp), for forms that were photographed or scanned at an angle.
  • Multi page templates: one template can hold several base images. Each row of your sheet generates that row's pages in sequence.
  • Reusable named templates, tied to the form image by content hash.
  • Bulk generation from an .xlsx: one row per form, output named by a serial column or by row number.
  • Runs as a desktop window or in the browser.

Requirements

  • Python 3.10 or newer
  • pip install -r requirements.txt
  • At least one font file in workspace/fonts/ (any .ttf or .otf). Drop the file in and it shows up in the per box font dropdown. The workspace/ folder is created automatically on first run.
  • To make filled forms look hand written rather than typed, use an Arabic handwriting font (a flowing ruqaa or script face) rather than a print naskh. Check that it includes Arabic-Indic digits if you fill numbers with it, since some display and demo fonts ship letters only. Handwriting faces are usually more compact than print ones, so expect to raise the font size by roughly a sixth to keep the same visual height.

Run

Desktop window:

python run.py

Or in a browser:

python -m formforge.server
# then open http://localhost:8000

Using it

  1. Upload your blank form image (Base img). It belongs to the current page.
  2. Switch to Define boxes, pick a box type, and drag rectangles on the form.
    • Date: place the day, month, and year slots.
    • Multiple choice: place a mark box for each option and pick the mark style.
    • Number cells: set how many cells.
  3. Set each box's font and color from its dropdowns.
  4. For depth, press 3D on a box, then drag its corner handles on the form until the text sits in the plane of the paper. Press flat to undo it.
  5. For a multi page form, press + in the Pages bar. The new page starts with the same box places as page 1 (values cleared), so a second copy of the same form needs no redrawing: just upload that page's base image. Boxes that keep their name share one spreadsheet column and get the same value on both pages, which is what you want for a carbon copy; rename a box to give that page its own value, or move and delete boxes freely since each page keeps its own copy. Press + blank for a page with no boxes. Switch pages with the numbered buttons.
  6. Type a template name and Save.
  7. Fill values and Render for one page, or use the bulk flow below.

Your work is not lost if you forget to save. Changes are written to the working file about a second after you make them, and opening a different template from the Open list keeps the current layout first (under the name in the Template box, or as "draft"), so you can reopen it from that same list.

Bulk generation from Excel

  1. Click Download XLSX to get a sheet with one column per field, across all pages. A date field becomes three columns (name.day, name.month, name.year); a choice column holds the selected option key. Every column is formatted as text, so values keep their leading zeros.
  2. Fill one row per form.
  3. Pick the file and click Generate from XLSX.
  4. Images land in workspace/output/<template>/, each named by a field whose name contains "serial" if present, otherwise by row number. With a multi page template each row writes its pages in sequence: 0338610.png, 0338610_p2.png, 0338610_p3.png, and so on.

Template format

Templates are JSON: global settings plus a list of pages, each with its own base image and fields. See examples/fields.example.json.

{
  "font": "fonts/YourFont.ttf", "ink": [20,20,20], "default_size": 22,
  "pages": [
    { "name": "page1", "base_image": "bases/front.jpg", "fields": [ ... ] },
    { "name": "page2", "base_image": "bases/back.jpg",  "fields": [ ... ] }
  ]
}

A field looks like:

{
  "name": "full_name",
  "type": "text",
  "box": [x0, y0, x1, y1],
  "value": "",
  "font": "fonts/YourFont.ttf",
  "color": "#112233",
  "quad": [[x,y],[x,y],[x,y],[x,y]]
}

type is one of text, date, choice, digits. font, color and quad are optional; font and color fall back to the global defaults. quad holds the four corners (top left, top right, bottom right, bottom left) that the text is warped into for 3D depth; without it the text is drawn flat in box.

Single page files that use a top level base_image and fields still load: they are read as a one page template.

Project layout

formforge/        the package (app, server, renderer, batch) and web/ UI
scripts/          build_exe.py (package as .exe), make_demo.py (build the gif)
examples/         a sample template
assets/           images used by this readme
workspace/        your data: form images, fonts, templates, output (git ignored)

Build a Windows executable

pip install pyinstaller
python scripts/build_exe.py

This produces dist/FormForge.exe, a single double click file. A workspace folder for your data is created next to the .exe on first run, so keep the .exe in its own folder.

How Arabic rendering works

This build of Pillow has no HarfBuzz, so text is shaped with arabic-reshaper and python-bidi. A font aware fallback swaps any presentation form glyph a font does not include for an equivalent it does, so different fonts render without missing letters.

License

MIT. See LICENSE.

About

Fill scanned paper forms from a template, with bulk generation from an Excel sheet. Arabic and English.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages