Colas Mérand
23/08/2025
Next.js
Vercel
5 minutes
Conversion DOCX vers PDF en environnement serverless : Solutions pour Next.js sur Vercel
La génération et la conversion de documents sont des fonctionnalités essentielles pour de nombreuses applications web modernes. Que ce soit pour créer des factures, des rapports ou des contrats, la possibilité de produire des documents professionnels en différents formats est souvent un besoin critique pour les entreprises. Dans cet article, nous allons explorer les défis et solutions pour convertir des fichiers DOCX en PDF dans un environnement serverless, spécifiquement pour les applications Next.js hébergées sur Vercel.
Le défi de la conversion DOCX vers PDF en serverless
Les applications hébergées sur des plateformes serverless comme Vercel présentent des contraintes spécifiques qui compliquent la conversion de documents. Contrairement aux serveurs traditionnels, vous ne pouvez pas simplement installer LibreOffice ou d'autres outils lourds qui sont couramment utilisés pour ces tâches.
Les principales difficultés incluent :
- Limitations de taille : Les fonctions serverless ont des limites strictes en termes de taille de bundle
- Absence d'accès au système de fichiers persistant
- Temps d'exécution limité (généralement 10-60 secondes maximum)
- Contraintes de mémoire
- Impossibilité d'installer des dépendances système
Ces contraintes nécessitent des approches spécifiques pour obtenir des résultats professionnels.
Solutions efficaces pour la conversion DOCX vers PDF sur Vercel
Après avoir travaillé sur plusieurs projets nécessitant ce type de fonctionnalité, notamment pour des plateformes comme Easop (gestion de stock options) et Astory (location d'œuvres d'art), nous avons identifié plusieurs approches viables :
1. Puppeteer-core avec Chrome serverless
Cette approche consiste à utiliser Puppeteer, un outil d'automatisation de navigateur, couplé à une version allégée de Chrome optimisée pour les environnements serverless.
// Exemple simplifié d'implémentation avec Puppeteer
import chromium from '@sparticuz/chromium';
import puppeteer from 'puppeteer-core';
import { readFile } from 'fs/promises';
import mammoth from 'mammoth';
export default async function handler(req, res) {
try {
const docxBuffer = req.body.docxFile;
// Convertir DOCX en HTML avec mammoth
const { value: html } = await mammoth.convertToHtml({ buffer: docxBuffer });
// Initialiser le navigateur
const browser = await puppeteer.launch({
args: chromium.args,
executablePath: await chromium.executablePath(),
headless: true,
});
const page = await browser.newPage();
await page.setContent(html, { waitUntil: 'networkidle0' });
// Générer le PDF
const pdfBuffer = await page.pdf({
format: 'A4',
printBackground: true,
margin: { top: '1cm', right: '1cm', bottom: '1cm', left: '1cm' }
});
await browser.close();
// Renvoyer le PDF
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename=document.pdf');
res.send(pdfBuffer);
} catch (error) {
res.status(500).json({ error: error.message });
}
}
Cette solution fonctionne bien pour des documents de complexité moyenne et offre un bon contrôle sur le rendu final.
2. Utilisation de services API tiers
Une autre approche consiste à utiliser des API spécialisées dans la conversion de documents :
// Exemple avec un service API tiers
export default async function handler(req, res) {
try {
const docxBuffer = req.body.docxFile;
const response = await fetch('https://api.conversion-service.com/convert', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.API_KEY}`,
'Content-Type': 'application/octet-stream'
},
body: docxBuffer
});
if (!response.ok) {
throw new Error('Conversion failed');
}
const pdfBuffer = await response.arrayBuffer();
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename=document.pdf');
res.send(Buffer.from(pdfBuffer));
} catch (error) {
res.status(500).json({ error: error.message });
}
}
Cette solution est souvent la plus fiable pour les documents complexes, mais elle introduit une dépendance externe et peut engendrer des coûts supplémentaires.
3. Approche hybride avec docx-to-pdf
Pour les cas où la mise en page n'est pas extrêmement complexe, une approche hybride utilisant des bibliothèques comme docx-to-pdf
peut être efficace :
import { convert } from 'docx-pdf';
import { writeFile, readFile } from 'fs/promises';
import { v4 as uuidv4 } from 'uuid';
import os from 'os';
import path from 'path';
export default async function handler(req, res) {
try {
const docxBuffer = req.body.docxFile;
// Créer des fichiers temporaires
const tempDir = os.tmpdir();
const docxPath = path.join(tempDir, `${uuidv4()}.docx`);
const pdfPath = path.join(tempDir, `${uuidv4()}.pdf`);
await writeFile(docxPath, docxBuffer);
// Convertir DOCX en PDF
await convert(docxPath, pdfPath);
// Lire le PDF généré
const pdfBuffer = await readFile(pdfPath);
// Nettoyer les fichiers temporaires
await Promise.all([
unlink(docxPath).catch(() => {}),
unlink(pdfPath).catch(() => {})
]);
// Renvoyer le PDF
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename=document.pdf');
res.send(pdfBuffer);
} catch (error) {
res.status(500).json({ error: error.message });
}
}
Optimisations et bonnes pratiques
Lors de l'implémentation d'une solution de conversion DOCX vers PDF sur Vercel, nous recommandons les pratiques suivantes :
Mise en cache des résultats
Pour éviter de reconvertir les mêmes documents, implémentez un système de mise en cache :
import { Redis } from '@upstash/redis';
const redis = new Redis({
url: process.env.REDIS_URL,
token: process.env.REDIS_TOKEN,
});
// Dans votre handler
const cacheKey = `pdf:${createHash('md5').update(docxBuffer).digest('hex')}`;
const cachedPdf = await redis.get(cacheKey);
if (cachedPdf) {
// Retourner le PDF depuis le cache
return res.send(Buffer.from(cachedPdf, 'base64'));
}
// Sinon, procéder à la conversion et mettre en cache
// ...
await redis.set(cacheKey, pdfBuffer.toString('base64'), { ex: 86400 }); // Expire après 24h
Gestion des timeouts
Les conversions de documents volumineux peuvent prendre du temps. Utilisez des stratégies pour gérer les timeouts :
export const config = {
api: {
bodyParser: {
sizeLimit: '10mb',
},
responseLimit: '10mb',
},
};
// Utiliser une fonction d'aide pour surveiller le temps d'exécution
const withTimeout = (promise, timeoutMs) => {
let timeoutHandle;
const timeoutPromise = new Promise((_, reject) => {
timeoutHandle = setTimeout(() => {
reject(new Error('Operation timed out'));
}, timeoutMs);
});
return Promise.race([
promise,
timeoutPromise,
]).finally(() => {
clearTimeout(timeoutHandle);
});
};
// Dans votre handler
try {
const result = await withTimeout(convertDocument(docxBuffer), 25000); // 25 secondes
// ...
} catch (error) {
if (error.message === 'Operation timed out') {
// Rediriger vers un processus asynchrone ou informer l'utilisateur
}
// ...
}
Cas d'utilisation concrets
Chez Platane, nous avons implémenté ces solutions pour plusieurs clients avec des besoins variés :
Pour Easop, nous avons développé un système de génération de contrats de stock-options qui nécessitait une conversion précise des documents juridiques du format DOCX vers PDF, tout en préservant la mise en page complexe incluant des tableaux et des signatures.
Pour Astory, nous avons créé un système de génération de certificats d'authenticité pour les œuvres d'art, où la qualité visuelle du document final était primordiale.
Dans ces deux cas, l'approche Puppeteer avec Chrome serverless s'est révélée être la solution la plus adaptée, offrant un bon équilibre entre fidélité de rendu et compatibilité avec l'environnement serverless de Vercel.
Conclusion
La conversion de documents DOCX vers PDF dans un environnement serverless comme Vercel présente des défis techniques spécifiques, mais plusieurs solutions viables existent. Le choix de l'approche dépendra de la complexité de vos documents, de vos contraintes budgétaires et de vos exigences en termes de fidélité de rendu.
Chez Platane, nous privilégions des solutions robustes qui allient performance et qualité, tout en respectant les contraintes techniques des environnements modernes comme Vercel. Notre expérience avec des projets comme Easop et Astory nous a permis de développer une expertise pointue dans ce domaine.
Vous avez un projet nécessitant une conversion de documents ou d'autres fonctionnalités techniques avancées pour votre application Next.js ? N'hésitez pas à prendre rendez-vous via notre formulaire de contact. Notre équipe d'experts se fera un plaisir d'échanger avec vous sur vos besoins spécifiques et de vous proposer des solutions sur mesure qui répondent parfaitement à vos objectifs. Collaborer avec Platane, c'est s'assurer d'une expertise technique de pointe au service de votre vision.
Automatisation des bornes de recharge électrique : l'avenir de la mobilité intelligente
WordPress Gutenberg pour les associations : créer un site performant avec système de réservation
Conversion DOCX vers PDF en environnement serverless : Solutions pour Next.js sur Vercel
N'hésitez pas à nous contacter.
Nous aussi et c'est évidemment sans engagement !