历史版本12 :从数据库读取报表 返回文档
编辑时间:
内容长度:图片数:目录数:
修改原因:
1. 描述编辑
上一节中我们已经将cpt模板保存入库了,当需要访问报表的时候,我们便可以从数据库中根据报表名称取出报表,不需要再保存为cpt模板,可以直接转为网络报表,在Web浏览器中进行访问。例如在浏览器中输入:
http://localhost:8075/webroot/decision/view/report?viewlet=com.fr.demo.ReadFromDatabase&cptname=GettingStarted.cpt,就可以读出上一节中保存的模板了。
若您修改参数cptname的值,就可以查看数据库中不同的报表。
frm模板保存入库方式与cpt一样,但要注意frm模板大小,模板内存过大会有无法入库的情况发生。
2. 实现步骤编辑
示例1.cpt模板
编写读取模板程序
新建类ReadFromDatabase,继承com.fr.web.Reportlet抽象类,并实现public Report createReport(ReportletRequest reportletRequest)方法。完整代码如下
package com.fr.demo;
import com.fr.base.operator.common.CommonOperator;
import com.fr.chart.activator.ChartBaseActivator;
import com.fr.config.activator.BaseDBActivator;
import com.fr.config.activator.ConfigurationActivator;
import com.fr.data.impl.config.activator.RestrictionActivator;
import com.fr.env.operator.CommonOperatorImpl;
import com.fr.main.TemplateWorkBook;
import com.fr.main.impl.WorkBook;
import com.fr.module.Module;
import com.fr.module.tool.ActivatorToolBox;
import com.fr.report.ReportActivator;
import com.fr.report.module.ReportBaseActivator;
import com.fr.store.StateServerActivator;
import com.fr.web.core.Reportlet;
import com.fr.web.request.ReportletRequest;
import com.fr.workspace.simple.SimpleWork;
import com.fr.log.FineLoggerFactory;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Map;
public class ReadFromDatabase extends Reportlet {
public TemplateWorkBook createReport(ReportletRequest reportletRequest) {
WorkBook workbook = new WorkBook();
String name = reportletRequest.getParameter("cptname").toString();
try {
// 定义数据连接(根据你实际数据库信息进行修改)
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://review.finedevelop.com:3306/susie";
String user = "root";
String pass = "ilovejava";
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, user, pass);
// 从数据库中读模板
String sql = "select cpt from report where cptname = '" + name
+ "'";
Statement smt = conn.createStatement();
ResultSet rs = smt.executeQuery(sql);
while (rs.next()) {
Blob blob = rs.getBlob(1); // 取第一列的值,即cpt列
FineLoggerFactory.getLogger().info(blob.toString());
InputStream ins = blob.getBinaryStream();
workbook.readStream(ins);
}
} catch (Exception e) {
e.printStackTrace();
}
return workbook;
}
@Override
public void setParameterMap(Map arg0) {
// TODO Auto-generated method stub
}
@Override
public void setTplPath(String arg0) {
// TODO Auto-generated method stub
}
}
发布并访问
编译源文件,将编译后的ReadFromDatabase.class类放至应用目录WEB-INF\classes\com\fr\demo下,启动内置jetty服务器,输入地址http://localhost:8075/webroot/decision/view/report?viewlet=com.fr.demo.ReadFromDatabase&cptname=GettingStarted.cpt,就可以看到报表结果了。
示例2. frm模板
编写读取模板程序
启动eclipse,新建类CityrayFormlet,继承com.fr.web.Reportlet抽象类,并实现public Report createReport(ReportletRequest reportletRequest)方法。完整代码如下package com.fr.demo;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.fr.base.FRContext;
import com.fr.dav.LocalEnv;
import com.fr.form.main.Form;
import com.fr.web.weblet.Formlet;
public class CityrayFormlet extends Formlet {
public CityrayFormlet(){
}
@SuppressWarnings("rawtypes")
@Override
public void setParameterMap(Map arg0) {
// TODO Auto-generated method stub
}
@Override
protected Form createForm(HttpServletRequest paramFormletRequest) throws Exception {
String envpath = "E:\\FineReport_10.0\\webapps\\webroot\\WEB-INF";
FRContext.setCurrentEnv(new LocalEnv(envpath));
Form form = new Form();
try{
String name = paramFormletRequest.getParameter("cptname").toString();
try {
// 定义数据连接
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://env.finedevelop.com:55703/mysql";
String user = "root";
String pass = "123456";
Class.forName(driver);
java.sql.Connection conn = DriverManager.getConnection(url, user, pass);
// 从数据库中读模板
String sql = "select cpt from report where cptname = '" + name
+ "'";
Statement smt = conn.createStatement();
ResultSet rs = smt.executeQuery(sql);
while (rs.next()) {
Blob blob = rs.getBlob(1); // 取第一列的值,即cpt列
FRContext.getLogger().info(blob.toString());
InputStream ins = blob.getBinaryStream();
form.readStream(ins);
}
} catch (Exception e) {
e.printStackTrace();
}
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e);
}
return form;
}
}
注:报表软件路径与数据库连接以个人使用情况为准。
发布并访问
编译源文件,将编译后的CityrayFormlet.class类放至应用目录WEB-INF\classes\com\fr\demo下,启动内置jetty服务器,输入地址http://localhost:8075/webroot/decision/view/form?viewlet=com.fr.demo.CityrayFormlet&cptname=form.frm,就可以看到报表结果了。
3. 解决导出文件同名问题编辑
3.1 问题描述描述
经过上述步骤可以实现读取数据库中模板的目的,但是使用内置的导出的时候,会发现导出的文件都是同名的,都是以com.fr.demo为名字的,这样会造成导出文件的名字都相同,造成文件混乱。
3.2 解决方案
通过修改workbook对象的title实现,并且以模板名字name参数去命名模板,多引用了一个import com.fr.web.attr.ReportWebAttr;
新添加的代码在return workbook之前
ReportWebAttr webattr= workbook.getReportWebAttr();
webattr.setTitle(name);
workbook.setReportWebAttr(webattr);
完整代码如下:
package com.fr.demo;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Map;
import com.fr.web.attr.ReportWebAttr;
import com.fr.base.Env;
import com.fr.base.FRContext;
import com.fr.dav.LocalEnv;
import com.fr.main.TemplateWorkBook;
import com.fr.main.impl.WorkBook;
import com.fr.web.core.Reportlet;
import com.fr.web.request.ReportletRequest;
public class ReadFromDatabase extends Reportlet {
public TemplateWorkBook createReport(ReportletRequest reportletRequest) {
// 定义报表运行环境,才能执行报表
String envpath = "D:\\FineReport_10.0\\webapps\\webroot\\WEB-INF";
FRContext.setCurrentEnv(new LocalEnv(envpath));
WorkBook workbook = new WorkBook();
String name = reportletRequest.getParameter("cptname").toString();
try {
// 定义数据连接
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://env.finedevelop.com:55703/yourdatebase";
String user = "yourusername";
String pass = "yourpassword";
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, user, pass);
// 从数据库中读模板
String sql = "select cpt from report where cptname = '" + name
+ "'";
Statement smt = conn.createStatement();
ResultSet rs = smt.executeQuery(sql);
while (rs.next()) {
Blob blob = rs.getBlob(1); // 取第一列的值,即cpt列
FRContext.getLogger().info(blob.toString());
InputStream ins = blob.getBinaryStream();
workbook.readStream(ins);
}
} catch (Exception e) {
e.printStackTrace();
}
ReportWebAttr webattr= workbook.getReportWebAttr();
webattr.setTitle(name);
workbook.setReportWebAttr(webattr);
return workbook;
}
@Override
public void setParameterMap(Map arg0) {
// TODO Auto-generated method stub
}
@Override
public void setTplPath(String arg0) {
// TODO Auto-generated method stub
}
}
3.3 效果展现
启动内置jetty服务器,输入地址http://localhost:8075/webroot/decision/view/report?viewlet=com.fr.demo.ReadFromDatabase&cptname=GettingStarted.cpt,输出为PDF格式,可以看到文件名变为GettingStarted.pdf: