What: I have a program which prints an RDLC report page using a CSV file when using a printer.
Issue: When the user prints to pdf, it saves each page 1 by 1 which is not efficent when there are 1000 pages to print.
Intent: When user selects specifically microsoft print to pdf, all files will print to 1 single pdf file. However other printers will print as usual.
Current situation: When printing to microsoft print to pdf, it prints to 1 file at a time, so 1000 records = 1000 files.
Below is the source code for the printer class and main class where the printer class is called
LocalReportExtensioncs.cs file
this file runs for every page so if there is 1000 pages to print, it will run 1000 times.
public static void PrintToPrinter(this LocalReport report)
{
var pageSettings = new PageSettings();
pageSettings.Color = false;
pageSettings.PaperSize = report.GetDefaultPageSettings().PaperSize;
pageSettings.Landscape = report.GetDefaultPageSettings().IsLandscape;
pageSettings.Margins = report.GetDefaultPageSettings().Margins;
pageSettings.Landscape = true;
Print(report, pageSettings);
}
public static void Print(this LocalReport report, PageSettings pageSettings)
{
string deviceInfo =
$@"<DeviceInfo>
<OutputFormat>EMF</OutputFormat>
<PageWidth>{pageSettings.PaperSize.Width * 100}in</PageWidth>
<PageHeight>{pageSettings.PaperSize.Height * 100}in</PageHeight>
<MarginTop>{pageSettings.Margins.Top * 100}in</MarginTop>
<MarginLeft>{pageSettings.Margins.Left * 100}in</MarginLeft>
<MarginRight>{pageSettings.Margins.Right * 100}in</MarginRight>
<MarginBottom>{pageSettings.Margins.Bottom * 100}in</MarginBottom>
</DeviceInfo>";
Warning[] warnings;
var streams = new List<Stream>();
var currentPageIndex = 0;
report.Render("Image", deviceInfo,
(name, fileNameExtension, encoding, mimeType, willSeek) =>
{
var stream = new MemoryStream();
streams.Add(stream);
return stream;
}, out warnings);
foreach (Stream stream in streams)
stream.Position = 0;
if (streams.Equals(null) || streams.Count == 0)
throw new Exception("Error: no stream to print.");
var printDocument = new PrintDocument();
printDocument.DocumentName = "default";
var printerController = new StandardPrintController();
printDocument.PrintController = printerController;
printDocument.DefaultPageSettings.Color = false;
printDocument.DefaultPageSettings = pageSettings;
DialogResult result = DialogResult.Retry;
while (!printDocument.PrinterSettings.IsValid)
{
result = MessageBox.Show("Error, Default printer hasnt been selected", "Error", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
if (result == DialogResult.Cancel)
{
Environment.Exit(0);
}
}
printDocument.PrintPage += (sender, e) =>
{
Metafile pageImage = new Metafile(streams[currentPageIndex]);
Rectangle adjustedRect = new Rectangle(
e.PageBounds.Left - (int)e.PageSettings.HardMarginX,
e.PageBounds.Top - (int)e.PageSettings.HardMarginY,
e.PageBounds.Width,
e.PageBounds.Height);
e.Graphics.FillRectangle(Brushes.White, adjustedRect);
e.Graphics.DrawImage(pageImage, adjustedRect);
currentPageIndex++;
e.HasMorePages = (currentPageIndex < streams.Count);
e.Graphics.DrawRectangle(Pens.Red, adjustedRect);
};
printDocument.EndPrint += (Sender, e) =>
{
if (streams != null)
{
foreach (Stream stream in streams)
stream.Close();
streams = null;
}
};
printDocument.PrinterSettings.PrinterName = Properties.Settings.Default.PrinterName;
printDocument.Print();
}
}
In main.cs file where the RDLC report data is inserted,
localReport = AddToLocalReport(localReport);
localReport.ReportPath = Application.StartupPath + "\\RDLCreport.rdlc";
for (int i = 1; i < printCounter + 1; i++)
{
if (Properties.Settings.Default.canPrint == true)
{
localReport.PrintToPrinter();
}
}