C# 在不预览的情况下直接打印RDLC并解决了只打印一部分的bug RDLC连打.

  • Post author:
  • Post category:其他


#region 报告打印相关代码
        private void barPrint_Click(object sender, EventArgs e)
        {
            try
            { 
                LocalReport localReport = new LocalReport();
                RefreshReport(localReport);
                Export(localReport);
                m_currentPageIndex = 0;
                Print();

            }
            catch (Exception ex)
            {
                log.Error(ex);
                MessageBox.Show(ex.Message);
            }

        }
         
        int m_currentPageIndex;
        List<Stream> m_streams;

private void RefreshReport(LocalReport localReport)
        {
            if (CurrentEditModel == null)
            {
                return;
            }

            //第一步:清除之前的数据
            localReport.DataSources.Clear();

            var templateContent = GetReportTemplate();
            if (templateContent == null)
            {
                return;
            }
            //第二步:指定报表路径
            //localReport.ReportPath = "Report2.rdlc";
            localReport.EnableExternalImages = true;
            localReport.ShowDetailedSubreportMessages = true;
            localReport.LoadReportDefinition(new StringReader(templateContent));

            //第三步:构造新的DataTable
            //DataTable dt = new DataTable("DataTable1");
            //dt.Columns.Add("Name");
            //dt.Columns.Add("Score");
            //dt.Columns.Add("Id");
            //dt.Rows.Add(new object[] { "语文", 80, "Y0001" });
            //dt.Rows.Add(new object[] { "数学", 75, "S0001" });
            //dt.Rows.Add(new object[] { "英文", 96, "E0001" });
            //名称不能写错,和报表中的数据集名称一致
            //ReportDataSource rdsItem = new ReportDataSource("DataSet1", dt);
            //var model = new ReportModel();
            //DataModel

            //此处可以有多个数据源 
            localReport.DataSources.Add(new ReportDataSource("Master", new List<Sampleinfo>() { CurrentEditModel }));
            //localReport.DataSources.Add(new ReportDataSource("Details", new List<BL_Sampleresult>() {   }));
            localReport.DataSources.Add(new ReportDataSource("ReportConfig", new List<ReportConfig>() { GetReportConfig() }));
            localReport.DataSources.Add(new ReportDataSource("DiagnosisData", new List<object>() { diagnosisUI.GetXmlDataModel() }));
            localReport.DataSources.Add(new ReportDataSource("Images", new List<Images>() { GetImages() }));



            //第四步:构造参数
            //List<ReportParameter> lstParameter = new List<ReportParameter>() {
            //    new ReportParameter("Title",this.txtTitle.Text),
            //    new ReportParameter("Id",this.txtId.Text),
            //    new ReportParameter("Name",this.txtName.Text),
            //    new ReportParameter("Age",this.txtAge.Text),
            //    new ReportParameter("Sex",this.txtSex.Text),
            //    new ReportParameter("Salary",this.txtSalary.Text),
            //    new ReportParameter("Depart",this.txtDepart.Text)
            //};
            //localReport.SetParameters(lstParameter);
            //if (lstParameters != null && lstParameters.Count > 0)
            //{
            //    localReport.SetParameters(lstParameters);
            //}

        }
        
        private void Export(LocalReport report)
        {
            string deviceInfo =
            "<DeviceInfo>" +
            " <OutputFormat>EMF</OutputFormat>" +
            " <PageWidth>210mm</PageWidth>" +
            " <PageHeight>295mm</PageHeight>" +
            " <MarginTop>0mm</MarginTop>" +
            " <MarginLeft>0mm</MarginLeft>" +
            " <MarginRight>0mm</MarginRight>" +
            " <MarginBottom>0mm</MarginBottom>" +
            "</DeviceInfo>";
            Warning[] warnings;
            m_streams = new List<Stream>();

            //可提升权限。报表加载速度进一步提升。
            report.SetBasePermissionsForSandboxAppDomain(new PermissionSet(PermissionState.Unrestricted));
            report.Render("Image", deviceInfo, CreateStream, out warnings);

            foreach (Stream stream in m_streams)
            {
                stream.Position = 0;
            }
        }

        private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek)
        {
            MemoryStream stream = new MemoryStream();
            m_streams.Add(stream);
            return stream;
        }

        public void Print()
        {

            m_currentPageIndex = 0;

            if (m_streams == null || m_streams.Count == 0)
                return;
            //声明PrintDocument对象用于数据的打印
            PrintDocument printDoc = new PrintDocument();
            //指定需要使用的打印机的名称,使用空字符串""来指定默认打印机 
            //printDoc.PrinterSettings.PrinterName = "";//不指定就是使用默认打印机

            //判断指定的打印机是否可用
            if (!printDoc.PrinterSettings.IsValid)
            {
                MessageBox.Show("Can't find printer");
                return;
            }

            PaperSize p = null;
            foreach (PaperSize ps in printDoc.PrinterSettings.PaperSizes)
            {
                if (ps.PaperName.Equals("A4"))
                    p = ps;
            }
            printDoc.DefaultPageSettings.PaperSize = p; //纸张大小其实可以不选定的.
            printDoc.DefaultPageSettings.Landscape = false;//纵打

            //声明PrintDocument对象的PrintPage事件,具体的打印操作需要在这个事件中处理。
            printDoc.PrintPage += new PrintPageEventHandler(printDocument1_PrintPage);
            //执行打印操作,Print方法将触发PrintPage事件。
            printDoc.Print();
        }

        private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            //System.Drawing.Imaging.Metafile pageImage = new System.Drawing.Imaging.Metafile(m_streams[m_currentPageIndex]);

            //e.Graphics.DrawImage(pageImage, 0, 0);

            //m_currentPageIndex++;
            //e.HasMorePages = (m_currentPageIndex < m_streams.Count);
			//上面的代码有bug,打印出来的只有一部分内容. 下面的代码加了个Rectangle 就解决了只打印一部分的问题
            System.Drawing.Imaging.Metafile pageImage = new System.Drawing.Imaging.Metafile(m_streams[m_currentPageIndex]);

            // Adjust rectangular area with printer margins.       
            Rectangle adjustedRect = new Rectangle(
                            e.PageBounds.Left - (int)e.PageSettings.HardMarginX,
                            e.PageBounds.Top - (int)e.PageSettings.HardMarginY, e.PageBounds.Width,
                            e.PageBounds.Height);       // Draw a white background for the report 
            e.Graphics.FillRectangle(Brushes.White, adjustedRect);       // Draw the report content       
            e.Graphics.DrawImage(pageImage, adjustedRect);       // Prepare for the next page. Make sure we haven't hit the end.       
            m_currentPageIndex++;
            e.HasMorePages = (m_currentPageIndex < m_streams.Count); 
        }

        #endregion 报告打印相关代码



版权声明:本文为phker原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。