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.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 = `
${data.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, win32: ['-nointterrupt'] // Tenta evitar comandos extras, mas o pdf-to-printer tem opções limitadas de corte. // Na verdade, o pdf-to-printer usa SumatraPDF, que não tem flag explícita de "no-cut". // O corte geralmente é configuração do driver ou do tamanho do papel. // Mas vamos garantir que não estamos enviando nada extra. }); 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); } } } }