??xml version="1.0" encoding="utf-8" standalone="yes"?>
JasperReports provides the necessary features to generate dynamic reports, including data retrieval using JDBC (Java Database Connectivity), as well as support for parameters, expressions, variables, and groups. JasperReports also includes advanced features, such as custom data sources, scriptlets, and subreports. All in all, JasperReports combines good features, maturity, community participation, and, best of all, it's free.
This article kicks off JavaWorld's new Open Source Profile column dedicated to Java-based open source tools and components. Look for upcoming articles spotlighting the Echo Web application framework and ObJectRelationalBridge, an object/relational mapping tool. Feel free to send me your suggestions for future articles.
Note: The documentation and code featured in this article are based on JasperReports version 0.3.3.
Report design <?xml version="1.0" encoding="UTF-8"?> The template's beginning includes any parameters passed into the report, the query that retrieves the data for the report, and the fields displayed in the report. The template's remainder divides into six report sections:
The open source JasperReports uses XML templates for your reporting needs
Summary
JasperReports, a popular, full-featured open source report-generating library, uses XML report templates to generate reports you can display on the screen, send to a printer, or save as a PDF document. In this inaugural Open Source Profile column, Erik Swenson introduces the JasperReports library and explains how to integrate JasperReports into your applications. (900 words;September 20, 2002) enerating reports is a common, if not always glamorous, task for programmers. In the past, report generation has largely been the domain of large commercial products such as Crystal Reports. Today, the open source JasperReports report generating library gives Java developers a viable alternative to commercial software.
In JasperReports, you design reports using XML report templates. For example, the following XML file is a template for a report with a title, two columns of data, and page numbers:
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN"
"http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
<jasperReport name="BasicReport" >
<parameter name="Title" class="java.lang.String"/>
<queryString><![CDATA[select name, cost from product]]></queryString>
<field name="NAME" class="java.lang.String"/>
<field name="COST" class="java.lang.Double"/>
<title>
<band height="50">
<textField>
<reportElement x="0" y="0" width="200" height="50" />
<textFieldExpression class="java.lang.String">$P{Title}</textFieldExpression>
</textField>
</band>
</title>
<pageHeader>
<band>
</band>
</pageHeader>
<columnHeader>
<band height="20">
<staticText>
<reportElement x="180" y="0" width="180" height="20"/>
<textElement>
<font isUnderline="true"/>
</textElement>
<text><![CDATA[NAME]]></text>
</staticText>
<staticText>
<reportElement x="360" y="0" width="180" height="20"/>
<textElement>
<font isUnderline="true"/>
</textElement>
<text><![CDATA[COST]]></text>
</staticText>
</band>
</columnHeader>
<detail>
<band height="20">
<textField>
<reportElement x="180" y="0" width="180" height="20"/>
<textFieldExpression class="java.lang.String"><![CDATA[$F{NAME}]]></textFieldExpression>
</textField>
<textField pattern="0.00">
<reportElement x="360" y="0" width="180" height="20"/>
<textFieldExpression class="java.lang.Double"><![CDATA[$F{COST}]]></textFieldExpression>
</textField>
</band>
</detail>
<columnFooter>
<band>
</band>
</columnFooter>
<pageFooter>
<band height="15">
<staticText>
<reportElement x="0" y="0" width="40" height="15"/>
<textElement/>
<text><![CDATA[Page:]]></text>
</staticText>
<textField>
<reportElement x="40" y="0" width="100" height="15"/>
<textElement/>
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
</band>
</pageFooter>
<summary>
<band>
</band>
</summary>
</jasperReport>pageHeader
detail
pageFooter
height
. Each band can include multiple textField
elements, which are given a position, size, and value. Report parameters, fields, and variables are referenced using F${name}
, and textField
containing the current page number. The page number's value is set to the variable <textElement/>
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
The above template represents a basic, yet functional, report. A thorough JasperReports XML-template description is beyond the scope of this article, but I've included numerous links in Resources to tools that will help you edit and create your own report templates. Next, let's see how to use JasperReports in your Java applications.
Use JasperReports
To begin using JasperReports, you first must understand what objects JasperReports uses to represent the reporting process as it progresses from report design to report generation:
JasperDesign
from an XML report template, though you can also create it programmatically.
JasperDesign
. The compilation process verifies the report design and compiles the design into a JasperPrint
: Represents a generated report. You create a JasperReport
through the fill process in which a report is populated with data from a data source.
The JasperReports API's flexibility lets you load JasperReport
, and dori.jasper.engine.JasperManager
, with methods that facilitate loading, compiling, filling, and printing reports. The following code illustrates a JasperReport jasperReport = JasperManager.compileReport(jasperDesign);
// Second, create a map of parameters to pass to the report.
Map parameters = new HashMap();
parameters.put("ReportTitle", "Basic JasperReport");
parameters.put("MaxSalary", new Double(25000.00));
// Third, get a database connection
Connection conn = Database.getConnection();
// Fourth, create JasperPrint using fillReport() method
JasperPrint jasperPrint = JasperManager.fillReport(jasperReport,
parameters, conn);
// You can use JasperPrint to create PDF
JasperManager.printReportToPdfFile(jasperPrint, "BasicReport.pdf");
// Or to view report in the JasperViewer
JasperViewer.viewReport(jasperPrint);
The code example above shows how to perform some common tasks using JasperReports. In a real-world application, you'd find it impractical to load and compile the JasperDesign
files to increase speed. You can also increase a large report's speed by generating and saving Reports the easy way
In this article, you learned how the open source JasperReports can aid your Java reporting needs. If you are building a reporting application or looking to add reporting capability to an existing application, look at JasperReports. Visit the JasperReports homepage for more information and download the latest version.
IT315发表的文档,均来自于相关|站公开发表的内容,如果(zhn)认为本站发表的文章늊了?zhn)的著作权Q请?qing)时与本站取得联p,本站在W一旉内删除。如果?zhn)有好的文章也可以通过Email提供l我们,如果有问题可以在留言板提出?/font> |
客户端:(x)
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.io.BufferedReader;
import java.io.*;
import java.lang.Thread;
import java.nio.charset.*;
import java.nio.charset.CharsetDecoder;
public class ChatClient{
private InetSocketAddress address = new InetSocketAddress("localhost",13);
private SocketChannel client = null;
private String user = null;
private String pass = null;
private BufferedReader in = null;
private Thread t = null;
public ChatClient(){
try{
client = SocketChannel.open();
System.out.println("connecting...");
client.connect(address);
System.out.println("connected with "+address.getHostName());
client.configureBlocking(false);
}catch(IOException ex){
ex.printStackTrace();
System.exit(-1);
}
this.start();
}
public void start(){
this.receiveMessage();
this.sendMessage();
}
public void sendMessage(){
try{
in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Input the Info then check it out on the server");
System.out.print("Your Name:");
user = in.readLine();
System.out.println("Password:");
pass = in.readLine();
ByteBuffer buffer = ByteBuffer.allocate(50);
String message= new String("LOGIN:"+user+"&"+pass);
buffer = ByteBuffer.wrap(message.getBytes());
while(buffer.hasRemaining()&client.write(buffer)!=-1);
System.out.println(message+" has been send");
buffer.flip();
Charset charset = Charset.forName("gb2312");
CharsetDecoder decoder = charset.newDecoder();
CharBuffer charBuffer = decoder.decode(buffer);
//System.out.println("receive:"+charBuffer+" length:"+charBuffer.limit());
}catch(IOException ex){
ex.printStackTrace();
}
this.waitFor(2000);
System.out.println("WELCOME TO THE KING 'S CHAT ROOM!");
System.out.println("Input the Info(exit is to leave out)");
while(true){
System.out.print(">");
ByteBuffer buffer = ByteBuffer.allocate(100);
in = new BufferedReader(new InputStreamReader(System.in));
try{
String read=in.readLine();
if(read.equals("exit")){
break;
}
String message1="SENTO:"+read;
buffer = ByteBuffer.wrap(message1.getBytes());
// buffer.flip();
System.out.println("before");
while(buffer.hasRemaining()&client.write(buffer)!=-1);
// buffer.flip();
System.out.println(message1+" has been send");
this.waitFor(500);
}catch(IOException ex){
ex.printStackTrace();
}
}
System.out.println("Welcome to use this soft!---King");
System.exit(-1);
}
public void waitFor(long time){
try{
Thread.sleep(time);
}catch(Exception ex){
ex.printStackTrace();
}
}
public void receiveMessage(){
t=new ReceiveThread(client);
t.start();
}
public static void main(String[]args){
ChatClient cc=new ChatClient();
}
class ReceiveThread extends Thread{
SocketChannel client =null;
ByteBuffer buffer=ByteBuffer.allocate(50);
private boolean val=true;
public ReceiveThread(SocketChannel client){
this.client = client;
}
public void run(){
while(val){
try{
while (client.read(buffer) > 0){
buffer.flip();
String result = decode(buffer);
System.out.println(">(back)"+result);
buffer.flip();
}
}catch(IOException ex){
ex.printStackTrace();
return;
}
}
}
}
public String decode(ByteBuffer buffer){
Charset charset=null;
CharsetDecoder decoder=null;
CharBuffer charBuffer=null;
try{
charset= Charset.forName("gb2312");
decoder= charset.newDecoder();
charBuffer= decoder.decode(buffer);
return charBuffer.toString();
}catch(Exception ex){
ex.printStackTrace();
return "";
}
}
}注意Q可以多个客戯行交,E序要求输入验证信息Q但׃旉原因后台我都以合法用L(fng)予回?/p>
服务端:(x)import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.net.ServerSocket;
import java.net.InetSocketAddress;
import java.nio.channels.Selector;
import java.nio.channels.SelectionKey;
import java.io.IOException;
import java.util.Iterator;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.nio.charset.*;
import java.nio.*;
public class ChatServer {
private int port = 13;
private Selector selector;
private ServerSocketChannel ssc;
private ServerSocket server;
private InetSocketAddress address;
private ArrayList connectKey=new ArrayList();
public ChatServer(){
//initServer
try{
ssc=ServerSocketChannel.open();
server=ssc.socket();
address = new InetSocketAddress(port);
server.bind(address);
selector=Selector.open();
ssc.configureBlocking(false);
ssc.register(selector,SelectionKey.OP_ACCEPT);
System.out.println("============================================================");
System.out.println("= =");
System.out.println("= =");
System.out.println("= 水底沙聊天室Qversion1.0 =");
System.out.println("= =");
System.out.println("= QQ:247095340(交流) =");
System.out.println("============================================================");
System.out.println("Listening the port 13...");
}catch(IOException ex){
ex.printStackTrace();
System.exit(-1);
}
}
public void startServer() throws IOException{
while(true){
int i=selector.select();
//System.out.print(i);
Iterator keys = selector.selectedKeys().iterator();
while(keys.hasNext()){
SelectionKey key = (SelectionKey)keys.next();
keys.remove();
try{
if(key.isAcceptable()){
ServerSocketChannel ssc=(ServerSocketChannel)key.channel();
SocketChannel channel = ssc.accept();//return null if there's no request
System.out.println(channel+" has accepted");
channel.configureBlocking(false);
SelectionKey clientKey=channel.register(selector,SelectionKey.OP_READ);
}//else
if(key.isWritable()){
SocketChannel channel = (SocketChannel)key.channel();
ByteBuffer buffer = (ByteBuffer)key.attachment();
if(buffer!=null){
key.attach(null);//avoid the return twice
//check info:the login or the message
//buffer.flip();
String checkBuffer = this.decode(buffer);
System.out.println("write:"+checkBuffer);
if(checkBuffer.equals("LOGIN:OK")){
//return LOGIN:OK then add into the connectKey array!
System.out.println("ok"+buffer);
buffer.flip();
//while(buffer.hasRemaining()&channel.write(buffer)!=-1);
channel.write(buffer);
key.interestOps(SelectionKey.OP_READ|SelectionKey.OP_WRITE);
connectKey.add(key);//add to the connectKey array
System.out.println("here");
}else if(checkBuffer.equals("LOGIN:ERROR")){
//return LOGIN:ERROR the client should close the channel
//warning:method:key.channel();
//Returns the channel for which this key was created.
// This method will continue to return the channel even after the key is cancelled.
while(buffer.hasRemaining()&channel.write(buffer)!=-1);
key.cancel();
}else //if(checkBuffer.indexOf("SENTO:")!=-1){
{
//return the message to everyone
// while(buffer.hasRemaining()&channel.write(buffer)!=-1);
System.out.println("sento"+buffer);
buffer.flip();
channel.write(buffer);
System.out.println("send over");
}
}
}//else
if(key.isReadable()){
SocketChannel channel = (SocketChannel)key.channel();
ByteBuffer buffer=ByteBuffer.allocate(50);
System.out.println("read...");
channel.read(buffer);
buffer.flip();
String checkBuffer = this.decode(buffer);
System.out.println("read:"+checkBuffer);
//while(buffer.hasRemaining()&&channel.read(buffer)!=-1);
//check the buffer
//buffer.flip();
//String checkBuffer = this.decode(buffer);
// System.out.println("read:"+checkBuffer);
if(checkBuffer.startsWith("LOGIN:")){
//get info of the user & pass then check for it,return feedback!
//the format is LOGIN:user&pass
int p1=checkBuffer.length();
int p2=checkBuffer.indexOf("&");
String user=checkBuffer.substring(6,p2);
String pass=checkBuffer.substring(p2+1,p1);
System.out.println(user+pass);
//todo check from the database!!!
//assume the user is legal
ByteBuffer feedback = ByteBuffer.allocate(20);
feedback=ByteBuffer.wrap("LOGIN:OK".getBytes());
key.interestOps(SelectionKey.OP_WRITE);
key.attach(feedback);
}else if(checkBuffer.startsWith("SENTO:")){
String message = checkBuffer.substring(6);
System.out.println("sentto:"+message);
ByteBuffer buffer1 = ByteBuffer.allocate(50);
buffer1=ByteBuffer.wrap(message.getBytes());
Iterator it = connectKey.iterator();
//key.interestOps(SelectionKey.OP_WRITE);
while(it.hasNext()){
((SelectionKey)it.next()).attach(buffer1.duplicate());
}
System.out.println("here1");
//for(int i=0;i<connectKey.add.;i++){
//connectKey[i].attach(buffer.duplicate());
//}
}
}
}catch(IOException ex){
key.cancel();
//System.exit(-1);
try{
key.channel().close();
}catch(IOException cex){
}
}
}
}
}
public String decode(ByteBuffer buffer){
Charset charset=null;
CharsetDecoder decoder=null;
CharBuffer charBuffer=null;
try{
charset= Charset.forName("gb2312");
decoder= charset.newDecoder();
charBuffer= decoder.decode(buffer);
return charBuffer.toString();
}catch(Exception ex){
ex.printStackTrace();
return "";
}
}
public static void main(String []args){
ChatServer cs = new ChatServer();
try{
cs.startServer();
}catch(IOException ex){
ex.printStackTrace();
System.exit(-1);
}
}
}注意Q假如客户强制登出服务端时候,服务器里面的d用户列表q是保存他注册的SelectionKey地址Q这是存在问题,其实解决很简单,在对通道q行写入时候,如果通道已经被关闭的话,可以用try/catch语句q行处理
上面是ȝE序Q其实之前我都是用阻塞socketd成这cd作的Q由于在用swtZ实现时候遇到很多swtU程问题Q后期我?x)以GUI界面׃nl大Ӟ当然自己也在不断学习(fn)中!King
Field Name | Allowed Values | Allowed Special Characters | ||
---|---|---|---|---|
Seconds
|
0-59
|
, - * /
|
||
Minutes
|
0-59
|
, - * /
|
||
Hours
|
0-23
|
, - * /
|
||
Day-of-month
|
1-31
|
, - * ? / L W C
|
||
Month
|
1-12 or JAN-DEC
|
, - * /
|
||
Day-of-Week
|
1-7 or SUN-SAT
|
, - * ? / L #
|
||
Year (Optional)
|
empty, 1970-2099
|
, - * /
|
The '*' character is used to specify all values. For example, "*" in the minute field means "every minute".
The '?' character is allowed for the day-of-month and day-of-week fields. It is used to specify 'no specific value'. This is useful when you need to specify something in one of the two fileds, but not the other.
The '-' character is used to specify ranges For example "10-12" in the hour field means "the hours 10, 11 and 12".
The ',' character is used to specify additional values. For example "MON,WED,FRI" in the day-of-week field means "the days Monday, Wednesday, and Friday".
The '/' character is used to specify increments. For example "0/15" in the seconds field means "the seconds 0, 15, 30, and 45". And "5/15" in the seconds field means "the seconds 5, 20, 35, and 50". Specifying '*' before the '/' is equivalent to specifying 0 is the value to start with. Essentially, for each field in the expression, there is a set of numbers that can be turned on or off. For seconds and minutes, the numbers range from 0 to 59. For hours 0 to 23, for days of the month 0 to 31, and for months 1 to 12. The "/" character simply helps you turn on every "nth" value in the given set. Thus "7/6" in the month field only turns on month "7", it does NOT mean every 6th month, please note that subtlety.
The 'L' character is allowed for the day-of-month and day-of-week fields. This character is short-hand for "last", but it has different meaning in each of the two fields. For example, the value "L" in the day-of-month field means "the last day of the month" - day 31 for January, day 28 for February on non-leap years. If used in the day-of-week field by itself, it simply means "7" or "SAT". But if used in the day-of-week field after another value, it means "the last xxx day of the month" - for example "6L" means "the last friday of the month". When using the 'L' option, it is important not to specify lists, or ranges of values, as you'll get confusing results.
The 'W' character is allowed for the day-of-month field. This character is used to specify the weekday (Monday-Friday) nearest the given day. As an example, if you were to specify "15W" as the value for the day-of-month field, the meaning is: "the nearest weekday to the 15th of the month". So if the 15th is a Saturday, the trigger will fire on Friday the 14th. If the 15th is a Sunday, the trigger will fire on Monday the 16th. If the 15th is a Tuesday, then it will fire on Tuesday the 15th. However if you specify "1W" as the value for day-of-month, and the 1st is a Saturday, the trigger will fire on Monday the 3rd, as it will not 'jump' over the boundary of a month's days. The 'W' character can only be specified when the day-of-month is a single day, not a range or list of days.
The 'L' and 'W' characters can also be combined for the day-of-month expression to yield 'LW', which translates to "last weekday of the month".
The '#' character is allowed for the day-of-week field. This character is used to specify "the nth" XXX day of the month. For example, the value of "6#3" in the day-of-week field means the third Friday of the month (day 6 = Friday and "#3" = the 3rd one in the month). Other examples: "2#1" = the first Monday of the month and "4#5" = the fifth Wednesday of the month. Note that if you specify "#5" and there is not 5 of the given day-of-week in the month, then no firing will occur that month.
The legal characters and the names of months and days of the week are not case sensitive.