REFACTOR: create builder for parser reporterand fix pdf

This commit is contained in:
marcos-silva-rodrigues
2025-04-29 15:18:46 -03:00
parent 04accb6689
commit 36997403e1
9 changed files with 129 additions and 76 deletions
+3 -3
View File
@@ -1,11 +1,11 @@
import { stringify } from 'csv'
import { Parser } from './parser.interface';
export class CsvParser<T> {
export class CsvParser<T> implements Parser<T>{
async parse(data: T[]) {
return new Promise((resolve, reject) => {
return new Promise<string>((resolve, reject) => {
stringify(data, { header: true }, function (err, output) {
if (err) reject(err);
console.log(output)
resolve(output)
});
+3 -2
View File
@@ -1,9 +1,10 @@
import { readFileSync } from 'fs';
import Handlebars from 'handlebars';
import { Parser } from './parser.interface';
export class HtmlParser<T> {
export class HtmlParser<T> implements Parser<T> {
constructor(private readonly templatePath: string) {}
parse(data: T[]) {
async parse(data: T[]) {
const templateSource = readFileSync(this.templatePath, 'utf8');
const template = Handlebars.compile(templateSource);
+1
View File
@@ -0,0 +1 @@
export type TypeParser = "html" | "csv" | "pdf"
+29
View File
@@ -0,0 +1,29 @@
import path from 'path';
import { TypeParser } from './parser-types';
import { HtmlParser } from './html-parser';
import { CsvParser } from './csv-parser';
import { PDFParser } from './pdf-parser';
import { Parser } from './parser.interface';
export class ParserBuilder {
static build<T>(type: TypeParser): Parser<T> {
const templatePath = path.join(
__dirname,
'../../../src/template/pii-reporter.html',
);
if (type === 'html') {
const htmlParser = new HtmlParser<T>(templatePath);
return htmlParser;
} else if (type === 'csv') {
const csvParser = new CsvParser<T>();
return csvParser;
} else if (type === 'pdf') {
const htmlParser = new HtmlParser<T>(templatePath);
const pdfParser = new PDFParser(htmlParser);
return pdfParser;
}
throw new Error('Unsupported Type: ' + type);
}
}
+3
View File
@@ -0,0 +1,3 @@
export interface Parser<T> {
parse(data: T[]): Promise<string | Buffer>
}
+23 -14
View File
@@ -1,30 +1,39 @@
import puppeteer from "puppeteer";
import puppeteer from 'puppeteer';
import { Parser } from './parser.interface';
import { HtmlParser } from './html-parser';
export class PDFParser<T extends string> {
async parse(data: T) {
export class PDFParser<T> implements Parser<T> {
constructor(private htmlParser: HtmlParser<T>) {}
async parse(data: T[]) {
try {
const browser = await puppeteer.launch({
executablePath: process.env.PUPPETEER_EXECUTABLE_PATH,
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage']
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
],
});
const page = await browser.newPage();
page.setDefaultNavigationTimeout(0);
await page.setContent(data, {
const html = await this.htmlParser.parse(data);
await page.setContent(html, {
waitUntil: 'networkidle0',
timeout: 30000
timeout: 30000,
});
// Configurações adicionais para garantir um PDF válido
const pdfBuffer = await page.pdf({
const pdf = await page.pdf({
format: 'A4',
printBackground: true,
margin: {
top: '20mm',
right: '15mm',
bottom: '20mm',
left: '15mm'
left: '15mm',
},
preferCSSPageSize: true,
displayHeaderFooter: false,
@@ -34,12 +43,12 @@ export class PDFParser<T extends string> {
pageRanges: '',
tagged: true,
outline: false,
timeout: 30000
timeout: 30000,
});
await browser.close();
return pdfBuffer;
return Buffer.from(pdf);
} catch (error) {
console.error('Error generating PDF:', error);
throw error;