Archive for May, 2006
May 26, 2006
key words: IE打印 web打印 页面打印
最近又碰到了页面打印,顺便记录一下,本来下午写完了,可惜最近blogjava最近总是出现问题,提交居然失败,只好再来一次.
function SaveDataSourec(HeadName1, HeadName2, DivName) {
var Div1 = DivName.innerHTML;
var css = ’<style type=“text/css“ media=all>‘ +
‘p { line-height: 120%}’ +
‘.fhead { font-size: 9pt; text-decoration: none; color: 104A7B}’ +
‘.ftitle { line-height: 120%; font-size: 18px; color: #000000}’ +
‘td { font-size: 10px; color: #000000}’ +
‘</style>‘ ;
var body = ’<table width=“640“ border=“0“ cellspacing=“0“ cellpadding=“5“>‘ +
‘ <tr> ’ +
‘ <td class=“fbody“>‘ +
‘ <b><div align=“center“>‘ + ’<font size=“+1“ class=fhead>‘ + HeadName1 + ’</div>‘ + ’</font></b>‘ +
‘ <b><div align=“center“>‘ + ’<font size=“+1“ class=fhead>‘ + HeadName2 + ’</div>‘ + ’</font></b>‘ +
‘ </td>‘ +
‘ </tr>‘ +
‘ <tr> ’ +
‘ <td class=“fbody“>‘ +
‘ <div align=“center“ class=ftitle>‘ + Div1 + ’</div>‘ +
‘ </td>‘ +
‘ </tr>‘ +
‘</table>‘;
document.body.innerHTML = ’<center>‘ + css + body + ’<OBJECT classid=“CLSID:8856F961-340A-11D0-A96B-00C04FD705A2“ height=0 id=wb name=wb width=0></OBJECT>‘ + ’</center>‘;
}
function PrintDataSourec(HeadName1, DivName) {
var oldBody = document.body.innerHTML;
var Div1 = DivName.innerHTML;
var css = ’<style type=“text/css“ media=all>‘ +
‘p { line-height: 120%}’ +
‘.fhead { font-size: 40pt; text-decoration: none; color: 104A7B}’ +
‘.ftitle { line-height: 120%; font-size: 25px; color: #000000}’ +
‘td { font-size: 25px; color: #000000}’ +
‘</style>‘ ;
var body =
‘<table width=“100%“ border=“0“ cellspacing=“0“ cellpadding=“0“>‘ +
‘ <tr>‘ +
‘ <td height=“40“></td>‘ +
‘ </tr>‘ +
‘</table>‘ +
‘<table width=“640“ border=“0“ cellspacing=“0“ cellpadding=“5“>‘ +
‘ <tr> ’ +
‘ <td class=“fbody“>‘ +
‘ <b><div align=“center“>‘ + ’<font size=“+3“ class=fhead>‘ + HeadName1 + ’</div>‘ + ’</font></b>‘ +
‘ </td>‘ +
‘ </tr>‘ +
‘ <tr> ’ +
‘ <td class=“fbody“>‘ +
‘ <div align=“center“ class=ftitle>‘ + Div1 + ’</div>‘ +
‘ </td>‘ +
‘ </tr>‘ +
‘</table>‘ +
‘<table width=“640“ border=“0“ cellspacing=“0“ cellpadding=“5“>‘ +
‘ <tr> ’ +
‘ <td class=“fbody“>‘ +
‘ </td>‘ +
‘ </tr>‘ +
‘</table>‘;
document.body.innerHTML = ’<center>‘ + css + body + ’<OBJECT classid=“CLSID:8856F961-340A-11D0-A96B-00C04FD705A2“ height=0 id=wb name=wb width=0></OBJECT>‘ + ’</center>‘;
try {
wb.execwb(6, 6);
}
catch(ex) {
alert(“请在IE里设置允许ActiveX“);
}
document.body.innerHTML = oldBody;
}
function PrintDataSourecWithSetup(HeadName1, HeadName2, DivName) {
var oldBody = document.body.innerHTML;
var Div1 = DivName.innerHTML;
var css = ’<style type=“text/css“ media=all>‘ +
‘p { line-height: 120%}’ +
‘.fhead { font-size: 9pt; text-decoration: none; color: 104A7B}’ +
‘.ftitle { line-height: 120%; font-size: 18px; color: #000000}’ +
‘td { font-size: 10px; color: #000000}’ +
‘</style>‘ ;
var body = ’<table width=“640“ border=“0“ cellspacing=“0“ cellpadding=“5“>‘ +
‘ <tr> ’ +
‘ <td class=“fbody“>‘ +
‘ <b><div align=“center“>‘ + ’<font size=“+1“ class=fhead>‘ + HeadName1 + ’</div>‘ + ’</font></b>‘ +
‘ <b><div align=“center“>‘ + ’<font size=“+1“ class=fhead>‘ + HeadName2 + ’</div>‘ + ’</font></b>‘ +
‘ </td>‘ +
‘ </tr>‘ +
‘ <tr> ’ +
‘ <td class=“fbody“>‘ +
‘ <div align=“center“ class=ftitle>‘ + Div1 + ’</div>‘ +
‘ </td>‘ +
‘ </tr>‘ +
‘</table>‘;
document.body.innerHTML = ’<center>‘ + css + body + ’<OBJECT classid=“CLSID:8856F961-340A-11D0-A96B-00C04FD705A2“ height=0 id=wb name=wb width=0></OBJECT>‘ + ’</center>‘;
wb.execwb(6, 6);
document.body.innerHTML = oldBody;
}
function SetPrintSettings() {
// – advanced features
factory.printing.SetMarginMeasure(2) // measure margins in inches
factory.SetPageRange(false, 1, 3) // need pages from 1 to 3
factory.printing.printer = “HP DeskJet 870C“
factory.printing.copies = 2
factory.printing.collate = true
factory.printing.paperSize = “A4“
factory.printing.paperSource = “Manual feed“
// – basic features
factory.printing.header = “This is MeadCo“
factory.printing.footer = “Advanced Printing by ScriptX“
factory.printing.portrait = false
factory.printing.leftMargin = 1.0
factory.printing.topMargin = 1.0
factory.printing.rightMargin = 1.0
factory.printing.bottomMargin = 1.0
}
//调用接口
function printit(HeadName1, DivName) {
if (confirm(‘是否确认打印?‘)) {
PrintDataSourec(HeadName1, DivName);
return;
}
}
//带配置的接口
function printitWithSetup(HeadName1, HeadName2, DivName) {
if (confirm(‘是否确认’)) {
PrintDataSourecWithSetup(HeadName1, HeadName2, DivName);
}
}
//另存
function saveas(HeadName1, DivName) {
SaveDataSourec(HeadName1, “”, DivName);
//wb.execwb(4,1);
top.frames(“mainFrame“).document.execCommand(“saveAs“);
window.history.back(0);
}
调用很简单,把要打印的部分直接放在 <div>里就可以了
<div id=”myPrint”>
your content to print
</div>
把div传给printit就可以了
由于本质上是js调用了ActiveX,所以会涉及到安全的问题,如果客户端对ActiveX禁用会出现问题,所以可以在异常处理信息里告诉用户,可以在安全设置里把你的站点的URL放进信任站点
关于打印,还有另一种类型,就是发票套打,可以用Applet实现,也可以用自己写的ActiveX来实现,上一次的一个phs项目里他们就使用vc写的ActiveX,用起来感觉不错,不过依然存在安全上的限制问题,不过如果用Applet的话实际上也是需要客户端安装jre的,从某种角度上来说差不多。话又说回来,做项目不同于做产品,可以对客户有所要求 
VN:F [1.6.3_896]
Rating: 0.0/10 (0 votes cast)
VN:F [1.6.3_896]
May 23, 2006
kew words: javamail
这几天项目里涉及到javamail,顺便看了下.
现在都习惯在blogjava上搜索一番了 XXX in site:blogjava.net是我常用的搜索方式了,呵呵,大多数时候发现blogjava没让我失望,也说明这里的高手很多啊
感觉 Bromon的两篇文章很实用:
JavaMail使用指南(一) 和 Javamail使用指南(二)
还有 morcble的 javamail发送邮件 和 javamail接受邮件
在测试的时候有几个问题值得一提:
- 第一就是一定要加上activation.jar 库文件,否则会报下面的异常:
NoClassDefFoundError: javax/activation/DataSource
- 另外,发现用yahoo的smtp会报535的验证错误,把验证的方式换为morcble的下面的内部类的方式验证也不行:
Session session = Session.getDefaultInstance(props,
new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(mymail.username,
mymail.password);
}
});
最后换了个smtp服务器没问题,不知道各位兄弟有没有碰到这样的问题,可以确认的是我的yahoo配置信息应该是正确的,因为我用foxmail收发信件都是可以的.
后来到yahoo中国里面看了一下帮助,里面说
我们目前正在对雅虎邮箱该项服务进行相关的调整,因此我们暂时停止了在页面上POP服务设置的相关介绍。目前雅虎邮箱暂时不提供POP服务,敬请关注雅虎邮箱的近期活动。
应该就是这个原因了
可以参考这篇 : 简化JavaMail:小巧 Jakarta Commons-Email 简单教程
VN:F [1.6.3_896]
Rating: 0.0/10 (0 votes cast)
VN:F [1.6.3_896]
May 22, 2006
出处:codeChina
key words: cos 文件上传 jsp上传
index.html文件:
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html;charset=gb2312″>
<title>无标题文档</title>
</head>
<body>
<!– enctype的值很重要,upload.jsp为处理上传的jsp–>
<form name=”form1″ method=”post” enctype=”multipart/form-data”
action=”upload.jsp”>
<p>
<input name=”file1″ type=”file”>
</p>
<p>
<input name=”file2″ type=”file”>
</p>
<p> <input name=”file3″ type=”file”>
</p>
<p>
<input type=”submit” name=”Submit” value=”上传”>
</p>
</form >
</body>
</html>
upload.jsp文件 :
<%@page import=“java.io.*“%>
<%@page import=“com.oreilly.servlet.MultipartRequest“%>
<%@page import=“com.oreilly.servlet.multipart.CoverFileRenamePolicy“%>
<%@page contentType=“text/html; charset=gb2312“ %>
<%
//文件上传后,保存在c:\\upload
String saveDirectory =“c:\\upload“;
//每个文件最大5m,最多3个文件,所以
int maxPostSize =3 * 5 * 1024 * 1024 ;
//response的编码为“gb2312“,同时采用缺省的文件名冲突解决策略,实现上传
//就这一句就完成上传了,真是很爽
MultipartRequest multi = new MultipartRequest(request, saveDirectory, maxPostSize,“gb2312“);
//输出反馈信息
Enumeration files = multi.getFileNames();
while (files.hasMoreElements()) {
System.err.println(“ccc“);
String name = (String)files.nextElement();
File f = multi.getFile(name);
if(f!=null){
String fileName = multi.getFilesystemName(name);
String lastFileName= saveDirectory+“\\“ + fileName;
out.println(“上传的文件:“+lastFileName);
out.println(“<hr>“);
}
}
%>
相关链接:几种上传方法介绍和比较
VN:F [1.6.3_896]
Rating: 0.0/10 (0 votes cast)
VN:F [1.6.3_896]
May 16, 2006
key words: 动态树 eval函数用法
近期项目中需要在ilearning中做开发,用到大量纯jsp模式的开发,当然javaScript也用了很多,看来近期要好好研究javascript了
一.树
这次要做一个树,需要支持展开和放置checkbox,开始的时候打算找一个,后来发现没有适合的,最后自己写,其实也就是用到.style.display=’none’或者.style.display=’block’来支持展开
显示效果如下:

<!DOCTYPE HTML PUBLIC ”-//W3C//DTD HTML 4.01 Transitional//EN”
“http://www.w3.org/TR/html4/loose.dtd”>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″>
<title>Tree</title>
<script language=”javascript”>
function show(IMG,DV)
{
if(DV.style.display==“none“)
{
DV.style.display=“block“;
IMG.src=“manager.gif“
}
else
{
DV.style.display=“none“;
IMG.src=“manager.gif“
}
}
var display=“none“;
var i;
function showall()
{
var divTags=document.getElementsByTagName(“div“);
//alert(divTags[10].id.replace(“DV”,”"));
if( display==“none“ )
{
for(i=0;i<divTags.length;i++)
{
divTags[i].style.display=“block“;
eval(“IMG“+divTags[i].id.replace(“DV“,“”)).src=“images/btnDel.gif“;
display=“block“
}
}
else
{
for(i=0;i<divTags.length;i++)
{
divTags[i].style.display=“none“;
eval(“IMG“+divTags[i].id.replace(“DV“,“”)).src=“images/btnAdd.gif“;
display=“none“;
}
}
}
</script>
<SCRIPT LANGUAGE=”JavaScript”>
function checkAll(str)
{
var a = document.getElementsByName(str);
var n = a.length;
for (var i=0; i<n; i++)
a[i].checked = window.event.srcElement.checked;
}
function checkItem(str)
{
var e = window.event.srcElement;
var all = eval(“document.form0.“+ str);
if (e.checked)
{
var a = document.getElementsByName(e.name);
all.checked = true;
for (var i=0; i<a.length; i++)
{
if (!a[i].checked){ all.checked = false; break;}
}
}
else all.checked = false;
}
</SCRIPT>
</head>
<body>
<a href=”#” ONCLICK=”show(IMG001,DV001)”>
<img id=”IMG001″ src=”manager.gif” border=”0″></a>
<input type=”Checkbox” name=”All” onclick=”checkAll(‘cb’)”>
第一层
<!–Begin of 2–>
<DIV id=’DV001′ style=’display:none’>
<img id=”IMG0010″ src=”user.gif” border=”0″>
<input type=”checkbox” name=”cb” value=”1″ >
101
<br>
<img id=”IMG0010″ src=”user.gif” border=”0″>
<input type=”checkbox” name=”cb” value=”1″ >
102
<!–End of 2–>
</div>
<br>
<a href=”#” ONCLICK=”show(IMG002,DV002)”>
<img id=”IMG002″ src=”manager.gif” border=”0″>
</a>
<input type=”Checkbox” name=”fdasfdsafsd” onclick=”checkAll(‘cbb’)” >
第二层
<!–Begin of 2–>
<DIV id=’DV002′ style=’display:none’>
<img id=”IMG0011″ src=”user.gif” border=”0″>
<input type=”checkbox” name=”cbd” value=”1″ id=”cbb”>
201
<br>
<img id=”IMG0011″ src=”user.gif” border=”0″>
<input type=”checkbox” name=”cbd” value=”1″ id=”cbb”>
202
<!–End of 2–>
</div>
</body>
</html>
2.eval函数用法
这次碰到一个问题,就是动态获取某个id的值,比如document.formX.idX.value,其中idX是动态的,所以直接写无法获得,会提示找不到某变量,这时eval就派上用场了
比如
var myObj = “document.formX.“+idX;
myObj.value = XXValue;
详细信息参考这里
这里再提供几个例子:
function simpleSwap()
{
var the_image = prompt(“change parrot or cheese“,“”);
var the_image_name = “window.document.“ + the_image;
var the_image_object = eval(the_image_name);
the_image_object.src = “ant.gif“;
}
function tophide(id) //id indicates menu
{
if (top.topframeset.rows == “31,*“)
{
top.topframeset.rows = “86,*“;
eval(id + “_icon.src=“/imgs/collapse_up.gif’“);
eval(id + “_icon.alt=‘Collapse The Head’“);
head.style.display = “block“
}
else
{
top.topframeset.rows = “31,*“;
eval(id + “_icon.src=“/imgs/collapse_down.gif’“);
eval(id + “_icon.alt=’Expand The Head’“);
head.style.display = “none“
}
}
VN:F [1.6.3_896]
Rating: 0.0/10 (0 votes cast)
VN:F [1.6.3_896]
May 8, 2006
注:这个说的挺全面,考虑到了两种情况,一个是超连接,一个是表单
原文是这里
Struts 的 Token 机制可以解决这个问题。
1. 防止通过超链接重复访问 Struts Action 。
如果我们要防止 A 的默认页面 J 中指向 K 的超链接重复提交数据,按照下列步骤即可:
a. 如果 J 是从 Struts Action 转发而来,我们要在该 Struts Action 的 execute 方法中添加下面的一行:
saveToken(request);
b. 如果 J 不是从 Struts Action 转发而来,那么新建一个 Struts Action ,在该 Struts Action 的 excute 方法中增加上面的一行,然后再从该 action 转到 J 页面。
c. 在 J 页面中使用 Struts 标签生成指向 K 的超链接,如:
<html:link action=”/deleteLayoutAction?layoutId=0″ transaction=”true” >delete</html:link>
注意红色字体部分。
d. 在 <html:link> 标签指向的 action 的 excute 方法中加入下面的代码:
if (!isTokenValid(request)) {
return mapping.findForward(“ 这种情况下就是重复提交,转到相应的页面 “);
}
e . All Done.
2. 防止通过表单重复提交数据。
a. 如果 J 是从 Struts Action 转发而来,我们要在该 Struts Action 的 execute 方法中添加下面的一行:
saveToken(request);
b. 如果 J 不是从 Struts Action 转发而来,那么新建一个 Struts Action ,在该 Struts Action 的 excute 方法中增加上面的一行,然后再从该 action 转到 J 页面。
c. 在 J 页面中表单 Action 属性指向的 Struts action 的 excute 方法中加入下面的代码:
if (!isTokenValid(request)) {
saveToken(request);
return mapping.findForward(“ 这种情况下就是重复提交,转到相应的页面 “);
saveToken(request);
}
e . All Done.
VN:F [1.6.3_896]
Rating: 0.0/10 (0 votes cast)
VN:F [1.6.3_896]
May 8, 2006
注:本文继续分页的上一篇 关于分页,标签,缓存
hibernate分页有现成的支持:
query.setFirstResult(start);
query.setMaxResults(rowNum);
MySql如下:
select * from table where
limit start,rowNum;
Oracle如下
select * from table where
and rowid not in(select rowid from t_table where …. and rownum<= (pageIndex-1) * size)
and rownum <= size;
PageBean以前是设置currentPage,然后在页面里自己判断上一页下一页是什么,后来发现纯粹多余,完全可以把目标页写进去,而且参数也统一了,以前页面传到Action有好几个参数:
if(method.equals(“lastPage“)){
}else if(method.equals(“nextPage“)){
}else if(method.equals(“targetPage“)){
//
.
}
现在统一一个参数就是pageIndex,爽多了 
PageBean代码如下:
int currentPage = 1;//当前页:Action控制
int totalPages = 0;//总页数 :自己运算
public static int pageRecorders = 10; //每页记录数,默认为10,可以在初始化的时候修改//总数据数
int pageStartRow = 0; //每页的起始数 [这个字段可以去掉]
int pageEndRow = 0; //每页显示数据的终止数 [这个字段也可以去掉]
boolean hasNextPage = false; //是否有下一页:自己运算
boolean hasPreviousPage = false; //是否有前一页 :自己运算
List objList = new ArrayList();//存放欲展示的对象列表
int totalRows;//总记录数,由底层service提供
//增加上一页索引 [directly to target page]
private int lastPageIndex = 1;
//增加下一页索引 [directly to target page]
private int nextPageIndex = 1;
public int getLastPageIndex() {
return currentPage - 1;
}
public int getNextPageIndex() {
return currentPage + 1;
}
//是否有上一页
public boolean isHasPreviousPage() {
return (currentPage > 1 ? true : false);
}
//共有多少页,service只提供有多少条记录,多少页数由PageBean自己运算
public int getTotalPages() {
if (totalRows <= pageRecorders) return 1;
return (totalRows % pageRecorders == 0 ? totalRows / pageRecorders : totalRows / pageRecorders + 1);
}
public int getCurrentPage() {
return currentPage;
}
public int getPageEndRow() {
return pageEndRow;
}
//是否有下一页
public boolean isHasNextPage() {
return (currentPage < this.getTotalPages() ? true : false);
}
public int getTotalRows() {
return totalRows;
}
public int getPageStartRow() {
return pageStartRow;
}
public int getPageRecorders() {
return pageRecorders;
}
public void setObjList(List objList) {
this.objList = objList;
}
public void setHasPreviousPage(boolean hasPreviousPage) {
this.hasPreviousPage = hasPreviousPage;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public void setPageEndRow(int pageEndRow) {
this.pageEndRow = pageEndRow;
}
public void setHasNextPage(boolean hasNextPage) {
this.hasNextPage = hasNextPage;
}
public void setTotalRows(int totalRows) {
this.totalRows = totalRows;
}
public void setPageStartRow(int pageStartRow) {
this.pageStartRow = pageStartRow;
}
public void setPageRecorders(int pageRecorders) {
this.pageRecorders = pageRecorders;
}
public List getObjList() {
return objList;
}
}
在action中负责把pageIndex传给PageBean,以及通过service得到的记录总数传给pageBean就OK了
补充:另,在IDEA中文站上看到一篇文章 分页,心中的痛? 提到用一个统一的接口来规范:
代码如下:
public interface Page {
boolean isFirstPage();
boolean isLastPage();
boolean hasNextPage();
boolean hasPreviousPage();
int getLastPageNumber();
Object getThisPageElements();
int getTotalNumberOfElements();
int getThisPageFirstElementNumber();
int getThisPageLastElementNumber();
int getNextPageNumber();
int getPreviousPageNumber();
int getPageSize();
int getThisPageNumber ();
}
个人感觉思想挺好,不过我还是喜欢用一个PageBean类就足够了,没必要搞复杂了,在PageBean中其实是currentPage为核心.
一个工具能够在任何地方都能容易的嵌入进去,这就很小巧了,也就够用了. 
VN:F [1.6.3_896]
Rating: 0.0/10 (0 votes cast)
VN:F [1.6.3_896]
May 5, 2006
在新窗口中添加内容到父窗口
代码如下:
父窗口: form.html
<script language=“JavaScript“>
function addItems()
{
var AWnd=window.open(‘items.htm’,'fwId’,'resizable=yes,scrollbars=yes,width=300,height=400‘);
AWnd.focus();
}
function delItems()
{
var sel=document.menu.fwId;
for(i=0;i<=sel.options.length;i++)
{
if(sel.options[i]!=null)
if(sel.options[i].selected)
{
sel.options[i]=null;
i–;
}
}
}
</script>
<form method=“post“ name=“menu“>
<select name=“fwId“ size=“5“ multiple>
</select>
<input name=“item“ type=“button“ onClick=“addItems()“ value=“Ìí¼Ó“>
<input name=“itemDel“ type=“button“ onClick=“delItems()“ value=“ɾ³ý“ >
</form>
新开窗口items.html:
<script language=“JavaScript“>
function doSubmit(value,name)
{
var aa = window.opener.document;
var myop = aa.createElement(“OPTION“);
for(var j = 0; j < aa.menu.fwId.options.length; j++)
{
if(value == aa.menu.fwId.options[j].value)
{
alert(“ÒѾ±»Ñ¡Ôñ£¡“);
return;
}
}
myop.text =name;
myop.value =value;
aa.menu.fwId.add(myop);
}
</script>
<form name=“items“>
<a onclick=“javascript:doSubmit(’1′,’test1′);“ href=“#“>test1</a><br>
<a onclick=“javascript:doSubmit(’2′,’test2′);“ href=“#“>test2</a><br>
</form>
VN:F [1.6.3_896]
Rating: 0.0/10 (0 votes cast)
VN:F [1.6.3_896]