ASP.net的PDF打印(水晶报表)[摘]

如何部署ASP.NET Crystal Report
(1) CRRedist2008_x86.msi 報表套件
C:/Program Files/Microsoft SDKs/Windows/v6.0A/Bootstrapper/Packages/CrystalReports10_5

(2) CRREdist2008_x86_chs.msi 中文語言套件
C:/Program Files/Microsoft SDKs/Windows/v6.0A/Bootstrapper/Packages/CrystalReports10_5/zh-CHS

ASP.net的PDF打印(水晶报表)(表里含有多行数据,而且分页,带图片)
     这个需求其实很普遍,首先打印用PDF的确要比excel要方便的多,至少格式不需要用户再处理了。但是pdf的打印如果用一种画图的方法,就太太麻烦了。最后尝试了用水晶报表转,的确很方便很方便,不应该说太简单了。所以我把做的最复杂的报表给做个小总结。
     首先数据集:在App_Code里(适合net2005)新建一个数据集*.xcd(其实在哪建都可以),在服务器资源管理器里面,拉下来一个表到数据集里,如果你要改变字段或添加字段都可以,这样一个页面你要显示的所有的数据都在这个数据集里面。如果你要多行多列,而且分好页面,就把所有的字段都贴上去吧,水晶报表是有可以多行分组显示的,但为了页面好看,只能这样了。名字可以按数组来,比如name1,name2等等。
     然后水晶报表:做一个rpt的文件,在字段管理器里点数据库字段,在数据库专家里选择ADO.net数据集下面的一个数据集。可以把刚才的数据集拉过来。把每个字段摆在何时的地方。表格我是右键,插入,OLE对象,由文件创建,我在word里面将这个表事先画好了。这样摆在Section3(详细资料里),然后调节里面的字段正好在表格下面。把Section2里面的删除掉,因为不需要上面有个头了。
    页面转成PDF方法:加一个button,在事件里加入如下的代码:
                ReportDocument rptdoc = new ReportDocument();
                rptdoc.Load(MapPath("rpt/YeWuChuLi.rpt"));//水晶报表的相对地址
                string filename = T_ProcessID.Text + ".pdf";//生成PDF的文件名
                string Fname = MapPath("rpt/" + filename);//生成PDF地址
                rptdoc.SetDataSource(dtable);//得到数据源,这个table会在sql语句里把所有的数据都读出来。
                DiskFileDestinationOptions crDiskFileDestinationOptions = new DiskFileDestinationOptions();
                crDiskFileDestinationOptions.DiskFileName = Fname;
                ExportOptions crExportOptions = rptdoc.ExportOptions;
                
                crExportOptions.ExportDestinationOptions = crDiskFileDestinationOptions;
                crExportOptions.ExportDestinationType = ExportDestinationType.DiskFile;
                crExportOptions.ExportFormatType = ExportFormatType.PortableDocFormat;
                rptdoc.Export();//上面代码是将水晶报表转化成PDF
                Response.ClearContent();//下面的代码是弹出这个转换好的pdf文件
                Response.ClearHeaders();
                Response.ContentType = "application/pdf";
                Response.WriteFile(@"rpt/" + filename);
                Response.Redirect(@"rpt/" + filename);
                Response.Flush();
                Response.Close();
 
      注意要加引用在最上面
      using CrystalDecisions.CrystalReports.Engine;
      using CrystalDecisions.Shared;
 
      那么这个数据源看怎么做了,当然,最简单的就是一个查询语句付给这个DataTable里就完成了。
      当表里还有表的时候,就要首先把所有的表都查询出来,放在不同的DataTable里,例如我这个表里,首先有一个总体的介绍设备,一个表的数据,管道是一个表里要显示5个管道信息,阀门一个表里有3个管道的信息等等,整压器里面要显示2个整压器,而如果管道多于5个要第二个表里显示。这样打印的时候,就都看到了。
      因为水晶报表是按表的列来填入数据的,无法把行读出来,所以这里面有一个关于把行转化成列的sql语句。比较有意思。
      举例 一个数据库的表
          Name   sex    birthday
            aa     bb      cc
            dd     ee      ff
            gg     hh      ii
            jj       kk      ll
            mm    nn      oo
  要变成:
       Name1  sex1   birthday1 Name2  sex2 birthday2 Name3 sex3 birthday3
          aa     bb        cc         dd       ee     ff           gg      hh   ii
          jj      kk         ll            mm     nn     oo          Null    Null  Null
SQL 语句       
select (id-1)/3,
Name1 =  max(case when id%3 = 1 then Name else null end),
Name1 =  max (case when id%3 = 2 then Name else null end),
Name1 =  max (case when id%3 = 0 then Name else null end),
Sex1 =  max(case when id%3 = 1 then Type else null end),
Sex2 =  max (case when id%3 = 2 then Type else null end),
Sex3 =  max (case when id%3 = 0 then Type else null end),
Birthday1 =  max(case when id%3 = 1 then Quantity else null end),
Birthday2 =  max (case when id%3 = 2 then Quantity else null end),
Birthday3 =  max (case when id%3 = 0 then Quantity else null end),
from (SELECT row_number() over(order by dbo.表名.Name) as id,表名.* FROM dbo.表名 where ID='" + processid + "') tt group by (id-1)/3";
 
然后解决分页的问题
     这三个表首先要看谁的表的行数多,就按照行数多的那个作为循环,将所有的数据都拼在一个表里面
例如:      
                DataTable dtable = new DataTable;
                //#region 用气设备
                DataTable gasdevicedt = getgasdevicebyprocessid(T_ProcessID.Text);
                //#region 报警设备
                DataTable Alertdevicedt = GetAlertdeviceByProcessID(T_ProcessID.Text);
                //#region 计量表
                DataTable meadevicedt = getmeadevice(T_ProcessID.Text);
                //#region 调压器
                DataTable boosterdt = getboosterbyprocessid(T_ProcessID.Text);
               
                int k = 最多行的表.Rows.Count;
                
                for (int i = 0; i <= k; i++)
                {
                    DataRow row = dtable.NewRow();
                    row["ProjectName"] = T_ProjectName.Text;
                    row["NodeEndTime"] = D_NodeEndTime.Text;
 
                    row["NameA"] = gasdevicedt.Rows[i]["NameA"].ToString();
                    row["NameB"] = gasdevicedt.Rows[i]["NameB"].ToString();
                    row["NameC"] = gasdevicedt.Rows[i]["NameC"].ToString();
                    row["NameD"] = gasdevicedt.Rows[i]["NameD"].ToString();
                    row["NameE"] = gasdevicedt.Rows[i]["NameE"].ToString();

                    
                   row["AlertDeNameA"] = Alertdevicedt.Rows[i]["AlertDeNameA"].ToString();
                    row["AlertDeNameB"] = Alertdevicedt.Rows[i]["AlertDeNameB"].ToString();
                    row["AlertDeNameC"] = Alertdevicedt.Rows[i]["AlertDeNameC"].ToString();
 
                    row["PipNameA"] = meadevicedt.Rows[i]["PipNameA"].ToString();
                    row["PipNameB"] = meadevicedt.Rows[i]["PipNameA"].ToString();
                    dtable.Rows.Add(row);
                }
                dtable.AcceptChanges();
这个Table的数据源就好了
这样就可以显示出来要的PDF了
 
水晶报表显示图片:
       ReportDocument rptdoc = new ReportDocument();
        rptdoc.Load(MapPath("PipelineHandover.rpt"));
        HandOverSet ds = _HandOver1.GetSingleHandOverByPHID(Convert.ToInt32(Request.QueryString["PHID"]));
        if (ds.HandOver.Rows[0]["PipelinePic"].ToString() == "")
            ds.HandOver.Rows[0]["PipelinePic"] = "nopic.gif";
        FileStream fs = new FileStream(MapPath("../images/pics/" + ds.HandOver.Rows[0]["PipelinePic"].ToString()), FileMode.Open); // 创建文件流
        BinaryReader br = new BinaryReader(fs);
        ds.HandOver.Rows[0]["img"] = br.ReadBytes((int)br.BaseStream.Length);
        rptdoc.SetDataSource(ds);
        crv.ReportSource = rptdoc; 
 
打印的时候只要那个ds出来了,就都出来了,下面的字段是不弹出来pdf页面,直接就在打印机里出来了。
        System.Drawing.Printing.PrintDocument printDocument = new System.Drawing.Printing.PrintDocument();
        rptdoc.PrintOptions.PrinterName = printDocument.PrinterSettings.PrinterName;
        rptdoc.PrintToPrinter(1, true, 1, 1);
 
以上的方法,在ASP.net里应该足够用了吧,当然有更简单的方法也好,我也用过一个很牛的控件,感觉是“画”一个pdf很灵活,但过于复杂。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
asp.net生成PDF详解 asp.net生成PDF PDF详解 用C#制作PDF文件全攻略 丽水市汽车运输集团有限公司信息中心 苟安廷 目 录 前 言 3 第一部分 iText的简单应用 4 第一章 创建一个Document 4 第一步 创建一个Document实例: 5 第二步 创建Writer实例 6 第三步 打开Document 6 第四步 添加内容 10 第五步,关闭 document 11 第二章 块、短句和段落 11 块 11 短句 12 段落 12 字体的延续 13 第三章 锚点、列表和注释 14 锚点 14 列表 14 注释 15 第四章 页眉页脚、章节、区域和绘图对象 16 页眉页脚 16 章节和区域 17 图形 17 第五章 表格 18 一些简单的表格 18 一些表格参数 18 大表格 20 内存管理 20 嵌套表格 21 表格偏移 21 表格的绝对位置 21 第六章 图片 21 Image对象 21 图片的位置 22 缩放和旋转图片 23 原始图片数据 23 System.Drawing.Bitmap 23 TIFF和CCITT 24 图片和其他对象 24 第二部分 其他文档格式 25 第七章 XML和 (X)HTML 25 第八章 RTF文件 25 RTF包 25 创建一个RTF文档 25 不支持的特性 26 RTF中扩展的页眉和页脚 26 第三部分 iText的高级应用 27 第九章 字体 27 TrueType字体应用 27 TruType字体集合的应用 28 第十章 图象和文本的绝对位置 28 pdfContentByte 28 简单图形 29 文本 29 模板(Form xObjects) 30 分栏 31 PdfTable 32 颜色(SpotColors)和图案(Patterns) 33 第十一章 本地和异地转向、目标和概要 33 本地转向 33 异地转向 33 第十二章 页面和表格事件 34
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值