Написал маленькое приложение которое генерит пдф со страницы. Сама страница динамическая. Разной высоты.
const express = require('express');
const bodyParser = require('body-parser');
const puppeteer = require('puppeteer');
const app = express();
app.use(bodyParser.json({ limit: '10mb' }));
app.post('/generate', async (req, res) => {
const { html, options } = req.body;
if (!html) {
return res.status(400).send('No HTML provided');
}
try {
const browser = await puppeteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
const page = await browser.newPage();
await page.setViewport({
width: 720,
deviceScaleFactor: 1,
height: 1500 // просто временно!
});
await page.setContent(html, { waitUntil: 'networkidle0' });
const scrollHeight = await page.evaluate(() => {
const main = document.querySelector('main.generator.page');
return main ? main.scrollHeight : document.body.scrollHeight;
});
const pdf = await page.pdf({
width: '720px',
height: `${scrollHeight}px`,
printBackground: true,
...options
});
await browser.close();
res.set({
'Content-Type': 'application/pdf',
'Content-Disposition': 'attachment; filename="file.pdf"',
});
res.send(pdf);
} catch (e) {
console.error('PDF generation error:', e);
res.status(500).send(e.toString());
}
});
const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
console.log(`PDF generator listening on port ${PORT}`);
});
Запустил приложение, но с высотой страницы не понятно. пытаюсь scrollHeight расчитать по контейнеру. То он сохраняет вроде нормально, то белое пустое место снизу оставляет прям в разы больше. Не понимаю с чем это связано.
По ширине все норм, макет фиксированный 720px
обложился логами.
const express = require('express');
const bodyParser = require('body-parser');
const puppeteer = require('puppeteer');
const fs = require('fs');
const path = require('path');
const app = express();
app.use(bodyParser.json({ limit: '10mb' }));
// Функция для записи логов
function logToFile(message) {
const logPath = path.join(__dirname, 'log.txt');
const timestamp = new Date().toISOString();
const logMessage = `[${timestamp}] ${message}\n`;
fs.appendFile(logPath, logMessage, (err) => {
if (err) console.error('Ошибка записи в лог:', err);
});
}
console.log('Доступные методы Page:', Object.keys(require('puppeteer').Page.prototype));
app.post('/generate', async (req, res) => {
const { html, options } = req.body;
if (!html) {
logToFile('Ошибка: Не предоставлен HTML');
return res.status(400).send('No HTML provided');
}
try {
logToFile('Запуск браузера Puppeteer...');
const browser = await puppeteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
const page = await browser.newPage();
await page.setViewport({
width: 720,
deviceScaleFactor: 1,
height: 1 // Минимальная высота
});
logToFile('Установка HTML-контента...');
await page.setContent(html, { waitUntil: 'networkidle0' });
await new Promise(r => setTimeout(r, 500)); // Доп. задержка
logToFile('Вычисление высоты содержимого...');
const scrollHeight = await page.evaluate(() => {
const main = document.querySelector('main.generator.page') || document.body;
return main.scrollHeight;
});
logToFile(`Высота PDF: ${scrollHeight}px`);
const pdf = await page.pdf({
width: '720px',
height: `${scrollHeight + 1}px`, // +1px
printBackground: true,
...options
});
await browser.close();
logToFile('PDF успешно сгенерирован');
res.set({
'Content-Type': 'application/pdf',
'Content-Disposition': 'attachment; filename="file.pdf"',
});
res.send(pdf);
} catch (e) {
logToFile(`Ошибка генерации PDF: ${e.toString()}`);
console.error('PDF generation error:', e);
res.status(500).send(e.toString());
}
});
const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
logToFile(`Сервер запущен на порту ${PORT}`);
console.log(`PDF generator listening on port ${PORT}`);
});
[2025-06-06T17:23:38.131Z] Сервер запущен на порту 3001
[2025-06-06T17:23:43.882Z] Запуск браузера Puppeteer...
[2025-06-06T17:23:47.428Z] Установка HTML-контента...
[2025-06-06T17:23:49.157Z] Вычисление высоты содержимого...
[2025-06-06T17:23:49.163Z] Высота PDF: 2348px
[2025-06-06T17:23:52.763Z] PDF успешно сгенерирован
Всё по высоте бьется.
благодаря этому костылю,
height: `${scrollHeight + 1}px`, // +1px
Оно как то работает, но снизу оставляет полоску. А если убрать то снизу белая простыня, хотя в логах расчитывает высоту по html странице четко. у body, html height:100%; пробовал и auto и т.д.