C# 报表(RDLC)实现打印,Word、Excel、PDF导出

目录

1,整体效果

2,什么是RDLC

3,RDLC基本应用

3.1,添加RDLC文件

3.2, 绑定数据集(示例选择绑定对象)。

3.3, 添加参数字段

3.4,添加文本框

3.5,添加表格

3.6,自定义表达式

3.7,效果

4,RDLC分组

4.1,准备的对象类

4.2,构建RDLC布局

4.3,添加分组信息后

4.4,效果

5, RDLC子报表

5.1,子报表使用的实例类

5.2,创建子报表

5.3,主报表添加子报表

5.4, 注意事项

5.5, 效果:

6,RDLC添加图片

6.1,使用嵌入图片

6.2,使用参数传入外部图片

 6.3,注意事项

7,RDLC添加条码

7.1,RDLC控件准备

​7.2,代码

 7.3,效果

8,WPF中添加ReportViewer

9,RDLC常见问题

9.1,报表出现空白页

10,打印与导出

10.1,打印导出帮助类

10.2,打印

10.3,打印效果

10.4,导出

10.5,导出效果

11,Demo链接


1,整体效果

2,什么是RDLC

        .rdlc是VisualStudio中报表文件的后缀名,是Report Definition Language Client的缩写,直接翻译过来可以理解为报表定义语言客户端。这样听起来很难懂,不知所云。其实和rdlc同时存在的还有一个rdl,就是上面这个全程前3个单词的缩写。从SQL Server 2005开始,微软提供了一个报表服务(Reporting Service),而rdl是指那些针对报表服务部署在服务器端的报表,而rdlc是指在本地的一些报表。也就是说我们要使用报表不一定要依赖于SQL Server的Reporting Service,而是可以自主生成一些数据源然后通过报表的方式展现出来。如果和rdl比较,rdlc可以看成是一个轻量级的报表。在展现报表的时候我们需要使用到的一个控件叫ReportViewer,这种控件可以展现rdl报表,也可以展现rdlc报表。从其属性可以看出,ReportView.ServerReport是针对rdl报表的,而ReportViewer.LocalReport是针对rdlc报表的。里面设置的参数和内容也不尽相同。

更多资料:https://www.cnblogs.com/xcsn/category/449087.html

3,RDLC基本应用

3.1,添加RDLC文件

添加之后绑定对象或者数据集,这里绑定对象

准备的对象类

 class StudentInfo
    {
        public  int Sid { get; set; }
        public string Sname { get; set; }
        public string Sphone { get; set; }
        public string Sbirthday { get; set; }
        public string Semail { get; set; }
    }

如果没有显示报表数据窗口则在视图菜单下单击Report Data选项,如果该选项未显示,请改变Vs窗口大小,然后再次打开视图菜单进行查看。

3.2, 绑定数据集(示例选择绑定对象)。

 

 添加成功后

3.3, 添加参数字段

3.4,添加文本框

 3.5,添加表格

选择列,右键选择添加列,靠右(该方法添加的列具有选择列同样的格式,例如选择的列设置格式居中,添加的列也将格式居中)

添加自定义参数

3.6,自定义表达式

 添加后台代码

  private void button1_Click(object sender, EventArgs e)
        {
            reportViewer1.LocalReport.DataSources.Clear();
            //加载报表此时rdlc文件位于启动目录下\bin\Debug\RDLC\Report.rdlc
            reportViewer1.LocalReport.ReportPath ="RDLC\\Report.rdlc";            
            list = dal.GetAllStudentInfo(int.Parse(textBox1.Text.Trim()));
            //"MyReportData"为添加的数据源名称
            reportViewer1.LocalReport.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource("MyReportData", list));
            //加载自定义参数
            List<Microsoft.Reporting.WinForms.ReportParameter> paras = new List<Microsoft.Reporting.WinForms.ReportParameter>();
            Microsoft.Reporting.WinForms.ReportParameter rp = new Microsoft.Reporting.WinForms.ReportParameter("MyParam", "一般报表");
            paras.Add(rp);
            reportViewer1.LocalReport.SetParameters(paras);
            reportViewer1.LocalReport.Refresh();
            reportViewer1.RefreshReport();
            
        }

3.7,效果

4,RDLC分组

4.1,准备的对象类

 class StudentInfoExt:StudentInfo
    {
        public byte[] Image { get; set; }
        public string Uri { get; set; }
        public string Class { get; set; }
    }

4.2,构建RDLC布局

选择表格行-右键-添加组-父组

4.3,添加分组信息后

4.4,效果

5, RDLC子报表

5.1,子报表使用的实例类

    class UserClass
    {
        public int Cid { get; set; }
        public string Cname { get; set; }
    }

5.2,创建子报表

5.3,主报表添加子报表

5.4, 注意事项

1,用作子报表的是不带扩展名的子报表文件名

2,参数必须是子报表中已定义的自定义参数,该参数将用于后续子报表事件。

  List<Model.UserClass> userArray = new List<Model.UserClass>();
        private void btnSubReport_Click(object sender, EventArgs e)
        {
            reportViewer1.LocalReport.DataSources.Clear();
            //加载报表
            reportViewer1.LocalReport.ReportPath = @"RDLC\SubReport\MainReport.rdlc";
            //加载报表数据
            list = dal.GetAllObject(int.Parse(textBox1.Text.Trim()));
            var array = list.Select(item => new Model.StudentInfoExt
            {
                Sid = item.Sid,
                Sbirthday = item.Sbirthday,
                Semail = item.Semail,
                Sname = item.Sname,
                Sphone = item.Sname,
                Class = (item.Sid % 5).ToString()
            });
            userArray = useDal.GetAllObject(20);
            reportViewer1.LocalReport.SubreportProcessing += LocalReport_SubreportProcessing;
            //绑定数据
            reportViewer1.LocalReport.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource("MyReportData", array));
            //刷新报表
            reportViewer1.RefreshReport();
        }

        private void LocalReport_SubreportProcessing(object sender, Microsoft.Reporting.WinForms.SubreportProcessingEventArgs e)
        {
            //子报表
            //获取参数的值
            string cid = e.Parameters["classId"].Values[0];
            //获取数据
            var datas = userArray.Where(item => item.Cid.ToString().Equals(cid));
            //绑定数据
            e.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource("SubReportData", datas));
        }

5.5, 效果:

6,RDLC添加图片

6.1,使用嵌入图片

效果:

6.2,使用参数传入外部图片

 private void button1_Click(object sender, EventArgs e)
        {
            reportViewer1.LocalReport.DataSources.Clear();
            //加载报表此时rdlc文件位于启动目录下\bin\Debug\RDLC\Report.rdlc
            reportViewer1.LocalReport.ReportPath = "RDLC\\Report.rdlc";
            list = dal.GetAllObject(int.Parse(textBox1.Text.Trim()));
            
            //加载自定义参数
            List<Microsoft.Reporting.WinForms.ReportParameter> paras = new List<Microsoft.Reporting.WinForms.ReportParameter>();
            Microsoft.Reporting.WinForms.ReportParameter rp = new Microsoft.Reporting.WinForms.ReportParameter("MyParam", "一般报表");
            paras.Add(rp);
            //传递图片位置,路径如果包含特殊字符(例如#等)将无法正常显示图片
            string imgPath = Application.StartupPath + @"\1.jpeg";

            //必须标明协议为file///
             string filePath = "file:///" + imgPath;
           
            //必须指定包含外部图片时可以显示
            reportViewer1.LocalReport.EnableExternalImages = true;
            paras.Add(new Microsoft.Reporting.WinForms.ReportParameter("logo", filePath));
            reportViewer1.LocalReport.SetParameters(paras);
            reportViewer1.LocalReport.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource("MyReportData", list));
            reportViewer1.LocalReport.Refresh();
            reportViewer1.RefreshReport();

        }

 6.3,注意事项

1,图片的路径如果包含特殊字符(例如#等)将无法正常显示图片。
2,必须在图片路径前添加file///开头。如:file:///C:\Users\adminsitor\Desktop\1.jpg
3, 必须显示指明可使用外部图片
   reportViewer1.LocalReport.EnableExternalImages = true;

7,RDLC添加条码

7.1,RDLC控件准备

7.2,代码

 private void btnQRCode_Click(object sender, EventArgs e)
        {
            //包含二维码的报表
            //获取数据
            list = dal.GetAllObject(int.Parse(textBox1.Text.Trim()));
            var array = list.Select(item => new Model.StudentInfoExt
            {
                Sid = item.Sid,
                Sbirthday = item.Sbirthday,
                Semail = item.Semail,
                Sname = item.Sname,
                Sphone = item.Sphone,
                Class = (item.Sid % 5).ToString(),
                Image = GetQRCodeBytes(item.Semail)
            });
            reportViewer1.LocalReport.DataSources.Clear();
            //这种所用的报表
            reportViewer1.LocalReport.ReportPath = "RDLC/MyReport.rdlc";
            //绑定数据
            reportViewer1.LocalReport.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource("MyReportData", array));
            reportViewer1.RefreshReport();
        }
        byte[] GetQRCodeBytes(string txt)
        {
            //生成二维码
            Bitmap map = Common.QRCode.Generate1(txt, 80, 80);
            using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
            {
                map.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                return ms.GetBuffer();
            }
        }

 7.3,效果

8,WPF中添加ReportViewer

<Window x:Class="RDLC.WPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:rv="clr-namespace:Microsoft.Reporting.WinForms;assembly=Microsoft.ReportViewer.WinForms"
        Loaded="Window_Loaded" Closed="Window_Closed" 
        Title="MainWindow" Height="350" Width="525">
    <WindowsFormsHost Name="windowsFormsHost">
        <rv:ReportViewer x:Name="reportView" /> 
    </WindowsFormsHost>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Reporting.WinForms;

namespace RDLC.WPF
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //代码区域

            this.reportView.RefreshReport();
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            this.reportView.LocalReport.Dispose();
            this.reportView.LocalReport.ReleaseSandboxAppDomain();
        }

    }
}

9,RDLC常见问题

9.1,报表出现空白页

在使用RDLC报表时,碰到这种情况:当只有一页数据时,报表确显示两页,第二页除了报表头之外数据为空。然后,当有多页数据时,最后一页为空。

以下的方法可以解决此问题。

方法一:设置报表的属性 ConsumeConteinerWhitespace = True

第一种方法具体操作:

1,选中要修改的报表按F4 ,将下拉框中的【主体】换选中【报表】

2,选择【报表】后就出现了ConsumeConteinerWhitespace 的属性,默认是false,改成True 即可解决空白行的问题  

方法二:在Row Group 中设置 Keep Together = False, 进入Advance Mode, 设置所有Static成员的Keep Together = False

对于一些报表,调整Body的宽度和高度,直到和Report的宽度和高度差不多就行了。操作就是将body的边框拖到和Report平齐。

这么说来,这就是个非常简单的问题,是由于Body的宽度太宽或高度太高引起的。

10,打印与导出

10.1,打印导出帮助类

using System.Collections.Generic;
using System.Data;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Common
{
    /// <summary>
    /// RDLC报表打印,导出帮助类
    /// </summary>
    public class RDLCPrintHelper
    {
        private int m_currentPageIndex;
        private IList<Stream> m_streams;
        /// <summary>
        /// 报表直接打印
        /// </summary>
        /// <param name="reportPath">报表文件路径</param>
        /// <param name="printerName">打印机名称</param>
        /// <param name="dt">DataTable</param>
        /// <param name="sourceName">rdlc的数据集名称</param>
        /// <param name="paraList">参数列表</param>
        public void Print(string reportPath, string printerName, object dt, string sourceName, List<ReportParameter> paraList)
        {
            LocalReport report = new LocalReport();
            report.ReportPath = reportPath;
            report.DataSources.Add(new ReportDataSource(sourceName, dt));
            report.EnableExternalImages = true;
            if (paraList != null && paraList.Count > 0)
            {
                report.SetParameters(paraList);
            }
            Export(report);
            m_currentPageIndex = 0;
            Print(printerName);
        }
        private void Export(LocalReport report)
        {
            string deviceInfo =
                "<DeviceInfo>" +
                " <OutputFormat>EMF</OutputFormat>" +
                "</DeviceInfo>";
            Warning[] warnings;
            m_streams = new List<Stream>();
            try
            {
                report.Render("Image", deviceInfo, CreateStream, out warnings);
            }
            catch (Exception ex)
            {
                Exception innerEx = ex.InnerException;
                while (innerEx != null)
                {
                    string errmessage = innerEx.Message;
                    innerEx = innerEx.InnerException;
                }
            }
            foreach (Stream stream in m_streams)
            {
                stream.Position = 0;
            }
        }
        private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek)
        {
            Stream stream = new FileStream(name + DateTime.Now.Millisecond + "." + fileNameExtension, FileMode.Create);
            m_streams.Add(stream);
            return stream;
        }
        private void Print(string printerName)
        {
            if (m_streams == null || m_streams.Count == 0) return;
            PrintDocument printDoc = new PrintDocument();
            if (printerName.Length > 0)
            {
                printDoc.PrinterSettings.PrinterName = printerName;
            }
            foreach (PaperSize ps in printDoc.PrinterSettings.PaperSizes)
            {
                if (ps.PaperName == "A4")
                {
                    printDoc.PrinterSettings.DefaultPageSettings.PaperSize = ps;
                    printDoc.DefaultPageSettings.PaperSize = ps;
                }
            }
            if (!printDoc.PrinterSettings.IsValid)
            {
                string msg = string.Format("找不到打印机:{0}", printerName);
                //  LogUtil.Log(msg);
                throw new ArgumentException(msg);
            }
            printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
            printDoc.Print();
        }
        private void PrintPage(object sender, PrintPageEventArgs ev)
        {
            Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]);
            ev.Graphics.DrawImage(pageImage, 0, 0, 827, 1169);//像素
            m_currentPageIndex++;
            ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
        }
        // 自动导出excel/pdf/word
        /// <summary>
        /// 导出为excel/pdf/word文件
        /// </summary>
        /// <param name="report">报表文件</param>
        /// <param name="fileName">保存的文件名</param>
        /// <returns></returns>
        public bool Export(LocalReport report, string fileName)
        {
            string outType;
            string ext = System.IO.Path.GetExtension(fileName);
            if (ext.Equals(".xls", StringComparison.InvariantCultureIgnoreCase) || ext.Equals(".xlsx", StringComparison.InvariantCultureIgnoreCase))
            {
                outType = "Excel";
            }
            else if (ext.Equals(".doc", StringComparison.InvariantCultureIgnoreCase))
            {
                outType = "Word";
            }
            else if (ext.Equals(".pdf", StringComparison.InvariantCultureIgnoreCase))
            {
                outType = "PDF";
            }
            else
            {
                throw new ArgumentException("不支持导出为该类型文件!");
            }
            try
            {
                Warning[] warnings;
                string[] streamids;
                string mimeType;
                string encoding;
                string extension;
                byte[] bytes = report.Render(
                        outType, null, out mimeType, out encoding, out extension,
                        out streamids, out warnings);
                File.WriteAllBytes(fileName, bytes);
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    }
}

10.2,打印

 private void btnPrint_Click(object sender, EventArgs e)
        {
            if (reportViewer1.LocalReport.DataSources.Count == 0)
            {
                MessageBox.Show("无可供打印的内容");
                return;
            }
            //当前报表路径
            string reportPath = reportViewer1.LocalReport.ReportPath;
            var array = reportViewer1.LocalReport.DataSources[0].Value;
            var arrayName = reportViewer1.LocalReport.DataSources[0].Name;
            var paras = reportViewer1.LocalReport.GetParameters().Select(item => new Microsoft.Reporting.WinForms.ReportParameter(item.Name, item.Values[0])).ToList();
            using (PrintDialog pd = new PrintDialog())
            {
                if (pd.ShowDialog() == DialogResult.OK)
                {
                    string printerName = pd.PrinterSettings.PrinterName;
                    Common.RDLCPrintHelper printer = new Common.RDLCPrintHelper();
                    printer.Print(reportPath, printerName, array, arrayName, paras);
                }
            }
        }

10.3,打印效果

10.4,导出

 private void btnExport_Click(object sender, EventArgs e)
        {
            if (reportViewer1.LocalReport.DataSources.Count == 0)
            {
                MessageBox.Show("无可供打印的内容");
                return;
            }
            //当前报表路径
            var report = reportViewer1.LocalReport;
            using (SaveFileDialog pd = new SaveFileDialog())
            {
                pd.Filter = "Excel文件|*.xls|Excel文件|*.xlsx|word文件|*.doc|Pdf文件|*.pdf";
                if (pd.ShowDialog() == DialogResult.OK)
                {
                    string fileName = pd.FileName;
                    Common.RDLCPrintHelper printer = new Common.RDLCPrintHelper();
                    printer.Export(report, fileName);
                }
            }

10.5,导出效果

11,Demo链接

https://download.csdn.net/download/lingxiao16888/89580401

  • 8
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值