用壳浏览器实现Web的本地灵活打印
B/S架构是主流,但使用浏览器打印web内容并不方便,常需要用户对浏览器做一些设置,有了技术门槛。如果使用客户端程序,可以解决这个问题,但C/S架构非主流。所以考虑做个壳浏览器,用这个浏览器去访问网页,但网页中需要打印时,把打印功能的实现,交给壳浏览器实现。这样对于不懂设置浏览器的用户,可以选择使用壳浏览器。
具体思路如下:
当用普通浏览器访问时,服务器端返回的页面的打印按钮的js代码是直接调用浏览器的打印功能。
当用壳浏览器访问时,访问网址带个参数,服务器端判断到这个参数的存在,就在返回页面的打印按钮的js代码写成调转去一个特殊网址,这个特殊网址相当于一条指令,壳浏览器捕获到这条指令后,设置打印格式并打印,这样打印就完全由壳浏览器实现了。
服务器端代码
<%@ page language="java" contentType="text/html; charset=gb2312" pageEncoding="gb2312"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%
//保证request以及response的编码
request.setCharacterEncoding("gb2312");
response.setContentType("text/html;charset=gb2312");
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>testPrint</title>
</head>
<body>
<script>
function printWeb(){
var username = document.getElementById('username').value;
var gender = document.getElementById('gender').value;
var age = document.getElementById('age').value;
alert(username+" "+gender+" "+age);
window.print();
}
function printClient(){
var username = document.getElementById('username').value;
var gender = document.getElementById('gender').value;
var age = document.getElementById('age').value;
window.location="cmd=printme?"+username+"|"+gender+"|"+age;
}
</script>
<table border="1" align="center" width="400px">
<thead>
<tr>
<td colspan="3" align="center">用户信息</td>
</tr>
</thead>
<tr>
<td>姓名</td>
<td>性别</td>
<td>年龄</td>
</tr>
<tr>
<td><INPUT TYPE="text" id="username" value="vigar"></td>
<td><INPUT TYPE="text" id="gender" value="男"></td>
<td><INPUT TYPE="text" id="age" value="26"></td>
</tr>
<thead>
<tr>
<td colspan="3" align="center">
<c:choose>
<c:when test="${param.client eq 'app'}">
<input type="button" id="button" value="用客户端打印" onclick="printClient()" />
</c:when>
<c:otherwise>
<input type="button" id="button" value="用浏览器打印" onclick="printWeb()" />
</c:otherwise>
</c:choose>
</td>
</tr>
</thead>
</table>
</body>
</html>
把代码保存为testPrint.jsp,放到tomcat/webapps/ROOT下,在tomcat/lib要放一个jstl-1.2.jar,因为用到了jstl标签。启动tomcat,试试访问。
用普通浏览器访问:
用壳浏览器访问:
壳浏览器代码
壳浏览器是用delphi实现的,很简单的代码,不知算不算得上是壳浏览器。只需放一个webBrowser控件,添加两个事件:FormShow事件在窗口启动时触发控件去访问网页;WebBrowser1BeforeNavigate2事件用于捕获web鼠标点击打印事件,然后接手打印。
FormShow代码:
procedure TSDIAppForm.FormShow(Sender: TObject);
begin
//用参数告诉服务端是在用客户端进行访问,服务端因此返回带客户端打印按钮的页面
WebBrowser1.Navigate('http://192.168.3.123:8080/testPrint.jsp?client=app');
end;
WebBrowser1BeforeNavigate2代码:
procedure TSDIAppForm.WebBrowser1BeforeNavigate2(ASender: TObject;
const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData,
Headers: OleVariant; var Cancel: WordBool);
var
params:string;
pl:TStrings;
i:Integer;
PText:TextFile;
begin
//用约定的指令确定点击事件
if pos('cmd=printme',url)>0 then
begin
//获取要打印的内容,如果打印更复杂的内容,比如包含图片。可以至少只传回一个id,然后控件自己直接去服务器取其他内容,服务器端要有按id取内容的服务
i:=pos('?',url);
params:=RightStr(url,Length(url)-i);
pl:=TStringList.Create;
pl.Delimiter := '|';
pl.DelimitedText := params;
//只是利用url作为一个指令,不需要真正跳转
Cancel:=True;
//设置打印格式并打印
printer.Canvas.Font.Charset:=GB2312_CHARSET;
AssignPRN(PText);
Rewrite(PText);
Printer.Canvas.Font.Size:=15;
writeln(Ptext,pl[0]);
Printer.Canvas.Font.Size:=20;
Printer.Canvas.Font.Color:=clRed;
writeln(Ptext,pl[1]);
Printer.Canvas.Font.Color:=clBlue;
Printer.Canvas.Font.Size:=8;
writeln(Ptext,pl[2]);
CloseFile(Ptext);
ShowMessage('done');
end;
end;
壳浏览器捕获到打印请求后,就可以按自己的意愿设置打印格式,调用本地打印机进行打印。
打印效果
浏览器的打印
壳浏览器的打印
因没有打印机,所以用虚拟打印机生成了pdf文件。
请教
delphi已经太老,可以参考着用别的语言实践。请问用什么语言开发客户端程序好?件用什么报表控件可以灵活设置页面格式?
代码下载:
用壳浏览器实现Web的本地灵活打印