Migrating from docxtemplater and DOCX conversion / A report designer or markup toolchain
Migrating off DOCX templating, and keeping the Word deliverable
A pipeline that fills placeholders in a Word template and converts the result to PDF, where the conversion step is what you are replacing and the Word file may still be a deliverable.
What ports and what does not
The data. The template does not, and the first question is whether it can be retired at all, because these pipelines frequently produce a Word document as an output in its own right rather than only as an intermediate. If somebody downstream edits the DOCX, the template stays and only the conversion changes, which is a much smaller migration and a different one. If the PDF is the only output, the Word template is replaced by markup and the whole pipeline collapses to one call.
What the call becomes
The template fill followed by a conversion, usually headless LibreOffice or a conversion service, becomes a POST to /v1/pdf with html. If the DOCX is still a deliverable, keep the fill step, keep producing the DOCX, and replace only the conversion, which means running two templates and accepting that they will drift.
Side by side
The old shape and the new one, with the parts that have no counterpart called out in comments rather than quietly omitted.
// Before
const zip = new PizZip(fs.readFileSync("invoice.docx"));
const doc = new Docxtemplater(zip);
doc.setData({ customer, rows, total });
doc.render();
fs.writeFileSync("/tmp/out.docx", doc.getZip().generate({ type: "nodebuffer" }));
execSync("soffice --headless --convert-to pdf --outdir /tmp /tmp/out.docx");
// After, if the PDF is the only output: one call, one template.
const r = await fetch("https://api.pdfpipe.xyz/v1/pdf", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.PDFPIPE_KEY}`,
"Content-Type": "application/json" },
body: JSON.stringify({
html: renderInvoice({ customer, rows, total }),
options: { format: "A4" },
}),
});
/* Decide this first, because it changes the size of the project:
the DOCX is an intermediate only -> delete the Word template, one
template, one call
the DOCX is also a deliverable -> keep both. You now maintain
two templates for one document
and they will drift. Budget
for keeping them in step, or
decide the PDF is generated
from the DOCX and leave the
pipeline alone. */The CSS delta, in both directions
What the old engine accepted that a current one does not, and what it refused that a current one wants. The second direction is the one people forget, and it is where the value of the migration is.
- Nothing to migrate. The Word template's styles are the specification.
- Word's own constructs, content controls, fields, section breaks, have CSS counterparts that are usually simpler: a section break becomes break-before, and a field becomes interpolated text.
- Repeating regions in the template, which docxtemplater drove with its own loop syntax, become ordinary template loops producing rows.
- Headers and footers move from the Word document's own to the header and footer options.
What changes without anything erroring
The dangerous list. Each of these produces a different document and no diagnostic, so none of them are caught by a test that only checks the render succeeded.
- Everything visual, if the template is being replaced.
- Nothing at all, if you keep the DOCX and change only the conversion, which is why that variant is worth identifying early.
- Divergence between the two templates over time, if you keep both. That is a slow failure rather than an immediate one and it is the real cost of the hybrid.
What to diff before cutting over
Establish which variant you are in before anything else. Ask who consumes the DOCX. If the answer is nobody, the migration is small and clean. If the answer is a person who edits it, the migration is about the conversion step only and the template stays.
The one thing that always breaks
The assumption that the Word file was an intermediate. It usually is not: somebody downstream opens it, edits it or archives it, and that use is invisible from the code. Replacing the template with markup removes an output that another team depended on, and the first sign is a request for the Word version.
Frequently asked
Do I have to rewrite my templates to leave docxtemplater and DOCX conversion?
Effectively yes, and it is better to plan for that than to discover it. The old tool did not have HTML templates to port, so the document has to be expressed as markup for the first time. The value in the old code is the data layer underneath the drawing, and that part survives untouched.
Can I run both for a while?
Yes, and it is the safest way to do it. Put both behind one internal function that takes your data and returns bytes, switch on an environment variable, and run the new path on real traffic while the old one still serves. You get a diff on real documents rather than on fixtures, and you keep a way back that does not involve a deploy.
What about the documents already generated?
Nothing here changes them. They are files that already exist. What is worth deciding before the cutover is whether a regenerated document has to match the original byte for byte or merely say the same thing, because for anything with a legal or audit character the answer is usually to keep the original file rather than to be able to reproduce it.
Other migrations
The nearest neighbours first, then others that started from the same kind of tool, because the model matters more than the language.
Migrating off headless LibreOffice conversion, and its templates
An office suite run headless to convert documents to PDF, where the template is a word processor file and the conversion is a whole application invoked per document.
Migrating off Crystal Reports, and rebuilding the formula fields
A reporting product whose layouts live in binary report files edited in a designer, with sections, formula fields and its own formula language, none of which are portable.
Migrating off LaTeX, and what you give up in typesetting
A typesetting system with its own language and a compilation step, where the migration is honest about losing typographic quality in exchange for everything else.
Migrating off JasperReports, and what happens to the bands
A reporting engine whose layouts are XML files built in a visual designer, organised into bands that repeat by rule, where nothing about the layout is portable and the band model has no equivalent.
Migrating off SSRS, from RDL and tablix to markup
A reporting service whose layouts are RDL files built around a tablix, with the report server providing scheduling, subscriptions and delivery alongside the rendering.
Every migration, grouped by what you are coming from
The full list, sorted by the model the old tool used rather than by its name.
What this API actually does
One page per option and endpoint that exists, which is what the mappings above point at.
Render one of your existing documents through the playground before changing any code. That comparison is the whole of the risk assessment for this migration.