Python script for reading a PSD template and applying contents in a spreadsheet to export plenty of images. It's an alternative to Photoshop Image > Variables > Define.
You author PSD layer names and spreadsheet data, then review the images. An agent on your machine handles install and export runs.
📺 Example - Create spreadsheet
create_xlsx.mp4
📺 Example - Manual export
batch_export.mp4
📺 Example - Auto export
auto_export.mp4
This is what you do using Photoshop:
- Edit content in a spreadsheet.
- Save spreadsheet as a CSV file.
- Define variables for layers in Photoshop.
- Import the CSV file.
- Export data sets as files. Unfortunately, you get .psd files.
- Make a automate-batch to save PSD as JPG or PNG.
- Use the automate-batch to get final images.
With this project you edit the spreadsheet (and PSD once), then let the agent run the renderer. No Photoshop Variables / batch dance.
Data lives under demo/ by default, or a custom data directory configured as EPS_DATA_DIR.
- Put PSD templates in
workspace/. - Rename changeable layers/groups with
@Variable_name#Operation_Parameter, e.g.@badge#v,@description#t_p,@bg#i:@marks a changeable layer;Variable_namemust match a spreadsheet column#v— visibility from TRUE/FALSE#t— replace text; modifiers:_c/_ralign,_a[angle]rotate (keep the layer straight in PSD),_pparagraph wrap,_pm/_pbvertical align in paragraph (with_p). Combinations like#t_c_a15,#t_p_pmwork. PSD paragraph-align UI is ignored; names win.#i— fill pixels from an image path in the sheet; scale_cover(default) /_contain; 9-grid align_lt_ct_rt_lm_cm(default)_rm_lb_cb_rb- Do not free-transform (
Cmd/Ctrl+T) changeable text layers—set size via font size only - For rotation, only use
#t_a…in the name; keep the layer horizontal in the PSD
- Have the agent run
xlsx_generatorso column headers appear; edit the first sheet (or drive it with formulas from another sheet). Keep theFile_namecolumn (blank → defaultimage_1, …). - Put fonts under
workspace/assets/fonts/and other assets underworkspace/assets/. Image paths in the sheet are relative toworkspace/(e.g.assets/1_img/image.jpg). - Optional
workspace/fonts.jsonmaps PSD prefix → font filename.
Looks heavy? Doing the same with Photoshop Variables is worse. Once templates exist, daily work is “paste rows → ask the agent to export”.
- Paste or edit rows in the spreadsheet, then ask the agent to export (or to watch the file with the monitor script).
- Clipboard path: copy a table (Excel/web) → ask the agent to run the clipboard importer → pick the target workbook if prompted → images generate.
- Multi-PSD, one sheet: files sharing a prefix before the first
#(e.g.campaign#summer.psd+campaign#winter.psd) sharecampaign.xlsx. Each row yields one image per PSD; filenames include the suffix whenFile_nameis empty. - Transform rules: if
workspace/PREFIX.jsonexists, editPREFIX_raw.csv; rules write the renderable.xlsx. Types:direct,conditional,template,derived,derived_raw. Seetransform_guide.md.
Special thanks to psd-tools for APIs that let Photoshop stay the design tool while Excel/Python own the data.
Created by Victor42 & Agent Vik
Run batch PSD→image export with Python (no Adobe Photoshop app). After install, operate generators/renderers/importers when asked.
- Python 3 + pip
pip install -r requirements.txt- Readable PSD/Excel (or CSV) under the data directory’s
workspace/
- Clone the repo; install
requirements.txt. - Default data root is
demo/. Confirmdemo/workspace/exists. - Optional custom root: copy
.env.example→.env, setEPS_DATA_DIRto an absolute path.
Layout when using a custom data root:
EPS_DATA_DIR/
├── workspace/ # PSD, xlsx/csv, fonts.json, assets/
├── export/
└── log.csv
If EPS_DATA_DIR is set but missing on disk, tools will not fall back to demo/.
Work from the repo root. Data paths come from src/config.py (demo/ or EPS_DATA_DIR).
Entrypoints:
python src/xlsx_generator.py— build/refresh XLSX columns from PSD@Variablelayer namespython src/psd_renderer.py PREFIX FORMAT [OUTPUT_DIR]— batch render;FORMATisjpgorpng; default output isDATA_DIR/export/with a timestamp subfolderpython src/clipboard_importer.py— clipboard table → Excel → renderpython src/file_monitor.py— watch workspace spreadsheets and auto-export on changepython src/transform.py(also auto via renderer) — applyworkspace/PREFIX.jsonrules fromPREFIX_raw.csv
Typical flows:
- Smoke-test:
python src/psd_renderer.py 1 jpg→ checkexport/. - After sheet edits: re-run
psd_renderer.pyfor that prefix. - Clipboard table ready: run
clipboard_importer.pyand follow prompts. - Hands-free watch: start
file_monitor.pyand leave it running. - Stop when the requested export succeeds. Leave PSD layer naming and business spreadsheet content alone unless asked to edit those files.
- Authoring
@variable#opslayer names and spreadsheet rows - Choosing production
EPS_DATA_DIR - Visual QA of exported images
- Do not require Photoshop GUI—this stack is
psd-tools+ Pillow - Do not commit
.envor client data directories - Contracts:
notes.md/transform_guide.md