154 lines
4.4 KiB
TypeScript
154 lines
4.4 KiB
TypeScript
import puppeteer from 'puppeteer';
|
|
import { prisma } from '../prismaClient';
|
|
|
|
export class PdfService {
|
|
private async getConfiguracao() {
|
|
try {
|
|
// Buscar configuração ou usar valores padrão
|
|
const config = await prisma.configuracaoDocumento.findFirst({
|
|
orderBy: { criadoEm: 'desc' },
|
|
select: {
|
|
id: true,
|
|
headerImageUrl: true,
|
|
footerImageUrl: true,
|
|
logoUrl: true,
|
|
timbradoUrl: true,
|
|
timbradoMarginTop: true,
|
|
timbradoMarginBottom: true,
|
|
timbradoMarginLeft: true,
|
|
timbradoMarginRight: true,
|
|
criadoEm: true
|
|
}
|
|
});
|
|
|
|
console.log('Configuração encontrada:', config); // Debug
|
|
|
|
// Retornar configuração padrão se não existir
|
|
return {
|
|
cabecalhoHtml: config?.cabecalhoHtml || `
|
|
<div style="text-align: center; padding: 20px;">
|
|
<h2 style="margin:0;font-size:14pt">{{escritorio.nome}}</h2>
|
|
</div>
|
|
`,
|
|
rodapeHtml: config?.rodapeHtml || `
|
|
<div style="text-align: center; font-size: 10pt;">
|
|
{{escritorio.endereco}}<br>
|
|
Tel: {{escritorio.telefone}} | Email: {{escritorio.email}}
|
|
</div>
|
|
`,
|
|
logoUrl: config?.logoUrl || '',
|
|
timbradoUrl: config?.timbradoUrl || '',
|
|
timbradoMarginTop: config?.timbradoMarginTop || 100,
|
|
timbradoMarginBottom: config?.timbradoMarginBottom || 50,
|
|
timbradoMarginLeft: config?.timbradoMarginLeft || 50,
|
|
timbradoMarginRight: config?.timbradoMarginRight || 50
|
|
};
|
|
} catch (error) {
|
|
console.error('Erro ao buscar configuração:', error);
|
|
throw new Error('Falha ao buscar configuração');
|
|
}
|
|
}
|
|
|
|
private gerarHTML(content: string, config: any) {
|
|
const timbradoUrl = config.timbradoUrl
|
|
? `${process.env.BACKEND_URL || 'http://localhost:5000'}${config.timbradoUrl}`
|
|
: '';
|
|
|
|
console.log('Gerando PDF com timbrado:', timbradoUrl);
|
|
|
|
return `
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<link href="https://fonts.googleapis.com/css2?family=Fira+Sans:wght@400;500;600&display=swap" rel="stylesheet">
|
|
<style>
|
|
@page {
|
|
margin: 0;
|
|
size: A4;
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
padding: 0;
|
|
font-family: 'Fira Sans', Arial, sans-serif;
|
|
font-size: 11pt;
|
|
line-height: 1.5;
|
|
position: relative;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.page {
|
|
position: relative;
|
|
width: 21cm;
|
|
min-height: 29.7cm;
|
|
padding: ${config.timbradoMarginTop || 100}px ${config.timbradoMarginRight || 50}px ${config.timbradoMarginBottom || 50}px ${config.timbradoMarginLeft || 50}px;
|
|
background: ${timbradoUrl ? `url('${timbradoUrl}')` : 'none'};
|
|
background-size: cover;
|
|
background-position: center;
|
|
background-repeat: no-repeat;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.content {
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="page">
|
|
<div class="content">
|
|
${content}
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
`;
|
|
}
|
|
|
|
async gerarPDF(conteudo: string, escritorio: any) {
|
|
try {
|
|
const config = await prisma.configuracaoDocumento.findFirst({
|
|
orderBy: { criadoEm: 'desc' }
|
|
});
|
|
|
|
console.log('Configuração do PDF:', config);
|
|
|
|
const html = this.gerarHTML(conteudo, config);
|
|
|
|
const browser = await puppeteer.launch({
|
|
headless: 'new',
|
|
args: ['--no-sandbox']
|
|
});
|
|
|
|
const page = await browser.newPage();
|
|
|
|
await page.setViewport({
|
|
width: 794, // A4 width in pixels (72 dpi)
|
|
height: 1123,
|
|
deviceScaleFactor: 2
|
|
});
|
|
|
|
await page.setContent(html, {
|
|
waitUntil: ['networkidle0', 'load'],
|
|
timeout: 30000
|
|
});
|
|
|
|
const pdfBuffer = await page.pdf({
|
|
format: 'A4',
|
|
printBackground: true,
|
|
margin: { top: '0', right: '0', bottom: '0', left: '0' },
|
|
preferCSSPageSize: true
|
|
});
|
|
|
|
await browser.close();
|
|
return Buffer.from(pdfBuffer);
|
|
|
|
} catch (error) {
|
|
console.error('Erro ao gerar PDF:', error);
|
|
throw new Error('Falha ao gerar PDF');
|
|
}
|
|
}
|
|
}
|