- 浏览: 1311475 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (732)
- Java_about (146)
- Spring_Hibernate_Struts_OpenSource (27)
- linux_unix (62)
- life_sth (22)
- js_css_html_xml_nodejs (69)
- design_pattens (1)
- Perl (8)
- php_ecshop (4)
- DB_Mysql_Oracle_Informix_SqlServer (43)
- JSTL (8)
- Testing_自动化测试 (42)
- DB_ID_UUID (4)
- SEM_SEO (1)
- english_study_improvement (4)
- SVN_Git (9)
- WebService_SOA_CloudComputing (3)
- E-Commerce (1)
- Lucene_Solr (7)
- others (2)
- Regex (2)
- tomcat_jetty (8)
- zeroc-ice (1)
- java_excel (5)
- ant_maven_gradle (5)
- Unity_VR_AR_C# (2)
- jmeter (1)
- XPath_dom4j (1)
- Ruby_and_Rails (68)
- write_a_rails (17)
- manage_and_team (1)
- getting_real (1)
- ubuntu (20)
- git_and_git_flow (7)
- TODO (1)
- PM_design (2)
- Python_and_Django (8)
- NoSql_mongo_redis (24)
- C/C++ (3)
- vi_vim_gvim (0)
- c#_.Net_windows编程_dll (10)
- Php_and_Yii (9)
- Android_IOS (31)
- Mysql (5)
- sa_运维_network_硬件 (37)
- lua (2)
- c_cpp_VisualStudio (21)
- 硬件-RM-Arduino (6)
最新评论
-
shenkun58:
...
NoClassDefFoundError: Could not initialize springframework.BeanCreationException -
liaojia1:
正解,感谢
NoClassDefFoundError: Could not initialize springframework.BeanCreationException -
flingfox63:
谢谢分享,电脑上有IPV6,导致了Guard启动不了……
ruby错误解决: Address family not supported by protocol - connect(2) -
c39274936:
s = "hello_world_ruby" ...
驼峰格式和下划线格式转换_translation between camel and snake format -
yfj300:
学习了学习了学习了学习了
硬盘基本知识(磁道、扇区、柱面、磁头数、簇、MBR、DBR)
摘自:http://blog.csdn.net/wxf0701/archive/2006/11/24/1412931.aspx
一.概述
对基于B/S架构的应用程序而言,客户端的页面打印一直是比较头疼的问题,简单的做法是:1.使用IE的打印功能;2.使用水晶报表。但以上两种办法,都
有很大的局限性,很难实现特殊要求的排版和精确的定位,所以不能满足一些特殊客户的BT要求。为此,本人总结了自己在使用Web打印上的一点经验,和大家
分享。
本文涉及以下技术:javascript、ActiveX、ASP.NET、GDI+。
二.基本架构
首先,我们不能使用IE的打印功能,必须自己设计‘打印’按钮。很多人习惯将‘打印’按钮放在要打印的页面上,打印时为了不把这个按钮打印出来,采用办法如下:1.打印前隐藏按钮;2.打印;3.显示按钮。
我觉得这样比较麻烦,所以我采用框架。一共有三个页面:
1.main.htm :框架页面,上面是打印按钮,下面是要显示的页面。
2.header.htm :标题栏,至少包含一个打印按钮。
3.report.aspx :要打印的页面,由用户生成。
//main.htm
<html>
<head>
<title></title>
</head>
<frameset rows="10%,90%" frameborder="0" border="0" frameSpacing="0">
<frame id="header" name="header" src="Header.htm" noresize scrolling="no">
<frame id="report" name="report" src="Report.aspx" noresize scrolling="auto">
</frameset>
</html>
//header.htm
<html>
<head>
<script id=clientEventHandlersJS language=javascript>
<!--
function btnPrint_onclick()
{
parent.report.focus();
parent.report.print();
}
//-->
</script>
</head>
<body>
<INPUT id="btnPrint" type="button" value="Print" name="Print" onclick="return btnPrint_onclick()">
</body>
</html>
这样,在点击‘打印’按钮时,将直接打印report.aspx页面的内容,既简单又直观。
三.打印
要完全控制打印,就必须由程序设定页眉、页脚、页边距。每个客户端的IE设置都不尽相同,你可以要求你的客户修改他们的打印设置为你指定的值,显然这不现实。所以正确的做法是:
1.备份客户打印页面设置;
2.设置页眉页脚上下左右边距为自己需要的值;
3.打印;
4.恢复原来的打印页面设置。
这里用到一个叫ScriptX的控件。你需要下载一个文件:smsx.cab,下载地址:http://www.meadroid.com/scriptx/sxdownload.asp 。这个地址并不能保证长期有效,你可以在搜索引擎上搜索‘ScriptX’以获得更多相关信息。
在“header.htm”中增加该控件的引用:
<OBJECT id="factory" style="DISPLAY: none" codeBase="http://localhost/WebApplication1/smsx.cab#VVersion=6,3,434,12
"
classid="clsid:1663ed61-23eb-11d2-b92f-008048fdd814" viewastext>
</OBJECT>
注意CodeBase指向你的实际存放文件的位置,在客户端第一次浏览该页面时,将下载并安装该控件,请确定客户端的安全设置允许安装控件。
那么此时 header.htm 的内容如下。
//header.htm
<html>
<head>
<script id="clientEventHandlersJS" language="javascript">
<!--
function btnPrint_onclick()
{
//备份客户打印机设置
var h = factory.printing.header;
var f = factory.printing.footer;
var t = factory.printing.topMargin;
var b = factory.printing.bottomMargin;
var l = factory.printing.leftMargin;
var r = factory.printing.rightMargin;
//设置页眉页脚上下左右边距
factory.printing.header = "";
factory.printing.footer = "";
factory.printing.topMargin="0";
factory.printing.bottomMargin="0";
factory.printing.leftMargin="0";
factory.printing.rightMargin="0";
//打印
parent.report.focus();
parent.report.print()
//恢复原来的打印设置
factory.printing.header = h;
factory.printing.footer = f;
factory.printing.topMargin=t;
factory.printing.bottomMargin=b;
factory.printing.leftMargin=l;
factory.printing.rightMargin=r;
}
//-->
</script>
<OBJECT id="factory" style="DISPLAY: none" codeBase="http://localhost/WebApplication1/smsx.cab#VVersion=6,3,434,12
"
classid="clsid:1663ed61-23eb-11d2-b92f-008048fdd814" viewastext>
</OBJECT>
</head>
<body bgColor="#9999cc">
<INPUT id="btnPrint" type="button" value="Print" name="Print" onclick="return btnPrint_onclick()">
</body>
</html>
此时,不管客户端IE设置如何,都能正确打印页面,打印内容将完全取决于页面:report.aspx。
四.动态页面生成
1. 如果你的页面是静态页面,或者页面元素为固定数量,那就非常简单了。只要调整好各个元素位置就行了,绝对所见即所得。要注意的是一个A4纸的大小为21cm×29.7cm,对应象素大约为 794×1123 (系统分辨率96DPI) 。
2.如果你要生成一些图表,可以使用GDI+,你自己绘制的图片绝对能满足客户需求。下面给一个例子,我在页面放一个Label,一个Image。Image动态生成,调整其位置使其打印时出现在第二页的左上角。
2 {
3 protected System.Web.UI.WebControls.Image Image1;
4 protected System.Web.UI.WebControls.Label Label1;
5
6 Web 窗体设计器生成的代码 #region Web 窗体设计器生成的代码
7 override protected void OnInit(EventArgs e)
8 {
9 InitializeComponent();
10 base .OnInit(e);
11 }
12 private void InitializeComponent()
13 {
14 this .Load += new System.EventHandler( this .Page_Load);
15 }
16 #endregion
17
18 private void Page_Load( object sender, System.EventArgs e)
19 {
20 if ( ! Page.IsPostBack)
21 {
22 InitImage();
23 }
24 }
25
26 private void InitImage()
27 {
28 Bitmap bmp = new Bitmap( 800 , 1120 );
29 Graphics g = Graphics.FromImage(bmp);
30
31 g.FillRectangle(Brushes.Gray, 0 , 0 , 800 , 1120 );
32
33 g.FillRectangle(Brushes.RoyalBlue, 0 , 0 , 100 , 600 );
34 g.FillRectangle(Brushes.Aqua, 600 , 0 , 100 , 600 );
35 g.FillRectangle(Brushes.Coral, 700 , 0 , 100 , 600 );
36
37 g.FillRectangle(Brushes.YellowGreen, 0 , 800 , 800 , 100 );
38 g.FillRectangle(Brushes.Beige, 0 , 900 , 800 , 100 );
39 g.FillRectangle(Brushes.SkyBlue, 0 , 1000 , 800 , 100 );
40 g.FillRectangle(Brushes.Tomato, 0 , 1100 , 800 , 20 );
41
42 string filename = Server.MapPath( " TempImages\\img1.jpg " );
43
44 bmp.Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg);
45
46 this .Label1.Text = filename;
47 this .Image1.ImageUrl = filename;
48 this .Image1.Attributes[ " style " ] = " POSITION: absolute; LEFT: 0cm; TOP: 29.7cm " ; // 定位
49 }
50 }
51
52
注意:要保证存放图片的目录,有写权限。
3.以上技术只适合于页面元素为固定数量的情况,对于页面内容大小不定的情况,例如,要打印一份人员信息的清单,人员数量为1~1000不等,每页显示20条记录,要有规定的页眉、页脚,此时该如何处理。
思路:ASP.NET页面都有一个基类System.Web.UI.Page,该类有一个保护方法叫void
Render(HtmlTextWriter
writer),就是通过这个方法,ASP.NET在后台把WEB服务器端控件的属性转换成HTML代码,并发送到客户端供浏览器显示。我们的办法就是“
劫持”该方法,完全手工生成所需页面标记代码。
先看一个例子:
public class FrmRYInfo : System.Web.UI.Page
{
private void Page_Load(object sender, System.EventArgs e)
{
}
protected override void Render(HtmlTextWriter writer)
{
writer.Write("<HTML>");
writer.Write("<body>");
writer.Write("<h1>Hello,world!</h1>");
writer.Write("</body>");
writer.Write("</html>");
}
}
编译并运行以上程序,可以看到一行一号字体的"Hello,world!",查看页面源文件,内容如下:
<HTML><body><h1>Hello,world!</h1></body></html>
对照上面代码,应该非常好理解,下面我们就做一个实际的例子,将信息从数据库读出,显示在页面上,每页显示15条记录。
{
writer.Write( " <HTML> " );
writer.Write( " <body> " );
DataTable tabRY = GetCustomerInfo(); // 读取数据库
int Lines = 15 ; // 每页行数
int Count = tabRY.Rows.Count;
int TotalPage = Count / Lines + (Count % Lines == 0 ? 0 : 1 );
for ( int CurrentPage = 0 ; CurrentPage < TotalPage; CurrentPage ++ )
{
int StartRow = CurrentPage * Lines;
int EndRow = StartRow + Lines;
if (EndRow > Count) EndRow = Count;
ProcessCurrentPage(writer,tabRY,StartRow,EndRow,CurrentPage,TotalPage);
}
writer.Write( " </body> " );
writer.Write( " </html> " );
}
private void ProcessCurrentPage(HtmlTextWriter writer, DataTable tabRY, int StartRow, int EndRow, int
CurrentPage, int TotalPage)
{
if (CurrentPage != 0 )
{
writer.Write( " <p style=page-break-before:always></p> " );
}
writer.Write( " <table width=630 height=417 border=0> " );
writer.Write( " <tr> " );
writer.Write( " <td width=624 height=47><div align=center style=font-size:24px>人员信息汇总
表 </ div ></ td > " );
writer.Write( " </tr> " );
writer.Write( " <tr> " );
writer.Write( " <td height=222> " );
writer.Write( " <table width=623 border=1 cellpadding=0 cellspacing=0> " );
writer.Write( " <tr> " );
writer.Write( " <td width=134><div align=center>姓名</div></td> " );
writer.Write( " <td width=134><div align=center>编号</div></td> " );
writer.Write( " <td width=134><div align=center>电话</div></td> " );
writer.Write( " <td width=134><div align=center>小灵通</div></td> " );
writer.Write( " </tr> " );
for ( int i = StartRow; i < EndRow; i ++ )
{
DataRow row = tabRY.Rows[i];
string XM = row[ " MC " ].ToString();
string BH = row[ " BH " ].ToString();
string DH = row[ " LXDH " ].ToString(); if (DH.Length == 0 )DH = " - " ;
string XLT = row[ " XLT " ].ToString();
writer.Write( " <tr> " );
writer.Write( " <td width=134><div align=center> " + XM + " </div></td> " );
writer.Write( " <td width=134><div align=center> " + BH + " </div></td> " );
writer.Write( " <td width=134><div align=center> " + DH + " </div></td> " );
writer.Write( " <td width=134><div align=center> " + XLT + " </div></td> " );
writer.Write( " </tr> " );
}
writer.Write( " </table> " );
writer.Write( " </td> " );
writer.Write( " </tr> " );
writer.Write( " <tr> " );
writer.Write( " <td height=37><div align=right>第 " + (CurrentPage + 1 ).ToString() + " 页,共 " +
TotalPage.ToString() + " 页</div></td> " );
writer.Write( " </tr> " );
writer.Write( " </table> " );
}
感觉又回到了用记事本做网页的年代,手工生成HTML代码,是不是真正叫“随心所欲”。
几点说明:
(1)在每一页(除了第一页)的
头部加入 writer.Write("<p
style=page-break-before:always></p>");
目的是控制在打印时,打印机在此换页。这里通过强制打印机换页来实现页面的布局,与上面的绝对定位的办法不同。该标记只影响打印,不影响显示。
(2)用记事本做网页绝对很痛苦,而且HTML标记也很不好用,我的办法是:用Dreamweaver生成需要的页面,再参照其HTML代码进行编程。
(3)尽量使用HtmlTextWriter类提供的一些其它方法如WriteBeginTag等取代Write方法,这样可以提高页面在客户端的兼容性。同时在每个标记后加入writer.WriteLine();进行换行,以便于调试。
发表评论
-
如何在IDEA单元测试中使用Scanner获取输入内容
2024-10-25 21:19 48如何在IDEA单元测试中使用Scanner获取输入内容 = ... -
java播放音频声音mp3等
2024-05-22 15:16 426java播放音频声音mp3等 = = = 这个方法 ... -
打包Java程序为.exe文件
2023-09-27 16:25 389= = = 打包Java程序为.exe文件 fro ... -
Java怎么生成exe可执行文件【图文讲解】
2023-09-27 16:21 389= 开发的工具,让客户体验一下再说。此时又不想发源码,怕 ... -
Java8 List集合Stream流方法操作详解
2023-09-27 16:02 145= = = from: https://zhuanl ... -
Java8 List集合Stream流方法操作详解
2023-09-27 15:59 560= = = from: https://zhuan ... -
Java8 List集合Stream流方法操作详解
2023-09-27 15:56 99= = = from: https://zhuanl ... -
【原创】Cannot create property=xxx for JavaBean=【lombok 和 yaml包 混合报错】
2023-02-04 23:31 1003= = = 问题: 同时使用lombok 和 ... -
【摘】Java文档注释用法+JavaDoc的使用详解
2022-09-12 16:32 454= = 节约重复注释 使用@inheritDo ... -
【朝花夕拾】java内部类,原理,使用
2022-08-09 22:52 385= 碰到类似问题,多读《thinking in java ... -
【拾遗】java数组copy拷贝复制的工具类方法
2022-06-11 21:20 627= 对工具类来说,copyOfRange 最好用。 这 ... -
利用Httpclient下载图片,java不用httpClient下载图片
2022-05-30 22:25 470= = = from:https://blog.csd ... -
为什么要使用lombok?
2022-04-04 20:46 403= = = 参考:https://blog.csd ... -
朝花夕拾:java-向上转型中变量覆盖要小心使用_继承过程中Java子类父类属性的覆盖问题
2022-01-13 17:31 416==== 现在的代码结构设计的复杂起来了,为了后来人编写 ... -
【Mysql数据库】Cause: java.sql.SQLException: The table 'xxx' is full
2022-01-04 17:03 1507= 本地开发测试,怎 ... -
JAVA工具类学习-java 两个list 交集 并集 差集 去重复并集
2021-09-10 16:17 873= = = List<String> ... -
java汉字判断,中文符号判断,中文标点符号判断
2021-09-02 19:07 1194=== = = 一、判断中文汉字 st ... -
velocity的模板笔记总结文档-方便查阅
2020-04-28 14:41 388= 最好把这几个官网文档看了: 官网官方文档refer ... -
mjson:像python和ruby一样好用的java类库操作json_js
2020-04-17 20:54 527= = = JSON Library for Jav ... -
关于idea2019.2-2019.3版本中文控制台乱码问题,tomcat7-tomcat8乱码
2020-04-04 23:20 481= 1 idea2019.2-2019.3版本中文控制台乱 ...
相关推荐
随心所欲的Web页面打印技术是针对基于B/S架构的应用程序中客户端页面打印问题的一种解决方案。传统的Web页面打印方式,如使用IE的内置打印功能或水晶报表,往往无法满足特定的排版和定位需求。因此,本文探讨了一种...
在WEB系统中,打印的确是比较烦人的问题,如果我们能制作一个属于自己的自定义的打印插件,那么我们在后续自定义打印的时候能随心所欲的控制打印,这样的效果对于程序员来说是非常开心的一件事件,本文将自己开发...
你需要对目标打印机进行远程管理时,在局域网任意一台电脑上运行其中的 IE 浏览器程序,输入网络打印机的 URL 地址“http://打印服务器 IP 地址/print”即可打开网络打印机的管理页面了。单击“暂停”或“恢复”超级...
○新增订单打印功能,首先生成整洁的纯文本打印件,再执行打印操作,而不是像许多同类系统仅仅是调用打印命令打印网页,打印件中有太多杂而无用的内容。 ○销售统计,对所有完成的订单进行统计,了解销售情况。 ○...
8、页面选项中增加“保持页脚在页面底部”、“是否套打模板”、“不打印背景图”等选项。 9、增加了批量设置字段别名的方法:SetDataFieldAliasName,使得英文字段在报表中可以用中文展现,更便于最终用户设计报表。...
包含使用和开发接口文档,及Delphi、VB、VC++、C#.net、VB.net和WEB下的demo。 ACReport简介 Anycell Report(简称AC Report)是一款中国式报表组件,是国内最早的基于表格,支持图文混排、公式和脚本的中国式报表...
在制作复杂的中国式报表时可以避免很多不必要的合并拆分操作,制作表格更加方便和随心所欲,并且省时省力。AC Report单元格支持多种丰富的形态,例如格式化文本、图片、图表、条码、OLE容器等。 AC Report的一些...
- **预览和打印**:在截图前预览,确保满意后再进行保存或打印。 - **自动上传**:支持FTP、Email等快速分享方式,方便与他人协作。 ### 5. 用户友好性 FSCapture界面简洁,操作直观,无论是初次接触截图工具的...
我司WEB互联网版连锁会员管理系统和商家联盟会员管理系统可进行硬件加密,只要使用我司专用加密锁,客户电脑插入加密锁才能访问和登录系统,加密锁一旦拔出电脑,系统会在10秒内自动退出,加密锁没有通用性,一个客户指定...
<br>2007/6/1 Version 3.0.9 beta <br>Updates: 1) web.config中新增configfolder、functionfolder、skin三个必须目录的全局路径设置,以往旧版本如果要在不同级别子目录的页面调用控件都要单独设置...
基于MVC的.java.web设计与开发.pdf │ 学习Struts提供的和Form相关标签.txt │ 日企编码规范.doc │ 电信盈科面试题.pdf │ 速算.txt │ 面试题URL.txt │ ├─Javascript │ │ javascript资料(源码,教材,ppt)....
基于MVC的.java.web设计与开发.pdf │ 学习Struts提供的和Form相关标签.txt │ 日企编码规范.doc │ 电信盈科面试题.pdf │ 速算.txt │ 面试题URL.txt │ ├─Javascript │ │ javascript资料(源码,教材,ppt)....
基于MVC的.java.web设计与开发.pdf │ 学习Struts提供的和Form相关标签.txt │ 日企编码规范.doc │ 电信盈科面试题.pdf │ 速算.txt │ 面试题URL.txt │ ├─Javascript │ │ javascript资料(源码,教材,ppt)....
基于MVC的.java.web设计与开发.pdf │ 学习Struts提供的和Form相关标签.txt │ 日企编码规范.doc │ 电信盈科面试题.pdf │ 速算.txt │ 面试题URL.txt │ ├─Javascript │ │ javascript资料(源码,教材,ppt)....
基于MVC的.java.web设计与开发.pdf │ 学习Struts提供的和Form相关标签.txt │ 日企编码规范.doc │ 电信盈科面试题.pdf │ 速算.txt │ 面试题URL.txt │ ├─Javascript │ │ javascript资料(源码,教材,ppt)....
【制作工资条】 瞬间将工资明细表生成工资条,方便打印并裁剪。可以自己定义工资条标题的行数以及相隔行数、插入行数等。并能动态地显示运行过程,支持程序运行后中途暂停。 【恢复工资条】 能将已生成工资条的工资...
【制作工资条】 瞬间将工资明细表生成工资条,方便打印并裁剪。可以自己定义工资条标题的行数以及相隔行数、插入行数等。并能动态地显示运行过程,支持程序运行后中途暂停。 【恢复工资条】 能将已生成工资条的工资...