阅读(1248) (0)

UReport2 报表存储

2022-09-05 13:43:00 更新
UReport2教学视频http://pan.baidu.com/s/1boWTxF5,密码:98hj

报表存储目录配置

       在第二小节中,我们介绍如何搭建一个包含UReport2的项目,在运行项目后,我们发现在项目的WEB-INF目录有会自动生成了一个名为“ureportfiles”目录,这个目录是UReport2提供的默认的报表文件存储目录,也就是说默认情况下,UReport将在项目的WEB-INF/ureportfiles目录下存储设计好的报表文件。

默认报表存储目录如果您的项目在Eclipse的开发环境运行时,采用的是jetty(比如run-jetty-run插件),那么就可以在项目的WEB-INF目录下发现一个名为“ureportfiles”目录。但如果你采用tomcat运行项目,那么在WEB-INF目录下就没有一个名为“ureportfiles”目录,原因是在Eclipse中运行tomcat,tomcat需要创建一个临时的工作目录(该目录一般位于workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\下),所以采用tomcat运行项目,则需要到这个临时的工作目录下找到对应的项目,再到这个项目的WEB-INF目录下找到对应的“ureportfiles”目录。

运行我们搭建好的项目,打开报表设计器,点击工具栏上的保存按钮(),选择“保存”,可以看到如下图所示的弹出窗口:

save-dialog\

  在这个窗口,我们只要输入报表名称,同时再选择报表的存储目的地就,可以保存当前报表文件。可以看到,UReport2默认给我们提供的存储目的地是“服务器文件系统 ”,实际上就是我们项目中WEB-INF目录下的“ureportfiles”目录,这个目录是系统默认自动生成的,如果需要我们可以添加一个属性来更改这个目录位置。

       在我们项目的WEB-INF目录下创建一个名为config.properties,打开位于WEB-INF下名为context.xml的spring配置文件,在其中添加如下Bean以加载这个config.properties文件(如果我们的项目中已有自己的Properties文件,那么直接在这个Properties文件中配置即可)。

<bean id="propertyConfigurer" parent="ureport.props">
    <property name="location">
        <value>/WEB-INF/config.properties</value>
    </property>
</bean>
说明上面的Bean配置,实际上就是一个标准的org.springframework.beans.factory.config.PropertyPlaceholderConfigurer类配置,我们知道通过配置PropertyPlaceholderConfigurer,可以实现加载Spring外部properties的作用,所以如果您的项目中已配置了PropertyPlaceholderConfigurer类,那么直接在这个类对应的properties文件中添加对应的UReport2属性即可,而不需要额外配置config.properties文件。

       打开config.properties文件,在其中添加名为“ureport.fileStoreDir”的属性,该属性的值用于定义UReport2中提供的默认基于文件系统的报表存储目录,比如定义该属性为下面样式:

属性值定义示例ureport.fileStoreDir=D:/ureportfiles

       表示在D盘根下名为ureportfiles的目录中存储报表文件,需要注意的是,这里指定特定目录时,一定要保存这个目录已存在,否则将不会被采用,比如上面的D盘下名为ureportfiles的目录,就需要我们预先创建好。

自定义报表存储器

       UReport2默认提供的名为“服务器文件系统”的报表存储机制,实际上是实现了UReport2提供的com.bstek.ureport.provider.report.ReportProvider接口,该接口源码如下:

package com.bstek.ureport.provider.report;
import java.io.InputStream;
import java.util.List;
/**
 * @author Jacky.gao
 * @since 2016年12月4日
 */
public interface ReportProvider {
    /**
     * 根据报表名加载报表文件
     * @param file 报表名称
     * @return 返回的InputStream
     */
    InputStream loadReport(String file);
    /**
     * 根据报表名,删除指定的报表文件
     * @param file 报表名称
     */
    void deleteReport(String file);
    /**
     * 获取所有的报表文件
     * @return 返回报表文件列表
     */
    List<ReportFile> getReportFiles();
    /**
     * 保存报表文件
     * @param file 报表名称
     * @param content 报表的XML内容
     */
    void saveReport(String file,String content);
    /**
     * @return 返回存储器名称
     */
    String getName();
    /**
     * @return 返回是否禁用
     */
    boolean disabled();
    /**
     * @return 返回报表文件名前缀
     */
    String getPrefix();
}

       实现了ReportProvider接口后,只需要将实现类配置到Spring中,让其成为一个标准的Spring Bean,这样UReport2就会检测到它而将其加载。下面是UReport2默认提供的名为“服务器文件系统”的报表存储器源码:

package com.bstek.ureport.provider.report.file;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.servlet.ServletContext;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.WebApplicationContext;
import com.bstek.ureport.exception.ReportException;
import com.bstek.ureport.provider.report.ReportFile;
import com.bstek.ureport.provider.report.ReportProvider;
/**
 * @author Jacky.gao
 * @since 2017年2月11日
 */
public class FileReportProvider implements ReportProvider,ApplicationContextAware{
    private String prefix="file:";
    private String fileStoreDir;
    private boolean disabled;
    @Override
    public InputStream loadReport(String file) {
        if(file.startsWith(prefix)){
            file=file.substring(prefix.length(),file.length());
        }
        String fullPath=fileStoreDir+"/"+file;
        try {
            return new FileInputStream(fullPath);
        } catch (FileNotFoundException e) {
            throw new ReportException(e);
        }
    }
     
    @Override
    public void deleteReport(String file) {
        if(file.startsWith(prefix)){
            file=file.substring(prefix.length(),file.length());
        }
        String fullPath=fileStoreDir+"/"+file;
        File f=new File(fullPath);
        if(f.exists()){
            f.delete();
        }
    }
    @Override
    public List<ReportFile> getReportFiles() {
        File file=new File(fileStoreDir);
        List<ReportFile> list=new ArrayList<ReportFile>();
        for(File f:file.listFiles()){
            Calendar calendar=Calendar.getInstance();
            calendar.setTimeInMillis(f.lastModified());
            list.add(new ReportFile(f.getName(),calendar.getTime()));
        }
        Collections.sort(list, new Comparator<ReportFile>(){
            @Override
            public int compare(ReportFile f1, ReportFile f2) {
                return f2.getUpdateDate().compareTo(f1.getUpdateDate());
            }
        });
        return list;
    }
    @Override
    public String getName() {
        return "服务器文件系统";
    }
     
    @Override
    public void saveReport(String file,String content) {
        if(file.startsWith(prefix)){
            file=file.substring(prefix.length(),file.length());
        }
        String fullPath=fileStoreDir+"/"+file;
        FileOutputStream outStream=null;
        try{
            outStream=new FileOutputStream(new File(fullPath));
            IOUtils.write(content, outStream,"utf-8");
        }catch(Exception ex){
            throw new ReportException(ex);
        }finally{
            if(outStream!=null){
                try {
                    outStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
         
    }
    @Override
    public boolean disabled() {
        return disabled;
    }
     
    public void setDisabled(boolean disabled) {
        this.disabled = disabled;
    }
     
    public void setFileStoreDir(String fileStoreDir) {
        this.fileStoreDir = fileStoreDir;
    }
     
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        File file=new File(fileStoreDir);
        if(file.exists()){
            return;
        }
        if(applicationContext instanceof WebApplicationContext){
            WebApplicationContext context=(WebApplicationContext)applicationContext;
            ServletContext servletContext=context.getServletContext();
            String basePath=servletContext.getRealPath("/");
            fileStoreDir=basePath+fileStoreDir;
            file=new File(fileStoreDir);
            if(!file.exists()){
                file.mkdirs();
            }
        }
    }
    @Override
    public String getPrefix() {
        return prefix;
    }
}
禁用系统提供的默认报表存储器 如果我们定义了自己的报表存储器,同时又不想再使用系统默认提供的”服务器文件系统“的报表存储器,那么我们只需要在之前介绍的config.properties文件中添加一个名为ureport.disableFileProvider属性,将其值设置成true即可。

       通过上面的介绍,可以看到,通过实现ReportProvider接口,我们可以很容易的开发出其它类型的报表存储器,比如开发一个新的报表存储器将报表文件存储到数据库、FTP等。