C#水晶报表应用

目录

1,前期准备:

1.1  前言:

1.2  下载地址:

1.3  使用注意事项:

2,Crystal Report制作使用:

2.1  Crystal Report for .NET 的功能

2.2  Crystal Report总体结构

2.3  报表数据访问执行模式

2.4  报表类型

2.5  Crystal Report 设计器的布局

2.6  Crystal Report 的具体实例

2.6.1 添加数据库字段:

2.6.2 Windows应用程序中的Crystal Report开发

2.6.3 参数的传递:

3,Crystal Report添加条形码,二维码。

4,最终效果:

5,Demo链接:


1,前期准备

1.1,前言:

        Visual Studio2015开发环境中默认没有水晶报表,开发人员在使用时,首先需要到SAP官网下载Crystal Reports for Visual Studio2015安装文件进行安装,然后才可以在Visual Studio2015开发环境中创建水晶报表。

1.2,下载地址:

水晶报表历史版本网页地址:

How to download and Install Crystal Report Runtime and Crystal Report for Visual Studio | Parth Patel - a Web Developer

 Crystal Reports for Visual Studio2015插件下载链接:

地址1:

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

地址2:

https://origin.softwaredownloads.sap.com/public/file/0020000000672512019

(安装时请退出360等杀毒软件)

1.3,使用注意事项:

  • 桌面进行切换时,水晶报表创建向导自动隐藏,使用Ctrl+shift或者ctrl+tab可使其显示。

2,Crystal Report制作使用

2.1  Crystal Report for .NET 的功能

         通过将Crystal Report 的报表处理功能整和到自己的数据库应用程序中,Windows应用程序和Web开发人员可以节省开发时间来满足用户的需求。Crystal Report 支持大多数流行的开发语言,可以方便的在任何应用程序中添加报表。

 具体来说,Crystal Report的功能有以下几点:

 1、全面的数据库访问:

          Crystal Report 中包括了超过35中数据源驱动,可以访问一种XML、企业和关系型数据库。

2、广泛的设计格式与设计:

          通过Crystal Report,用户可以将数据库转换为高度交互性内容。可以从100多中格式选项中进行选择、包括参数、映射、交叉表和超级链接、用以强化报表的冲击力。

3、强大的图表设计功能:

          Crystal Report 可以在报表中包含多彩的、易读的图表(提供了非常丰富的报表类型,如:条形图、折线图、面积图、饼图、甘特图、股票图等)。

4、灵活的应用集成技术:

  Crystal Report 带有灵活的Java、COM和.NET SDK,以及可内嵌的Report Application Server,可将报表与企业Web应用紧密地集成在一起。通过使用Crystal Report 的"零"客户端浏览器控制,能够为最终端拥护提供丰富的报表交互、创建和修改功能。

5、强大的报表导出:

  Crystal Reprort 的所有的报表都可以导出多种不同的格式:包括XML、PDF、HTML、和Microsoft Excel。

2.2  Crystal Report总体结构

1、Crystal Report Engine (CREngine.dll)

        将数据与报表文件合并、将数据输出为不同的格式,将Crystal Report转为传到.aspx页中的简洁明了的HTML.

2、Crystal Report Designer (CRDesigner.dll)

        使用Crystal Report Designer可以制作报表,可以设计标题、插入数据、公式、表格、次级报告等。

3、The .rpt Report file

        将一份报表应用到你的应用程序中的第一步是使用Crystal Report Designer创建报表。但是如果已经有了一些现成的样本,你现在就可以用它。

4、The Data Source

        .rpt文件获取数据的方式取决于你所选用的方法。你可以选择制作Crystal Report以获取数据而无须手工写任何代码,也可以选择绑定你的dataset并将其传入报表文件。

5、Crystal Report Viewer

        Crystal Report Viewer是一个能够插入页中的容器(.net中习惯称为控件)。

2.3   报表数据访问执行模式

1、拉模型 Pull Model

        在拉模型中,驱动程序将连接到数据库并根据需要将数据“拉”进来。使用这种模型时,与数据库的连接和为了获取数据而执行的 SQL 命令都同时由 Crystal Reports 本身处理,不需要开发人员编写代码。如果在运行时无须编写任何特殊代码,则使用拉模型。

2、推模型 Push Model

        相反,推模型需要开发人员编写代码以连接到数据库,执行 SQL 命令以创建与报表中的字段匹配的记录集或数据集,并且将该对象传递给报表。该方法使您可以将连接共享置入应用程序中,并在 Crystal Reports 收到数据之前先将数据筛选出来。

2.4 报表类型

        Crystal Report Designer可以是独立于解决方案的报表外,也可是装载包含于解决方案方案之中的报表。

1、Strongly-typed Report :

        当在方案中加入一个报表时,该报表就成为一个Strongly-typed Report。在这种情况下,你可以直接创建报表实例(可以减少若干代码),可以将其隐藏。当然你可以点击Solution Explorer中的”show all files”来显示它。

2、Un-Typed Report :

        不包含在方案中的报表即Un-Typed Report。在这种情况下,必须创建一个Crystal Report Engine的''Report Document''对象并将报表手工装载进去。

2.5   Crystal Report 设计器的布局

        首先,在Visual Studio2015的一个工程中添加一个向 Windows 或 Web 窗体发布数据的 Crystal 报表文件:

        添加成功之后,打开该报表:

 

从上图可以看到设计器的完整布局。

1、字段资源管理器:

         列出该报表所有的字段,如:使用的数据库字段、参数字段、公式字段等。可以在此修改和删除字段对象。

2、主报表窗口:

         用来在报表窗口中显示主报表。对于包含子报表的报表,有主报表窗口和对每个的深化(通过双击)的子报表有一个

         子报表窗口。可以通过右击报表窗口的任何空白位置来启动报表快捷菜单。

3、水晶报表主工具栏:

         包括记录选择、分类和文本对象格式化图标。可以对整个工具栏移动或改变大小。

4、水晶报表插入工具栏:

         可以插入汇总字段、组、子报表、图表和图片的图标。也可以在Crystal Report工具栏中单击鼠标来选择"插入"。

2.6  Crystal Report 的具体实例

2.6.1 添加数据库字段:

 

方式1:链接SqlServer数据库:

 链接成功后在我的链接中选择需要的数据表并导入:

导入成功后自动添加数据库字段:

将数据库字段拖入需要使用的位置即可。

方式2:通过数据集导入字段:

新建数据集文件:

添加需要的字段

将数据集中的DataTable导入

2.6.2 Windows应用程序中的Crystal Report开发
  •     拉模型 pull model 的demo

         通过连接数据库直接拉取数据库数据

  private void Form1_Load(object sender, EventArgs e)
        {
            //查询语法
            string sqlcmd = " {tb_StudentInfo.ID} like '*'";
            ReportDocument doc = GetDocument("StudentInfoCrystalReport.rpt", sqlcmd);
            crystalReportViewer1.ReportSource = doc;

        }
 ReportDocument GetDocument(string fileName,string sqlcmd)
        {
            ReportDocument document = new ReportDocument();
            string curFilePath = System.IO.Path.GetFullPath("../../" + fileName);
            document.Load(curFilePath);
            document.RecordSelectionFormula = sqlcmd;//这里是为了完成指定查询,如果全部拉取数据则不需要此语句
            return document;
        }
 private void button1_Click(object sender, EventArgs e)
        {
            string sqlcmd;
            if (string.IsNullOrEmpty(textBox1.Text))
            {
                 sqlcmd = " {tb_StudentInfo.ID} like '*'";
            }
            else
            {
                sqlcmd = "{tb_StudentInfo.ID} like '" + textBox1.Text+ "'";
            }
            
            ReportDocument doc = GetDocument("StudentInfoCrystalReport.rpt", sqlcmd);
            crystalReportViewer1.ReportSource = doc;
        }

2,推模型 push model的demo

 public PrintFrm(DataTable dt,PrinterSettings printer,PageSettings page)
        {
            InitializeComponent();
           // report1.PrintOptions.CopyFrom(printer, page);//进行该设置后页面设置就异常了,所以不能进行这样的设置
            report1.SetDataSource(dt);
            this.Printer = printer;
            Page = page;
            PrintPreviewDialog ppd = new PrintPreviewDialog();
            crystalReportViewer1.ReportSource = report1;
        }

注意事项:

使用推模式时需要在App.Config文件中进行如下设置:

在<startup>中添加一句 useLegacyV2RuntimeActivationPolicy="true"”,完整代码如下:

 <startup useLegacyV2RuntimeActivationPolicy="true"> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>

否则将报以下异常:

“未能加载文件或程序集“file:///C:\Program Files (x86)\SAP BusinessObjects\Crystal Reports for .NET Framework”。

2.6.3 参数的传递:

        传递参数的时候首先要在report.rpt设计文件里新建一些参数如下所示:

传递方法1:

 CrystalReport1 cr = new CrystalReport1();
 crystalReportViewer1.ReportSource = cr;
 ParameterFields paramFields = new ParameterFields();
ParameterField paramField = new ParameterField();
 ParameterDiscreteValue discreteVal = new ParameterDiscreteValue();

paramField.ParameterFieldName = "RukuDate";
discreteVal.Value = "Rick just testing parameter";
paramField.CurrentValues.Add(discreteVal);
paramFields.Add(paramField);
 crystalReportViewer1.ParameterFieldInfo = paramFields;

传递方法2:

 CrystalReport1 report1 = new CrystalReport1();
 report1.SetParameterValue("RukuDate", "2099/23");
crystalReportViewer1.ReportSource = report1;

3, Crystal Report添加条形码,二维码。

类型为byte[]或者sbyte[]的字段,拖拽进Crystal Report中将以图片格式显示。

所以只需要将生成的二维码,条形码Bitmap转换为Byte[]保存至对应的字段即可。

 private void btnPrint_Click(object sender, EventArgs e)
        {
            if (dataGridView1.SelectedRows.Count <= 0)
            {
                MessageBox.Show("请先选择需要打印的数据","", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            DataTable dt = dataGridView1.DataSource as DataTable;
            DataTable seltable = dt.Clone();
            DataTable insertTable = dt.Clone();
           // seltable.Clear();
            foreach (DataGridViewRow row in dataGridView1.SelectedRows)
            {
                int index = row.Index;
                DataRow r = dt.Rows[index];
                //获取条形码
                string id = r["Id"].ToString();
                string productnum = r["ProductNum"].ToString();
              Bitmap barcode=  BarMethHepler.Generate2(id, 200, 50, true);
                Bitmap qCode = BarMethHepler.Generate1(productnum, 200, 200);
                byte[] barBytes = GetBytes(barcode);
                byte[] qcodeBytes = GetBytes(qCode);
                seltable.ImportRow(r);
                insertTable.ImportRow(r);
                //只有保存为byte[]或者sbyte[]格式该字段在水晶报表中才能以图片的样式显示
                seltable.Rows[seltable.Rows.Count - 1].SetField<byte[]>("BarCode", barBytes);
                seltable.Rows[seltable.Rows.Count - 1].SetField("QCode", qcodeBytes);
            }
            //将数据提交到数据库中
            using (SqlConnection con=new SqlConnection(constr))
            {
                using (SqlCommand com=new SqlCommand( ))
                {
                    con.Open();
                    com.Connection = con;
                    //批量复制到数据库中
                    using (SqlBulkCopy bulk = new SqlBulkCopy(con))
                    {
                        bulk.DestinationTableName = "EntryOrder";
                        bulk.WriteToServer(insertTable);
                    }
                }
            }
            insertTable.Dispose();
            PrintFrm frm = new PrintFrm(seltable, printer, page);
            frm.ShowDialog();
        }
        /// <summary>
        /// 将Bitmap转换为byte[]
        /// </summary>
        /// <param name="map"></param>
        /// <returns></returns>
        byte[] GetBytes(Bitmap map)
        {
            using (System.IO.MemoryStream ms=new System.IO.MemoryStream())
            {
                map.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
              return  ms.GetBuffer();
            }
        }

通过ZXing.Net来完成二维码,条形码生成。

        在项目中,点击项目名称右键-->管理NuGet程序包,打开NuGet包管理器窗口,搜索ZXing.Net下载。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using ZXing;
using ZXing.Common;
using ZXing.QrCode;
using ZXing.QrCode.Internal;
using System.Drawing.Imaging;

namespace WindowsFormsApp1
{
    public class BarMethHepler
    {
        /// <summary>
        /// 生成二维码
        /// </summary>
        /// <param name="text">内容</param>
        /// <param name="width">宽度</param>
        /// <param name="height">高度</param>
        /// <returns></returns>
        public static Bitmap Generate1(string text, int width, int height)
        {
            BarcodeWriter writer = new BarcodeWriter();
            writer.Format = BarcodeFormat.QR_CODE;
            QrCodeEncodingOptions options = new QrCodeEncodingOptions()
            {
                DisableECI = true,//设置内容编码
                CharacterSet = "UTF-8",  //设置二维码的宽度和高度
                Width = width,
                Height = height,
                Margin = 1//设置二维码的边距,单位不是固定像素
            };

            writer.Options = options;
            Bitmap map = writer.Write(text);
            return map;
        }

        /// <summary>
        /// 生成一维条形码
        /// </summary>
        /// <param name="text">内容</param>
        /// <param name="width">宽度</param>
        /// <param name="height">高度</param>
        /// <returns></returns>
        public static Bitmap Generate2(string text, int width, int height)
        {
            BarcodeWriter writer = new BarcodeWriter();
            //使用ITF 格式,不能被现在常用的支付宝、微信扫出来
            //如果想生成可识别的可以使用 CODE_128 格式
            //writer.Format = BarcodeFormat.ITF;
            writer.Format = BarcodeFormat.CODE_39;
            EncodingOptions options = new EncodingOptions()
            {
                Width = width,
                Height = height,
                Margin = 2
            };
            writer.Options = options;
            Bitmap map = writer.Write(text);
            return map;
        }

        /// <summary>
        /// 生成带Logo的二维码
        /// </summary>
        /// <param name="text">内容</param>
        /// <param name="width">宽度</param>
        /// <param name="height">高度</param>
        public static Bitmap Generate3(string text, int width, int height)
        {
            //Logo 图片
            string logoPath = System.AppDomain.CurrentDomain.BaseDirectory + @"\img\logo.png";
            Bitmap logo = new Bitmap(logoPath);
            //构造二维码写码器
            MultiFormatWriter writer = new MultiFormatWriter();
            Dictionary<EncodeHintType, object> hint = new Dictionary<EncodeHintType, object>();
            hint.Add(EncodeHintType.CHARACTER_SET, "UTF-8");
            hint.Add(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            //hint.Add(EncodeHintType.MARGIN, 2);//旧版本不起作用,需要手动去除白边

            //生成二维码
            BitMatrix bm = writer.encode(text, BarcodeFormat.QR_CODE, width + 30, height + 30, hint);
            bm = deleteWhite(bm);
            BarcodeWriter barcodeWriter = new BarcodeWriter();
            Bitmap map = barcodeWriter.Write(bm);

            //获取二维码实际尺寸(去掉二维码两边空白后的实际尺寸)
            int[] rectangle = bm.getEnclosingRectangle();

            //计算插入图片的大小和位置
            int middleW = Math.Min((int)(rectangle[2] / 3), logo.Width);
            int middleH = Math.Min((int)(rectangle[3] / 3), logo.Height);
            int middleL = (map.Width - middleW) / 2;
            int middleT = (map.Height - middleH) / 2;

            Bitmap bmpimg = new Bitmap(map.Width, map.Height, PixelFormat.Format32bppArgb);
            using (Graphics g = Graphics.FromImage(bmpimg))
            {
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                g.DrawImage(map, 0, 0, width, height);
                //白底将二维码插入图片
                g.FillRectangle(Brushes.White, middleL, middleT, middleW, middleH);
                g.DrawImage(logo, middleL, middleT, middleW, middleH);
            }
            return bmpimg;
        }

        /// <summary>
        /// 删除默认对应的空白
        /// </summary>
        /// <param name="matrix"></param>
        /// <returns></returns>
        private static BitMatrix deleteWhite(BitMatrix matrix)
        {
            int[] rec = matrix.getEnclosingRectangle();
            int resWidth = rec[2] + 1;
            int resHeight = rec[3] + 1;

            BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
            resMatrix.clear();
            for (int i = 0; i < resWidth; i++)
            {
                for (int j = 0; j < resHeight; j++)
                {
                    if (matrix[i + rec[0], j + rec[1]])
                        resMatrix[i, j] = true;
                }
            }
            return resMatrix;
        }
    }
}

4,最终效果

打印多张:

 5,Demo链接

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值