svr-imp/src/services/create-printer.ts

143 lines
3.9 KiB
TypeScript
Raw Normal View History

import { Injectable } from '@nestjs/common';
import { PrintDataDto } from '../dto/print-data.dto';
import { PrintHtmlDto } from '../dto/print-html.dto';
const { ThermalPrinter, PrinterTypes } = require('node-thermal-printer');
@Injectable()
export class ListPrinterService {
private readonly printerType = PrinterTypes.EPSON;
async printReceipt(data: PrintDataDto): Promise<{ success: boolean; message: string }> {
if (!data.lines?.length) {
return { success: false, message: 'No lines provided' };
}
try {
let printerInterface = data.printerInterface;
if (printerInterface && !printerInterface.includes('://') && !printerInterface.startsWith('printer:')) {
printerInterface = `printer:${printerInterface}`;
}
const printer = new ThermalPrinter({
type: this.printerType,
interface: printerInterface,
});
this.applyAlignment(printer, data.alignment);
for (const line of data.lines) {
if (data.upsideDown) {
printer.upsideDown(true);
}
printer.println(line);
if (data.upsideDown) {
printer.upsideDown(false);
}
}
printer.drawLine();
printer.cut();
printer.beep();
await printer.execute();
return { success: true, message: 'Print successful!' };
} catch (error) {
return {
success: false,
message: `Print failed: ${error.message || error}`
};
}
}
private applyAlignment(printer: any, alignment?: string): void {
if (alignment === 'center') {
return printer.alignCenter();
}
if (alignment === 'right') {
return printer.alignRight();
}
return printer.alignLeft();
}
async printHtml(data: PrintHtmlDto): Promise<{ success: boolean; message: string }> {
const puppeteer = require('puppeteer');
const pdfPrinter = require('pdf-to-printer');
const path = require('path');
const fs = require('fs');
const os = require('os');
const tempFilePath = path.join(os.tmpdir(), `print-${Date.now()}.pdf`);
try {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
const width = data.width || '80mm';
const height = data.height;
const fullHtml = `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://cdn.tailwindcss.com"></script>
<style>
html, body {
margin: 0;
padding: 0;
-webkit-print-color-adjust: exact;
width: 100%;
height: 100%;
}
body {
transform-origin: top left;
zoom: 1.25;
}
@page { size: ${width} ${height || 'auto'}; margin: 0; }
</style>
</head>
<body>
${data.html}
</body>
</html>
`;
await page.setContent(fullHtml, { waitUntil: 'networkidle0' });
const pdfOptions: any = {
path: tempFilePath,
printBackground: true,
width: width,
margin: { top: '0px', right: '0px', bottom: '0px', left: '0px' }
};
if (height) {
pdfOptions.height = height;
}
await page.pdf(pdfOptions);
await browser.close();
await pdfPrinter.print(tempFilePath, { printer: data.printerName });
return { success: true, message: 'HTML convertido (com Tailwind) e enviado para impressão!' };
} catch (error) {
console.error('Erro na impressão HTML:', error);
return { success: false, message: `Erro ao imprimir HTML: ${error.message}` };
} finally {
try {
if (fs.existsSync(tempFilePath)) {
fs.unlinkSync(tempFilePath);
}
} catch (e) {
console.warn('Não foi possível deletar arquivo temp:', e);
}
}
}
}