From 4708b9ec82f41a718e3428b50bf908e6b13308d4 Mon Sep 17 00:00:00 2001 From: Rodrigo Martins Date: Tue, 22 Apr 2025 11:05:46 -0300 Subject: [PATCH] tenta fix pdfservice.js --- src/server/services/PdfService.ts | 193 ++++++++++++++---------------- 1 file changed, 88 insertions(+), 105 deletions(-) diff --git a/src/server/services/PdfService.ts b/src/server/services/PdfService.ts index 8b083ce..468d0ff 100644 --- a/src/server/services/PdfService.ts +++ b/src/server/services/PdfService.ts @@ -641,168 +641,151 @@ export class PdfService { // Usar apenas a primeira página do timbrado para todas as páginas do documento if (timbradoPageCount > 0) { - // Corrigido: pdfDoc.embedPdfPage retorna uma promessa de um objeto e não um arrayo e não um array + // Corrigido: pdfDoc.embedPdfPage retorna uma promessa de um objeto e não um array const embedded = await pdfDoc.embedPdfPage(timbradoPdf.getPage(0)); timbradoPages = [embedded]; - console.log('Timbrado incorporado com sucesso'); timbradoPages = [embedded]; - }('Timbrado incorporado com sucesso'); + console.log('Timbrado incorporado com sucesso'); + } } catch (error) { - console.error('Erro ao carregar timbrado:', error); ao incorporar página do timbrado:', embedError); - timbradoExists = false; timbradoExists = false; - } } - } } + console.error('Erro ao carregar timbrado:', error); + timbradoExists = false; + } + } - let currentPar = 0;'Erro ao carregar timbrado:', error); + let currentPar = 0; let pageIndex = 0; - console.log(`Gerando PDF com ${paragrafos.length} parágrafos`); } + console.log(`Gerando PDF com ${paragrafos.length} parágrafos`); // Define um contador máximo para evitar loops infinitos const MAX_PAGES = 100; - t pageIndex = 0; - while (currentPar < paragrafos.length && pageIndex < MAX_PAGES) {ragrafos.length} parágrafos`); + while (currentPar < paragrafos.length && pageIndex < MAX_PAGES) { console.log(`Criando página ${pageIndex + 1}, processando parágrafo ${currentPar + 1} de ${paragrafos.length}`); let page = pdfDoc.addPage([PAGE_WIDTH, PAGE_HEIGHT]); - ${pageIndex + 1}, processando parágrafo ${currentPar + 1} de ${paragrafos.length}`); - // Adicionar timbrado à página= pdfDoc.addPage([PAGE_WIDTH, PAGE_HEIGHT]); + + // Adicionar timbrado à página if (timbradoPages.length > 0) { - console.log(`Adicionando timbrado na página ${pageIndex + 1}`);th > 0) { - // Usando o timbrado incorporadoradoPages[pageIndex % timbradoPages.length]; - page.drawPage(timbradoPages[0], {sole.log(`Adicionando timbrado na página ${pageIndex + 1}`); - x: 0, page.drawPage(embedded, { - y: 0, x: 0, + console.log(`Adicionando timbrado na página ${pageIndex + 1}`); + page.drawPage(timbradoPages[0], { + x: 0, + y: 0, width: PAGE_WIDTH, height: PAGE_HEIGHT }); - }}); + } let y = PAGE_HEIGHT - margens.top; let processedAnyParagraph = false; // Flag para verificar se processamos algum parágrafo - paragrafos.length) { + // Tenta processar parágrafos na página atual while (currentPar < paragrafos.length) { - const paraText = paragrafos[currentPar]; // Extract alignment - enter' | 'justify' = 'left'; - // Extract alignmenth = paraText.match(/^§§ALIGN=(center|justify|right)§§/); + const paraText = paragrafos[currentPar]; + + // Extract alignment let align: 'left' | 'center' | 'justify' = 'left'; - const alignMatch = paraText.match(/^§§ALIGN=(center|justify|right)§§/);ch[1] as 'center' | 'justify' | 'left'; + const alignMatch = paraText.match(/^§§ALIGN=(center|justify|right)§§/); if (alignMatch) { align = alignMatch[1] as 'center' | 'justify' | 'left'; - }// Extract indentation -0; - // Extract indentation paraText.match(/§§INDENT=([0-9.]+)§§/); + } + + // Extract indentation let indent = 0; - const indentMatch = paraText.match(/§§INDENT=([0-9.]+)§§/);); + const indentMatch = paraText.match(/§§INDENT=([0-9.]+)§§/); if (indentMatch) { indent = parseFloat(indentMatch[1]); } - // Clean text .replace(/^§§ALIGN=(center|justify|right)§§/, '') + // Clean text let text = paraText - .replace(/^§§ALIGN=(center|justify|right)§§/, '')(); + .replace(/^§§ALIGN=(center|justify|right)§§/, '') .replace(/§§INDENT=[0-9.]+§§/, '') - .trim();x = margens.left + indent; - parWidth = MAX_WIDTH - indent; + .trim(); + + let x = margens.left + indent; + let parWidth = MAX_WIDTH - indent; + // Se o texto for muito curto, avance para o próximo parágrafo - if (text.length < 2) {= renderInlineFormattedParagraph( + if (text.length < 2) { currentPar++; processedAnyParagraph = true; continue; } - let x = margens.left + indent; - let parWidth = MAX_WIDTH - indent;alic, - ic, console.log(`Tentando renderizar parágrafo ${currentPar + 1} em y=${y}`); - ), - let yAfter = renderInlineFormattedParagraph(align, - page, parWidth, + let yAfter = renderInlineFormattedParagraph( + page, text, x, - y,om, - font,EIGHT - fontBold,; + y, + font, + fontBold, fontItalic, - fontBoldItalic,= null) { - FONT_SIZE,a, criando nova página`); - rgb(0, 0, 0), pageIndex++; + fontBoldItalic, + FONT_SIZE, + rgb(0, 0, 0), align, - parWidth, } - false, y = yAfter - FONT_SIZE * 0.5; + parWidth, + false, margens.top, - margens.bottom,E * 1.5) break; + margens.bottom, PAGE_HEIGHT ); if (yAfter === null) { - // Se não conseguimos renderizar este parágrafo, vamos para a próxima página console.log(`PDF gerado com ${pageIndex} páginas`); - // Mas só se já tivermos processado algum parágrafo nesta página const pdfBytes = await pdfDoc.save(); - if (processedAnyParagraph) { return Buffer.from(pdfBytes); + // Se não conseguimos renderizar este parágrafo, vamos para a próxima página + // Mas só se já tivermos processado algum parágrafo nesta página + if (processedAnyParagraph) { console.log(`Página ${pageIndex + 1} está cheia, criando nova página`); break; } else { // Se não conseguimos nem processar um parágrafo, algo está errado // Vamos avançar para o próximo parágrafo para evitar um loop infinito console.log(`Não foi possível processar o parágrafo ${currentPar + 1}, avançando`); - currentPar++;{ - processedAnyParagraph = true;{\{([^}]+)\}\}/g, (match, key) => { - }arts = key.trim().split('.'); + currentPar++; + processedAnyParagraph = true; + } } else { // Parágrafo foi renderizado com sucesso - y = yAfter - FONT_SIZE * 0.5; (const part of keyParts) { - currentPar++; if (value && typeof value === 'object' && part in value) { + y = yAfter - FONT_SIZE * 0.5; + currentPar++; processedAnyParagraph = true; - console.log(`Parágrafo ${currentPar} processado com sucesso, nova posição y=${y}`); } else { - value = undefined; - // Verifica se ainda temos espaço para pelo menos uma linha break; - if (y < margens.bottom + FONT_SIZE * 2) { } + console.log(`Parágrafo ${currentPar} processado com sucesso, nova posição y=${y}`); + + // Verifica se ainda temos espaço para pelo menos uma linha + if (y < margens.bottom + FONT_SIZE * 2) { + console.log(`Espaço insuficiente para próximo parágrafo, criando nova página`); + break; + } + } + } + + pageIndex++; + } + if (pageIndex >= MAX_PAGES) { + console.warn(`AVISO: Número máximo de páginas (${MAX_PAGES}) atingido. Geração de PDF interrompida.`); + } + console.log(`PDF gerado com ${pageIndex} páginas`); + const pdfBytes = await pdfDoc.save(); + return Buffer.from(pdfBytes); + } catch (error) { + console.error('Erro geral ao gerar PDF:', error); + throw error; + } + } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -} } }); return value !== undefined ? value : match; } } break; value = undefined; } else { value = value[part]; if (value && typeof value === 'object' && part in value) { for (const part of keyParts) { let value = dados; const keyParts = key.trim().split('.'); return template.replace(/\{\{([^}]+)\}\}/g, (match, key) => { private processarTemplate(template: string, dados: any): string { } } throw error; console.error('Erro geral ao gerar PDF:', error); } catch (error) { return Buffer.from(pdfBytes); const pdfBytes = await pdfDoc.save(); console.log(`PDF gerado com ${pageIndex} páginas`); } console.warn(`AVISO: Número máximo de páginas (${MAX_PAGES}) atingido. Geração de PDF interrompida.`); if (pageIndex >= MAX_PAGES) { } } currentPar++; console.log(`AVISO: Não foi possível processar nenhum parágrafo na página ${pageIndex}, avançando`); if (!processedAnyParagraph && currentPar < paragrafos.length) { // algo está errado. Vamos avançar para o próximo para evitar loop infinito. // Se não conseguimos processar nenhum parágrafo nesta página e ainda temos parágrafos, pageIndex++; } } } break; console.log(`Espaço insuficiente para próximo parágrafo, criando nova página`); } + private processarTemplate(template: string, dados: any): string { + return template.replace(/\{\{([^}]+)\}\}/g, (match, key) => { + const keyParts = key.trim().split('.'); + let value = dados; + for (const part of keyParts) { + if (value && typeof value === 'object' && part in value) { + value = value[part]; + } else { + value = undefined; + break; + } + } return value !== undefined ? value : match; }); }