Im trying to figure out a way to print in a POS printer without knowing the height of the print.
The idea to dynamically fill a RDLC report with elements in a tree view (that’s done) and then send it to silent printing. This is where it gets tricky. The report size its set to the default POS size (80mm to 3276mm)
The idea its to start with a height (need to experiment what value fits best)
And then start adding based on the number of items being aggregated to the report so it would be something like this
double paperWidthMm = report_imprime_comanda.LocalReport.GetDefaultPageSettings().PaperSize.Width;
double totalHeight = 30;
foreach (TreeNode parentNode in parentNodes)
{
if (parentNode.Tag is Comanda comandaMain)
{
double itemHeight = GetItemHeight(comandaMain);
totalHeight += itemHeight;
filteredComandas.Add(comandaMain);
}
}
// Dynamically set the page height based on total content height
int paperWidthHundredthsOfInch = (int)(paperWidthMm / 25.4 * 100);
int paperHeightHundredthsOfInch = (int)(totalHeight / 25.4 * 100);
PageSettings pageSettings = new PageSettings
{
PaperSize = new PaperSize("Custom", paperWidthHundredthsOfInch, paperHeightHundredthsOfInch)
};
MessageBox.Show("Paper Size: " + pageSettings, "Tamaño papel", MessageBoxButtons.OK, MessageBoxIcon.Warning);
report_imprime_comanda.SetPageSettings(pageSettings);
// Bind filtered data to the report
report_imprime_comanda.LocalReport.DataSources.Clear();
report_imprime_comanda.LocalReport.DataSources.Add(new ReportDataSource("Comandas", filteredComandas));
// Refresh the report to apply the changes
report_imprime_comanda.RefreshReport();
PrintPOS printPOS = new PrintPOS();
// Render and print the report
printPOS.PrintReportToPrinter(report_imprime_comanda.LocalReport, printerName);
This the function that adds inches to the report based on the elements:
private double GetItemHeight(Comanda item)
{
// Base height for each comanda item
double baseHeight = 30;
// Additional height for each child note
double noteHeight = 15;
// Calculate total height
double totalHeight = baseHeight;
// Split the notes by ';' to count them
if (!string.IsNullOrEmpty(item.NOTAS))
{
string[] notes = item.NOTAS.Split(';');
totalHeight += notes.Length * noteHeight;
}
return totalHeight;
}
This is function that does the actual print
public void PrintReportToPrinter(LocalReport report, string printerName)
{
// Configure print settings for the POS printer
PrinterSettings printerSettings = new PrinterSettings
{
PrinterName = printerName,
Copies = 1,
PrintToFile = false,
};
// Create a PrintDocument object
PrintDocument printDoc = new PrintDocument
{
PrinterSettings = printerSettings
};
printDoc.PrintPage += (sender, args) =>
{
// Render the report to an image
Warning[] warnings;
string[] streamIds;
string mimeType;
string encoding;
string extension;
byte[] bytes = report.Render(
"Image", null, out mimeType, out encoding, out extension,
out streamIds, out warnings);
using (System.Drawing.Image image = System.Drawing.Image.FromStream(new System.IO.MemoryStream(bytes)))
{
args.Graphics.DrawImage(image, args.MarginBounds);
args.HasMorePages = false;
}
};
// Print the document
printDoc.Print();
}
}
If there is a more simple way. I’m all ears.
Any help is appreciated.
Thanks in advance !
Im expecting to print directly to a POS printer with dynamic data.