Bulk document generation with LibreOffice and ODT templates
Producing one separate document for every row in a spreadsheet is a standard administrative task. LibreOffice Writer includes a mail merge feature designed for this, but its workflow is heavily optimized for printing or emailing. When you need a clean batch of individual files—like fifty separate client letters or vendor contracts—the built-in wizard quickly becomes cumbersome.
You can generate separate files entirely in your browser using your existing ODT templates and ODS spreadsheets. This approach skips the database registration steps and returns a ZIP file containing one finished document per row.
This guide covers how LibreOffice handles bulk generation natively, where the process creates friction, and how to bypass it for a faster daily workflow using a browser-based generator.
How LibreOffice Writer handles mail merge
LibreOffice Writer generates bulk documents using the Mail Merge Wizard or the Print dialog. When you choose to save the output rather than print it, Writer gives you the option to save as a single large document or as individual files.
If you choose individual documents, Writer generates a separate ODT file for every row in your data source. You can define the file names using a specific column from your spreadsheet, such as a client name or an invoice number.
The output itself is solid. LibreOffice accurately maps the fields, preserves your document formatting, and handles pagination well. The friction lies entirely in the setup process required before you can click generate.
Why the built-in process gets awkward
To use a spreadsheet in LibreOffice Writer, you cannot simply open the file and read it. You must register the spreadsheet as a LibreOffice Base database source.
This requires navigating through the Data Sources panel or the Exchange Database dialog to link your .ods or .xlsx file. Writer then creates a separate .odb connection file behind the scenes. If you rename your spreadsheet or move it to a different folder, this connection breaks, and your mail merge fields stop working until you manually re-register the new file path.
This architecture is incredibly powerful if you are connecting Writer to a persistent SQL database on a corporate server. However, it is heavy and frustrating if you are just trying to process a temporary spreadsheet of thirty names that someone emailed you this morning. Running the Mail Merge Wizard step-by-step is also slow for a task you might need to repeat every week.
The browser route for ODT and ODS files
You can bypass the database registration entirely by using ManyDocs, a free browser-based generator. It takes your template and your spreadsheet, combines them locally on your device, and gives you a ZIP file of individual documents.
Everything happens inside your browser using JavaScript. Your files are never uploaded to a server, which keeps sensitive data like addresses or financial figures strictly on your machine.
To use it, you drag and drop your ODT template into the page, followed by your spreadsheet. You choose which spreadsheet column should be used to name the output files. You click generate, and a ZIP file downloads immediately. There is no software to install, no account to create, and no database connections to manage.
Typing placeholders in LibreOffice
Because LibreOffice is not connected directly to your spreadsheet during the drafting phase, you mark where the data should go by typing placeholders directly into your document text.
ManyDocs recognizes three styles of placeholders: ((field)), {{field}}, or [[field]]. Pick one style and use it consistently. The text inside the brackets must exactly match the column header in your spreadsheet, including capitalization.
If your spreadsheet has a column named "ClientName", you type {{ClientName}} in your ODT file wherever that name should appear. Placeholders work anywhere in the document, including inside tables, headers, footers, and section headings.
Note that the built-in visual editor on the ManyDocs website is available for DOCX templates only. For ODT templates, you must type the placeholders manually in LibreOffice Writer.
A worked example: Client renewal notices
Here is how a simple data set maps to an ODT template to produce three separate files.
The spreadsheet (renewal-data.ods)
| ClientName | ContractDate | Fee |
|---|---|---|
| Acme Corp | 14 March 2026 | 4,500 |
| Globex | 22 April 2026 | 3,200 |
| Initech | 05 May 2026 | 5,100 |
The template text (notice-template.odt)
Dear {{ClientName}},
This is a reminder that your service contract, originally signed on {{ContractDate}}, is due for renewal. The renewal fee for the upcoming year is €{{Fee}}.
Please contact us to confirm your continuation of service.
The output
If you select the "ClientName" column for your file names, the generator produces a ZIP containing three files: Acme Corp.odt, Globex.odt, and Initech.odt. Each file contains the specific text for that client.
Preparing your .ods spreadsheet
ManyDocs reads .ods files directly, alongside .xlsx and .xls formats. You do not need to export your LibreOffice Calc spreadsheets to CSV before using them.
The generator reads the spreadsheet exactly as it is structured:
- The first row must contain your column headers. Do not put a main title in row 1 and push the headers to row 2.
- One row equals one generated document.
- Formatting applied in Calc is ignored. If you format a cell as currency or color it red, that formatting does not transfer.
- Formulas are not recalculated. The generator reads the value currently stored in the cell. If your invoice total is a formula, ensure it is calculating correctly before you drop the file into the generator.
If you need a date or a number to appear in a very specific format (like "14 March 2026"), the safest approach is to store that exact text string in your spreadsheet column, rather than relying on Calc's display formatting.
Choosing between ODT and DOCX templates
Since ManyDocs supports both formats, you can choose the one that best fits your workflow.
Stick to ODT if you operate entirely in a Linux environment, if your organization strictly uses open-source software, or if the people receiving the editable files also use LibreOffice. Working natively in ODT avoids any minor layout shifts that can occasionally happen when translating complex documents between Writer and Word formats.
Consider saving your template as a DOCX file if you want to use the ManyDocs visual editor, which allows you to open a finished document in the browser and convert detected values back into placeholders with a click. DOCX is also the safer choice if you need to email the generated, editable files to external clients who use Microsoft Word.
Converting the generated batch to PDF
ManyDocs outputs DOCX or ODT files. It does not export to PDF. If you are generating invoices or certificates, you likely need PDF files to prevent unauthorized editing.
You can convert your batch of generated ODT files to PDF quickly using LibreOffice's built-in command line interface. You do not need to open the files one by one.
Open your terminal or command prompt, navigate to the unzipped folder containing your generated documents, and run the headless conversion command.
On Linux:
libreoffice --headless --convert-to pdf *.odt
On macOS:
/Applications/LibreOffice.app/Contents/MacOS/soffice --headless --convert-to pdf *.odt
On Windows (adjusting the path if necessary):
"C:\Program Files\LibreOffice\program\soffice.exe" --headless --convert-to pdf *.odt
This command launches LibreOffice in the background without the graphical interface, processes every .odt file in the folder, and saves a matching .pdf file alongside it. A batch of one hundred files takes a few seconds to process.
Frequently asked questions
Does the generator alter my original LibreOffice template?
No. The generator reads your ODT template to create the new documents, but it never modifies or overwrites your original file. The template remains exactly as you uploaded it, ready for the next batch.
Why did my placeholders not fill in?
The most common cause is a mismatch between the placeholder text and the spreadsheet header. "Client Name" and "ClientName" are different. Check for trailing spaces in your spreadsheet headers, and ensure you are using the exact same capitalization.
Can I include images that change per document?
No. The placeholder system is designed for text and numbers. You cannot use placeholders to swap out images, logos, or signatures dynamically based on the spreadsheet data.
Will my LibreOffice fonts and styling be preserved?
Yes. The generator replaces the text node itself without touching the surrounding XML styling. If you make your placeholder bold and red in your ODT template, the final inserted text will be bold and red in the output file.
Is there a limit to how many files I can generate?
There is no hard limit on rows, but because the processing happens locally, the speed depends entirely on your computer's memory and processor. A spreadsheet with several hundred rows will generate in a few moments on a modern device.