DocPerRow does it client-side: you write {Column name} placeholders in a .docx, drop in an xlsx/xls/ods/csv, pick a file-name pattern like {LastName} {InvoiceNo}, and get a ZIP with one .docx per row. It's a static site using docxtemplater, PizZip and SheetJS. Your files never leave the browser. The only outgoing requests are cookie-less GoatCounter analytics (page views and event names such as "run") and a same-origin counter that stores the event name and UI language; no file contents or names are sent.
docxtemplater already copes with Word splitting a placeholder like {Name} across several XML runs, which is what I feared most. The work went elsewhere:
- Excel date cells: the "locale default" date format is stored as m/d/yy, so dates have to be re-rendered in the user's locale or a Polish user gets 10/20/26.
- CSVs saved by Ukrainian/Polish Excel are often CP1251/CP1250, not UTF-8.
Free up to 20 documents per run, no sign-up. It outputs .docx only (no PDF yet). I'd like to hear what's missing for your use case, and whether the 20-document limit or the template syntax gets in the way.