@jackiemacklein/nettz-utils
Version:
Serviços de imagem, e-mail, códigos de barras, utilitários numéricos e componentes React para apps Node.js com TypeScript
266 lines (265 loc) • 9.78 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PRINT_PRESETS = void 0;
exports.pageToPDF = pageToPDF;
exports.generateThermalPDF = generateThermalPDF;
exports.generateA4PDF = generateA4PDF;
exports.generateReceiptPDF = generateReceiptPDF;
exports.generateLabelPDF = generateLabelPDF;
exports.generateCustomSizePDF = generateCustomSizePDF;
exports.getPrintPreset = getPrintPreset;
exports.getAvailablePrintTypes = getAvailablePrintTypes;
exports.htmlInject = htmlInject;
const lodash_1 = require("lodash");
const puppeteer_1 = __importDefault(require("puppeteer"));
// Configurações predefinidas para diferentes tipos de impressão
exports.PRINT_PRESETS = {
thermal: {
format: "A4", // Usar A4 como base, mas com CSS customizado
margin: { bottom: 5, left: 5, right: 5, top: 5 },
preferCSSPageSize: true,
displayHeaderFooter: false,
customWidth: 80, // 80mm para impressora térmica
customHeight: 297, // Altura A4
},
a4: {
format: "A4",
margin: { bottom: 25, left: 25, right: 25, top: 25 },
preferCSSPageSize: false,
displayHeaderFooter: false,
},
a5: {
format: "A5",
margin: { bottom: 20, left: 20, right: 20, top: 20 },
preferCSSPageSize: false,
displayHeaderFooter: false,
},
letter: {
format: "Letter",
margin: { bottom: 25, left: 25, right: 25, top: 25 },
preferCSSPageSize: false,
displayHeaderFooter: false,
},
legal: {
format: "Legal",
margin: { bottom: 25, left: 25, right: 25, top: 25 },
preferCSSPageSize: false,
displayHeaderFooter: false,
},
receipt: {
format: "A4", // Usar A4 como base
margin: { bottom: 3, left: 3, right: 3, top: 3 },
preferCSSPageSize: true,
displayHeaderFooter: false,
customWidth: 60, // 60mm para recibo
customHeight: 297, // Altura A4
},
label: {
format: "A4", // Usar A4 como base
margin: { bottom: 2, left: 2, right: 2, top: 2 },
preferCSSPageSize: true,
displayHeaderFooter: false,
customWidth: 40, // 40mm para etiqueta
customHeight: 297, // Altura A4
},
custom: {
format: "A4",
margin: { bottom: 25, left: 25, right: 25, top: 25 },
preferCSSPageSize: false,
displayHeaderFooter: false,
},
};
async function pageToPDF({ url, customStyle, specificElement, pages, margin, displayHeaderFooter, preferCSSPageSize, format, content, returnBuffer = false, printType = "a4", customWidth, customHeight, }) {
try {
// Aplica as configurações do tipo de impressão selecionado
const preset = exports.PRINT_PRESETS[printType];
const finalFormat = format || preset.format;
const finalMargin = margin || preset.margin;
const finalDisplayHeaderFooter = displayHeaderFooter !== null && displayHeaderFooter !== void 0 ? displayHeaderFooter : preset.displayHeaderFooter;
const finalPreferCSSPageSize = preferCSSPageSize !== null && preferCSSPageSize !== void 0 ? preferCSSPageSize : preset.preferCSSPageSize;
// Configuração customizada de tamanho se especificado
const pdfOptions = {
pageRanges: pages || "",
format: finalFormat,
margin: finalMargin,
displayHeaderFooter: finalDisplayHeaderFooter,
printBackground: true,
preferCSSPageSize: finalPreferCSSPageSize,
};
// Se especificou largura e altura customizadas, usa elas
if (customWidth && customHeight) {
pdfOptions.width = `${customWidth}mm`;
pdfOptions.height = `${customHeight}mm`;
delete pdfOptions.format; // Remove format quando usa dimensões customizadas
}
else if (preset.customWidth && preset.customHeight) {
// Se o preset tem dimensões customizadas, usa elas
pdfOptions.width = `${preset.customWidth}mm`;
pdfOptions.height = `${preset.customHeight}mm`;
delete pdfOptions.format; // Remove format quando usa dimensões customizadas
}
// cria o navegador virtual
const browser = await puppeteer_1.default.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();
// Configurações importantes para renderização de imagens
await page.setViewport({ width: 1200, height: 800 });
// Aguarda o carregamento completo das imagens
await page.setDefaultNavigationTimeout(30000);
await page.setDefaultTimeout(30000);
if (url) {
await page.goto(url, {
waitUntil: "networkidle0",
timeout: 30000,
});
}
if (content) {
// Aguarda um pouco para garantir que as imagens carreguem
await page.setContent(`<html><head><style type="text/css">${customStyle}</style></head><body>${content}</body></html>`, {
waitUntil: "networkidle0",
});
}
else {
if (specificElement) {
const innerHTML = await page.$eval(specificElement, (element) => {
return element.innerHTML;
});
await page.setContent(`<html><head><style type="text/css">${customStyle}</style></head><body>${innerHTML}</body></html>`, {
waitUntil: "networkidle0",
});
}
}
if (customStyle) {
await page.addStyleTag({ content: customStyle });
}
// Aguarda um pouco mais para garantir que tudo foi renderizado
// Aguarda especificamente pelas imagens carregarem se existirem
try {
await page.waitForSelector("img", { timeout: 5000 });
}
catch (error) {
console.log("Imagem não carregada", error);
}
// gera o pdf
const pdf = await page.pdf(pdfOptions);
await browser.close();
return returnBuffer
? Buffer.from(pdf)
: Buffer.from(pdf).toString("base64");
}
catch (err) {
console.log("err2", err);
return "";
}
}
/**
* Função auxiliar para gerar PDF para impressora térmica (cupom)
*/
async function generateThermalPDF(props) {
return pageToPDF({ ...props, printType: "thermal" });
}
/**
* Função auxiliar para gerar PDF para papel A4
*/
async function generateA4PDF(props) {
return pageToPDF({ ...props, printType: "a4" });
}
/**
* Função auxiliar para gerar PDF para recibo pequeno
*/
async function generateReceiptPDF(props) {
return pageToPDF({ ...props, printType: "receipt" });
}
/**
* Função auxiliar para gerar PDF para etiqueta
*/
async function generateLabelPDF(props) {
return pageToPDF({ ...props, printType: "label" });
}
/**
* Função auxiliar para gerar PDF com dimensões customizadas
*/
async function generateCustomSizePDF(props) {
const { width, height, ...rest } = props;
return pageToPDF({
...rest,
printType: "custom",
customWidth: width,
customHeight: height,
});
}
/**
* Função auxiliar para obter as configurações de um tipo de impressão
*/
function getPrintPreset(printType) {
return exports.PRINT_PRESETS[printType];
}
/**
* Função auxiliar para listar todos os tipos de impressão disponíveis
*/
function getAvailablePrintTypes() {
return Object.keys(exports.PRINT_PRESETS);
}
/**
* @author Jackiê Macklein
* @company Onside tecnologia/Nettz
* @copyright Todos direitos reservados.
* @description Injeção de variáveis em um conteúdo HTML
* @param {HtmlInjectProps} props
* @returns {string}
* @example
* const htmlContent = `
* <h1>{{name}}</h1>
* <p>{{age}}</p>
* `;
* const data = { name: "John", age: 30 };
* const data2 = {person: { name: "John", age: 30 }};
* const variables = [{ key: "name", column_name: "name", table_alias: "", function: "" }];
* const variables2 = [{ key: "name", column_name: "name", table_alias: "person", function: "" }];
* const result = htmlInject({ data: data, variables: variables, htmlContent: htmlContent });
* const result2 = htmlInject({ data: data2, variables: variables2, htmlContent: htmlContent });
* result === "<h1>John</h1><p>30</p>"
* result2 === "<h1>John</h1><p>30</p>"
*/
function htmlInject({ data, variables, htmlContent, }) {
try {
let converted = htmlContent;
for (let i = 0; i < variables.length; i++) {
const variable = variables[i];
let path = "";
let value = "";
if (variable.table_alias) {
path = `${variable.table_alias}.${variable.column_name}`;
}
else {
path = variable.column_name;
}
if (variable.function) {
value = eval(variable.function);
console.log({ value });
}
else {
value = (0, lodash_1.get)(data, path);
}
converted = converted.replace(new RegExp(`{{${variable.key}}}`, "g"), value);
}
return converted;
}
catch (error) {
console.log(error);
return "";
}
}