salesforce_node_pdf_api/improved-pdf-generation.js
2025-09-03 23:52:13 +05:30

145 lines
4.6 KiB
JavaScript

async function generateA4PDF(htmlContent, outputPDF) {
let browser = null;
try {
console.log("🚀 Starting PDF generation...");
// Launch browser
browser = await puppeteer.launch({
headless: true,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-accelerated-2d-canvas',
'--no-first-run',
'--no-zygote',
'--disable-gpu'
]
});
const page = await browser.newPage();
// Set viewport to A4 dimensions (210mm x 297mm = 794px x 1123px at 96 DPI)
await page.setViewport({ width: 794, height: 1123 });
page.setDefaultTimeout(0); // Infinite timeout
// Inject CSS to fix white spaces and page breaks
const improvedHTML = `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: Arial, sans-serif;
line-height: 1.4;
color: #333;
background: white;
margin: 0;
padding: 0;
}
@page {
size: A4;
margin: 0.25in;
}
.page-break {
page-break-before: always;
}
.no-break {
page-break-inside: avoid;
}
img {
max-width: 100%;
height: auto;
display: block;
}
table {
page-break-inside: avoid;
width: 100%;
}
h1, h2, h3, h4, h5, h6 {
page-break-after: avoid;
margin-top: 0.5em;
margin-bottom: 0.3em;
}
p {
margin-bottom: 0.5em;
orphans: 2;
widows: 2;
}
</style>
</head>
<body>
${htmlContent.replace(/<body[^>]*>|<\/body>/gi, '')}
</body>
</html>
`;
// Set content with improved HTML
await page.setContent(improvedHTML, {
waitUntil: 'networkidle0',
timeout: 0 // Infinite timeout
});
// Wait for content to load completely
await page.waitForTimeout(2000); // Wait 2 seconds for content to settle
// Wait for all resources to load
try {
await page.waitForNetworkIdle({ timeout: 0 });
} catch (error) {
// Ignore timeout errors for networkidle
}
console.log("📄 Generating A4 PDF...");
const pdfOptions = {
path: outputPDF,
printBackground: true,
margin: {
top: '0.25in',
right: '0.25in',
bottom: '0.25in',
left: '0.25in'
},
scale: 1.0,
format: 'A4',
preferCSSPageSize: false,
displayHeaderFooter: false,
omitBackground: false
};
// Generate PDF
await page.pdf(pdfOptions);
await browser.close();
// Get PDF file size for logging (no size restriction for download links)
const pdfStats = fs.statSync(outputPDF);
const pdfSizeMB = pdfStats.size / (1024 * 1024);
console.log(`✅ A4 PDF generated: ${outputPDF}`);
console.log(`📐 Format: A4 (210mm x 297mm)`);
console.log(`📏 Margins: 0.25in all sides`);
console.log(`🔍 Scale: 1.0`);
console.log(`📊 File size: ${pdfSizeMB.toFixed(2)} MB`);
} catch (error) {
if (error.name === 'TimeoutError') {
throw new Error("Timeout: Page took too long to load.");
}
console.error(`❌ PDF generation error: ${error.message}`);
throw error;
} finally {
// Cleanup
if (browser) {
try {
await browser.close();
} catch (error) {
console.error('Error closing browser:', error);
}
}
}
}