大家都知道,C#打印图片可以直接调用PrintDocument控件的PrintPage事件,通过画刷对image对象直接进行绘制。但是这种方法存在局限,例如如果打印的图片需要按纸张大小进行缩放的话,那么图片显示比例和图片显示位置等都需要动态计算,如果还要添加水印或者其他的图片操作,基本上要添加很多额外的逻辑,并且效率不高,严重限制了程序的性能。如果要在图片上绘制个性化的文本或者定制其他内容,则基本没办法实现,严重限制了程序的可扩展性和可维护性。

常规写法如下所示:

1 //例如这是PrintDocument的PrintPage事件

2 Graphics g = null;3 g =e.Graphics;4 g.SmoothingMode = SmoothingMode.HighQuality; //设置画刷高质量5

6 //绘制已经处理过的Bitmap对象(假设它已经从服务器或者某个地方下载下来并且已经算好了在纸张上指定的打印位置)7 //此种写法在激光高速打印机中存在明显缺陷,因此不建议大业务量的程序使用

8 g.DrawImage(bmp, locationX, locationY, bmp.Width, bmp.Height);

笔者使用某款佳能的普通喷墨打印机速度不是很理想,在实际业务需求量很大的情况下,采用了利盟牌某款高速激光打印机,但是调用PrintDocument控件对图像对象进行绘制时,打印机处于等待状态,虽然打印任务已经发送过去,但是由于图片尚未绘制完成,所以打印机停滞不出纸张,效率还不如普通喷墨打印机,可以说这是这种方法的局限性导致的,因此在大业务量的情况下,使用这种方法进行打印明显并不合适。

所以我就开始研究使用模板进行打印的方法。

本文所探讨的是使用FastReport第三方控件对图片打印进行个性化的模板定制。首先在项目中引入此控件的相关dll。

第一步:添加FastReport模板打印相关类和方法:

在打印类中,我们定义一个打印模板的方法,关键代码如下:

1 ///

2 ///打印报表3 ///

4 /// fastreport参数(key)及值(value)

5 /// 数据集

6 /// 模板名称

7 /// 模板类型

9 /// 是否选择打印机bool

10 public void Print(NoSortHashTable ht, DataSet ds, string functionCode, string modelCode, boolselectPrint)11 {12 //假设模板数据存在数据库中,此时先获取模板数据

13 Model.FR_Template m = this.GetFastReportModel(functionCode, modelCode, orgid);14

15 if (m == null)16 {17 throw new Exception("调用的模版不能为空!");18 }19 //设置模版数据

20 this.TempContent = string.IsNullOrEmpty(this.TempContent) ? m.TEMPCONTENT : this.TempContent;21

22 //TempInf为空时报错

23 if (!string.IsNullOrEmpty(this.TempContent))24 {25 //导入模版数据

26 this.report.LoadFromString(this.TempContent);27 }

29

31 if (FRds != null)32 {33 //注册报表数据

34 this.report.RegisterData(ds, FRds.DataSetName);35

36 //加载可用的数据源

37 foreach (DataTable dt inFRds.Tables)38 {39 this.report.GetDataSource(dt.TableName).Enabled = true;40 }41 }44

45 //动态添加fastreport参数

46 foreach (DictionaryEntry de inht)47 {48 string ParamName =de.Key.ToString();49 //获取参数

50 FastReport.Data.Parameter param = this.report.Parameters.FindByName(ParamName);51 if (param != null)52 {53 param.Value =de.Value;54 }55 }56

57 this.report.PrintSettings.ShowDialog =selectPrint;58

59 string printerName = ConfigurationManager.AppSettings[functionCode] == null ? "": ConfigurationManager.AppSettings[functionCode].ToString();60 if (!string.IsNullOrEmpty(printerName))61 {62 this.report.PrintSettings.Printer =printerName;63 }64 //运行报表打印

65 this.report.Print();66 //释放使用的资源

67 this.report.Dispose();68 }

在设置打印模板的界面中,打开FastReport设计器的代码如下:

SaveFRTemplateFrm saveFRTfrm = newSaveFRTemplateFrm(VoidNameEnum.Update, dgvr);

saveFRTfrm.Owner= this;

saveFRTfrm.StartPosition=FormStartPosition.CenterScreen;if (saveFRTfrm.ShowDialog() ==DialogResult.OK)

{//保存设计好的打印模板

}

第二步:传递参数和数据,调用打印

模板设计好之后,在打印的界面中需调用刚刚封装的打印方法对模板进行传参打印。一下为打印方法:

///

///从打印模板打印数据///

private voidPrintPaperByTemplet( DataTable dsRSPrint)

{

NoSortHashTable nht= newNoSortHashTable();

SavePrintTempFile();//添加打印参数

nht.Add("打印页码", (pagenum == 1 ? "" : Currentpagenum + "/" +pagenum));

nht.Add("打印时间", AppData.SysDate.ToString("yyyy-MM-dd hh:mm:ss"));

DataSet ds= new DataSet("DataPrint");

ds.Tables.Add(dsRSPrint.Copy());try{

Print(nht, ds, functionCode,"A4", false);

Application.DoEvents();

}catch(Exception ex)

{//errorMsg += "图片数据出现问题,无法输出到打印模板!\n";

}

}

那么关键的地方是,打印的图片数据如传入到FastReport模板中呢?有如下两种方法供你参考:

方法一:

在FastReport模板中添加图片对象的控件,指定本地或网络路径(注意必须是固定链接)的图片名称,每次打印之前先把需要打印的图片存放到这个路径并命名成指定的文件名。

///

///保存打印模板用到的临时缓存文件///

private voidSavePrintTempFile()

{bool isSaveFlag = true;do{try{if (File.Exists("某个文件.jpg"))

{

File.Delete("某个文件.jpg");

Thread.Sleep(100); //休眠 避免保存文件时图片尚未删除

}img.Save(printTempFile);

using (Bitmap bmpPrint = newBitmap(img))

{//对图片进行一些处理,例如压缩大小,调整对比度等等

}

}catch(Exception ex)

{

isSaveFlag= false;

}

}while (!isSaveFlag);//将文件设置为隐藏

FileInfo fi = newFileInfo(printTempFile);

File.SetAttributes(printTempFile, fi.Attributes|FileAttributes.Hidden);

}

当然如果你想在图片上添加水印,在模板中也可以实现,例如下图片所示,在图片层上面指定水印图片,注意必须是PNG格式的矢量图形,否则会盖住原始的图片内容。

水印的添加设置方法同上面的图片添加,在模板中设置指定路径即可。

方法二:

将图片对象通过数据列或参数形式传递到模板中,注意需要将image对象格式转化为64位字符串。

Byte[] streamByte =ImageBytesHelper.GetByteImage(img); //先将image对象转化为二进制字节(过程略)

dataRow["图片数据"] = Convert.ToBase64String(streamByte); //再将字节转换为64为字符

在模板中,你需要添加部分事件代码解析传过来的图片数据。

//在模板的DataPrintBefore事件中写下如下代码

string imgStr = (string)Report.GetColumnValue("ds.图片数据");byte[] imgData=Convert.FromBase64String(imgStr);

MemoryStream ms= newMemoryStream(imgData);

Image img=System.Drawing.Image.FromStream(ms);//PictureObject pic=Report.FindObject('Picture1') as PictureObject;

Picture1.Image=img;

此时image对象的64位字符即可以解析为图片显示在模板上了。

这两种方法是我研究了一段时间的结果,第一种直接存文件每次读取简单有效,并不影响打印效率。第二种方法传参设置,比第一种方法稍微复杂,但不需要读盘,稳定型更好。

注意:本文为Healer007原创,署名为小萝卜,本人站点:itoku.cn,欢迎交流学习,转载文章请注明出处。

fastreport打印ftp图片_C#:使用FastReport打印带图片传参模板的实现方法相关推荐

  1. html图片postmultipart,sendmail-MIMEText-MIMEImage-MIMEMultipart.py——发送带图片的HTML格式报表...

    #!/usr/bin/env python #coding:utf-8 # 通过MIMEText类来实现HTML格式的邮件,当要求包含图片数据的邮件内容时,需要引用MIMEImage类 # 若邮件主体 ...

  2. android论文引用图片,Android自动解析html带图片,实现图文混排

    在android中,如何将html代码转换为text,然后显示在textview中呢,有一个简单直接的方法: Java textView.setText(Html.fromHtml(content)) ...

  3. html圆形图片怎么加白边框,带图片,带文字,有白边框的这种图片怎么制作的?...

    这种"留白图文"可以用手机APP快速制作,用现成的文字模板,或者是自己加字,加图案都OK.比如:下面同样一张图片和文字,加上留白后,只需调整照片位置就能做出多种图文效果. 1.横版 ...

  4. c++打印心形_C语言控制台打印3D爱心图案

    非常多 这些代码能够完毕几个不同的爱心图案.当中有一个样例甚至能够在黑色背景的控制台上打印出跳动的3D爱心动画,效果相当震撼. 我用的是 普通的爱心图案 C语言代码: #include "s ...

  5. java 按钮设置图片_Java中如何设置带图片按钮的大小

    在java部分需要用到图形界面编程的项目中,经常会使用图片设置对按钮进行美化,但是使用时会出现一个很麻烦的问题, 按照方法:JButton jb1 = new JButton(); jb1.setBo ...

  6. java poi 读取word图片,Java POI导入word, 带图片

    1.导入文件示例,word中简历表格模板 2.代码示例分两部分,一部分读取图片/** * 导入word(基本信息,word格式) * @param staffId * @param baseInfoF ...

  7. c语言考试的说说带图片致自己,励志说说带图片致自己

    梦想,可以使人疯狂,它是人生的动力,也是人生活的源泉,人为梦想而活.下面是小编精心为你们整理的关于的相关内容,希望你们会喜欢! 精选 1. 比别人多一点努力,你就会多一份成绩;比别人多一点志气,你就会 ...

  8. c语言考试的说说带图片致自己,励志说说带图片致自己最新

    1.提笔安天下,跨马定乾坤. 2.走错了路要记得回头,爱错了人要懂得放手.你装作刀枪不入的样子,就要做好被万箭穿心的准备. 3.不要在意别人在背后怎么看你说你,因为这些言语改变不了事实,却可能搅乱你的 ...

  9. 微信昵称mysql图片不显示不全_带图片的微信用户名称存mysql问题总结

    先直接说两种解决方法,第一种比较烦(其实也没有很烦),第二种简单 1.后台对 用户名这个字段进行 加码 存入到mysql 取出来 再解码呈现 我的项目中 是 nickName 字段进行存储微信头像数据 ...

最新文章

  1. 使用boostrap组件结合PageHelper完成javaweb网页的分页功能
  2. CMake 条件判断
  3. 【方法杂谈】你真的了解CVPR吗?
  4. 51NOD 1138 连续整数的和
  5. 【Linux】一步一步学Linux——ld命令(256)
  6. [翻译:更新]Understanding Linux Network Internals - Table of Contents
  7. pdo mysql 和 mysqli_PHP中MySQL、MySQLi和PDO的用法和区别
  8. 例子 类的定义与对象的创建 狗的例子
  9. hu3201 Build a Fence 解题报告
  10. 检索每个组中的最后一条记录-MySQL
  11. 广东自考计算机专业在校生,2020年4月广东自考计算机及应用专业计划及课程设置(B080702本科)...
  12. python 截图 minicap_【Python】使用minicap对安卓手机快速截屏
  13. 单项选择题标准化考试系统
  14. ADC噪声全面分析 -01- ADC噪声的类型以及ADC特性
  15. 河北安新复合型水稻 国稻种芯·中国水稻节:雄安生态示范区
  16. 教育企业该如何搭建私域流量池
  17. 解决中标麒麟QQ乱码和WPS缺失字体的错误
  18. i7 10700和10700f 10700k这三个CPU有什么区别
  19. 什么是数据中心SOP、MOP、EOP?
  20. Symbian UIQ简介

热门文章

  1. 2021Q3展锐智能手机芯片全球市占率达10%
  2. PHPNOW如何卸载
  3. 几百行代码写个Mybatis,原理搞的透透的!
  4. Oracle账号分享(供jdk下载使用)
  5. 一年级课程表(3月28日-4月1日)
  6. 网络安全与网站安全及计算机安全:如何使用Kali Linux进行内网或局域网安全演练?
  7. MATLAB语言的串口助手
  8. 网站推广优化教程100条(SEO,网站关键字优化,怎么优化网站,如何优化网站关键字)...
  9. 盘点ML/DL领域国外和国内的顶级大牛
  10. 推荐一个免费、轻巧、简单好用的Excel工具包