commit b24ec3678b395d692e876abc10e4c7eea89f509a Author: al3dev Date: Thu Dec 18 00:19:15 2025 +0000 initial commit diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7f9d020 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM node:16-alpine +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +EXPOSE 3000 +CMD ["npm", "start"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..e8e1bfe --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +version: '3.8' + +services: + docxtemplater-service: + build: . + expose: + - "3000" + environment: + - PORT=3000 + networks: + - default + - caddy_default + restart: unless-stopped +networks: + default: {} + caddy_default: + external: true diff --git a/package.json b/package.json new file mode 100644 index 0000000..8029b21 --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "docxtemplater-service", + "version": "1.0.0", + "description": "Service to generate DOCX files using docxtemplater", + "main": "server.js", + "scripts": { + "start": "node server.js" + }, + "dependencies": { + "docxtemplater": "^3.21.0", + "express": "^4.17.1", + "pizzip": "^3.1.1", + "multer": "^1.4.5-lts.1" + } +} diff --git a/server.js b/server.js new file mode 100644 index 0000000..a190a5f --- /dev/null +++ b/server.js @@ -0,0 +1,83 @@ +// server.js +const express = require('express'); +const multer = require('multer'); +const Docxtemplater = require('docxtemplater'); +const PizZip = require('pizzip'); + +const app = express(); + +// Configure multer to accept any field +const upload = multer({ + storage: multer.memoryStorage(), +}).any(); + +app.use(express.json()); + +app.post('/process-template', (req, res) => { + upload(req, res, function(err) { + if (err instanceof multer.MulterError) { + console.error('Multer error:', err); + return res.status(400).json({ error: 'File upload error', details: err.message }); + } else if (err) { + console.error('Unknown error:', err); + return res.status(500).json({ error: 'Unknown error', details: err.message }); + } + + // Log incoming request details + console.log('Files received:', req.files); + console.log('Body received:', req.body); + + try { + // Find the template file from the uploaded files + const templateFile = req.files?.find(file => file.fieldname === 'template'); + const templateData = req.body?.data ? JSON.parse(req.body.data) : null; + console.log(templateData) + if (!templateFile || !templateData) { + return res.status(400).json({ + error: 'Missing required fields', + received: { + templateFile: !!templateFile, + templateData: !!templateData + } + }); + } + + // Get the template file buffer + const content = templateFile.buffer; + + // Create a new PizZip instance with the template content + const zip = new PizZip(content); + + // Create the template processor + const doc = new Docxtemplater(zip, { + paragraphLoop: true, + linebreaks: true, + }); + + // Render the document with the provided data + doc.render(templateData); + + // Generate the document as a buffer + const buffer = doc.getZip().generate({ + type: 'nodebuffer', + compression: 'DEFLATE', + }); + + // Set response headers for file download + res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'); + res.setHeader('Content-Disposition', 'attachment; filename=generated-document.docx'); + + // Send the generated document + res.send(buffer); + + } catch (error) { + console.error('Processing error:', error); + res.status(500).json({ error: 'Processing error', details: error.message }); + } + }); +}); + +const PORT = process.env.PORT || 3000; +app.listen(PORT, () => { + console.log(`Server is running on port ${PORT}`); +}); diff --git a/server.js.bkp b/server.js.bkp new file mode 100644 index 0000000..66560fa --- /dev/null +++ b/server.js.bkp @@ -0,0 +1,44 @@ +const express = require('express'); +const fs = require('fs'); +const path = require('path'); +const Docxtemplater = require('docxtemplater'); +const PizZip = require('pizzip'); + +const app = express(); + +// Enable JSON parsing for incoming requests +app.use(express.json()); +app.use(express.urlencoded({ extended: false })); + +// Endpoint to generate the document +app.post('/generate-doc', (req, res) => { + try { + // Load your DOCX template (ensure the template is in the same directory) + const content = fs.readFileSync(path.resolve(__dirname, 'template.docx'), 'binary'); + const zip = new PizZip(content); + const doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true }); + + // Set your template variables from the request body + doc.setData(req.body); + + // Render the document (this only replaces placeholders, preserving your formatting) + doc.render(); + + // Generate the updated document as a buffer + const buf = doc.getZip().generate({ type: 'nodebuffer' }); + + res.set({ + 'Content-Type': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'Content-Disposition': 'attachment; filename=output.docx' + }); + res.send(buf); + } catch (error) { + console.error('Error during document generation:', error); + res.status(500).send('An error occurred while generating the document.'); + } +}); + +const PORT = process.env.PORT || 3000; +app.listen(PORT, () => { + console.log(`Docxtemplater service listening on port ${PORT}`); +});