lukevp / ESC-POS-.NET

Efficient, Easy to Use Thermal Printing & POS (Windows/Linux/OSX, WiFi/BT/USB/Ethernet)
MIT License
523 stars 171 forks source link

I want to use foreach inside ByteSplicer.Combine or other way to print ? #274

Closed Eduardomendesc closed 2 weeks ago

Eduardomendesc commented 4 months ago

I want to print, so I don't want to use the ByteSplicer.Combine method because I have a dynamic foreach in the product list. Is there any way to print without using ByteSplicer.Combine?

My code below:

public async Task Print(int IDVenda) { var hostnameOrIp = "180.22.2.37"; var port = 9100; var printer = new ImmediateNetworkPrinter(new ImmediateNetworkPrinterSettings() { ConnectionString = $"{hostnameOrIp}:{port}", PrinterName = "TestPrinter" }); var response = false; var e = new EPSON(); try { Venda venda = await dbfitaz.Vendas.FindAsync(IDVenda); if (venda == null) { return Json(new { success = false, message = "Sales Not Found" }, JsonRequestBehavior.AllowGet); }

    _ = printer.WriteAsync(
        ByteSplicer.Combine(
         e.CenterAlign(),
         e.PrintImage(System.IO.File.ReadAllBytes(Server.MapPath("/Images/logo1.png")), true),
         e.PrintLine("DEV MOZAMBIQUE"),
         e.PrintLine("Av. Mozambique"),
         e.PrintLine("Maputo"),
         e.PrintLine("Tel: +258 841111"),
         e.PrintLine("VAT: 111111"),
         e.SetStyles(PrintStyle.Underline),
         e.PrintLine("www.brithol.com"),
         e.SetStyles(PrintStyle.None),
         e.PrintLine(""),
         e.LeftAlign(),
         e.PrintLine("Receipt n: " + venda.ID_venda + "/" + venda.Data_hora.Value.ToString("yyyy")),
         e.PrintLine("Document Original:             " + venda.Data_hora.Value.ToString("dd-MM-yyyy HH:mm")),
         e.PrintLine("------------------------------------------------"),
         e.PrintLine(""),
         e.PrintLine("VAT CLIENT: ----------"),
         e.PrintLine("NAME: FINAL"),
         e.PrintLine(""),
         e.SetStyles(PrintStyle.Bold | PrintStyle.FontB),
         e.PrintLine("Item (Produto)"),
         e.PrintLine("Qtd. * Price                         Total Value"),
         e.PrintLine("------------------------------------------------"),
         e.SetStyles(PrintStyle.FontB),
         venda.VendaProdutoes.ForEach(vendasPrd =>
         {
             e.PrintLine(vendasPrd.Produto.Product_name);
             e.PrintLine(vendasPrd.Qtd + " * " + vendasPrd.Preco_unitario + "                                  " + vendasPrd.Total);
             e.PrintLine("------------------------------------------------");
         }),
         e.RightAlign(),
         e.PrintLine("SUBTOTAL         " + venda.Total_iliquido),
         e.PrintLine("Total IVA 16%:         " + venda.Total_iva),
         e.PrintLine("Total:         " + venda.Total),
         e.PrintLine(""),
         e.SetStyles(PrintStyle.DoubleWidth | PrintStyle.Underline | PrintStyle.DoubleHeight | PrintStyle.Bold),
         e.PrintLine("Total to Pay: " + venda.Total + "\n"),
         e.PrintLine(""),
         e.CenterAlign(),
         e.SetStyles(PrintStyle.FontB),
         e.PrintLine("Processado por computador"),
         e.PrintLine(""),
         e.PrintLine("Operador: " + venda.AspNetUser.UserNameTango),
         e.PrintLine(""),
         e.PrintLine("Obrigado pela preferencia!"),
         e.PrintLine(""),
         e.PartialCutAfterFeed(5)
         )
        );
    response = true;
}
catch (Exception)
{
    response = false;
}

if (response)
{
    return Json(new { success = true, message = "Printed Successfully" }, JsonRequestBehavior.AllowGet);
}
else
{
    return Json(new { success = false, message = "Print Failed" }, JsonRequestBehavior.AllowGet);
}

}

igorocampos commented 4 months ago

Hey @Eduardomendesc, of course you can! ByteSplicer is just a helper method, you don't need it to print anything! the Printer.Write() method (or in your case Printer.WriteAsync()) intakes a byte[] parameter, or even any amount of byte[] parameters you wish to send to it!

So, you can just have a byte[] variable that stores what you wish to print. You go through your ForEach, appending every byte into the variable, and lastly you call the Write method passing the variable as a parameter.

However if you really want to go the LINQ route, perhaps you would like to use Select() instead of ForEach(), something like this

/* .
   .
   .
*/    

   e.SetStyles(PrintStyle.FontB),
   ByteSplicer.Combine(venda.VendaProdutos.Select(vendasPrd =>
   {
       ByteSplicer.Combine(
           e.PrintLine(vendasPrd.Produto.Product_name),
           e.PrintLine(vendasPrd.Qtd + " * " + vendasPrd.Preco_unitario + "                                  " + vendasPrd.Total),
           e.PrintLine("------------------------------------------------")
       );
   })),
   e.RightAlign(),

/* .
   .
   .
*/

WARNING: I haven't tested this code, just trying to show you the concept idea.