0

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();
                            }
                        }
stuartd
  • 70,509
  • 14
  • 132
  • 163
  • Sounds like you need to separate out the actual from the `Report` object, so that it just renders the output, and you can do something like `var pages = localReport.RenderedPages(); PrintToPrinter(Enumerable.Range(1, printCounter).SelectMany(i => pages));` – Charlieface Jul 01 '22 at 00:49
  • @Charlieface thanks for the comment, would these lines of code go in the local report class? also RenderPages isnt valid in LocalReport library – KamadoTanjiro2 Jul 01 '22 at 01:59
  • My point is that you need to change that class to instead of actually printing to just return an `IEnumerable` of pages, then you can aggregate them all together to print – Charlieface Jul 01 '22 at 02:16

0 Answers0