一.UReport2概述:

        UReport2是一款基于架构在Spring之上纯Java的高性能报表引擎,通过送代单元格可以实现任意复杂的中国式报表。相比UReport1UReport2重写了全部代码,弥补了UReport1在功能及性能上的各种不足。在UReport2中,提供了全新的基于网页的报表设计器,可以在Chrome、Firefox、Edge等各种主流浏览器运行 (E浏览器除外) 。使用UReport2打开浏览器即可完成各种复杂报表的设计制作。

 文档视频教程地址:

  1. BSDN WIKI: http://wiki.bsdn.org/display/UR/ureport2+Home
  2. w3cschool: https://www.w3cschool.cn/ureport

二.安装配置

1.pom.xml文件中引入ureport2的依赖

<!-- ureport2报表 -->
<dependency>
	<groupId>com.bstek.ureport</groupId>
	<artifactId>ureport2-console</artifactId>
	<version>2.2.9</version>
</dependency>

2.启动类指定xml文件,注册Bean

@ImportResource("classpath:ureport-console-context.xml")
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class RuoYiApplication {
    public static void main(String[] args) {
        SpringApplication.run(RuoYiApplication.class, args);
        System.out.println("(♥◠‿◠)ノ゙  若依启动成功   ლ(´ڡ`ლ)゙  \n" +
                " .-------.       ____     __        \n" +
                " |  _ _   \\      \\   \\   /  /    \n" +
                " | ( ' )  |       \\  _. /  '       \n" +
                " |(_ o _) /        _( )_ .'         \n" +
                " | (_,_).' __  ___(_ o _)'          \n" +
                " |  |\\ \\  |  ||   |(_,_)'         \n" +
                " |  | \\ `'   /|   `-'  /           \n" +
                " |  |  \\    /  \\      /           \n" +
                " ''-'   `'-'    `-..-'              ");
    }

@Bean
    public ServletRegistrationBean buildUReportServlet(){
        return new ServletRegistrationBean(new UReportServlet(),"/ureport/*");
    }

3.根据@ImportResource("classpath:ureport-console-context.xml")指定,创建context.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 
    <import resource="classpath:ureport-console-context.xml" />
    <bean id="propertyConfigurer" parent="ureport.props">
        <property name="location">
            <value>classpath:config.properties</value>
        </property>
    </bean>
</beans>

若依框架配置层级目录:ruoyi-admin\src\main\resources\context.xml

如果为springboot框架整合,放在resources下即可。

4.根据context.xml指定位置创建ureport配置文件。名为config.properties

ureport.disableHttpSessionReportCache=false
ureport.disableFileProvider=true
ureport.fileStoreDir=/WEB-INF/ureportfiles
ureport.debug=true

5.在ruoyi-framework模块SecurityConfig.java类中加入运行匿名访问,将拦截排除

 此时后端配置完成。启动项目,下图为启动成功。

 访问http://localhost:8080/ureport/designer即可。 

 三.前端配置

1.在ruoyi-ui/vue.config.js添加下列代码

'/ureport': {
    target: 'http://localhost:8080',
    ws:false,
    changeOrigin: true,
    pathRewrite: {
        '^/ureport': '/ureport'
    }
}

 位置如下

2.在views目录下创建ureport/designer,新增index.vue文件。

层级目录:src\views\ureport\designer\index.vue

<template>
  <div v-loading="loading" :style="'height:'+ height">
    <iframe :src="src" frameborder="no" style="width: 100%;height: 100%" scrolling="auto"/>
  </div>
</template>
<script>
  export default {
    name: "Ureport",
    data() {
      return {
        src: "/ureport/designer",
        height: document.documentElement.clientHeight - 94.5 + "px;",
        loading: true
      };
    },
    mounted: function() {
      setTimeout(() => {
        this.loading = false;
      }, 230);
      const that = this;
      window.onresize = function temp() {
        that.height = document.documentElement.clientHeight - 94.5 + "px;";
      };
    }
  };
</script>

3.在若依系统新增目录

4.新增菜单

启动项目后可看到

此时可制作报表。 

四.制作报表并保存至数据库

制作报表后,将模板保存至数据库。

首先创建数据库表。

CREATE TABLE `ureport_file_tbl` (
  `id_` int(11) NOT NULL AUTO_INCREMENT,
  `name_` varchar(100) NOT NULL,
  `content_` mediumblob,
  `create_time_` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time_` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id_`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4;

重写ureport中crud的接口方法。创建类MySQLProvider。前缀名为指定前缀,在做模板的crud时,调用到ureport底层代码,会根据前缀判断进入的方法。

package com.ruoyi.module.ureport;

 
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.bstek.ureport.provider.report.ReportFile;
import com.bstek.ureport.provider.report.ReportProvider;
import com.ruoyi.module.domain.UreportFileEntity;
import com.ruoyi.module.mapper.UreportFileMapper;
 
 
/**
 * Mysql 报表存储
 * @author hanshiyi
 * @version 2023年5月9日
 *
 */
 
@Component
// 该注解可以利用其 prefix属性值 + 类的属性名 在yml中配置属性值
// @ConfigurationProperties(prefix = "ureport.mysql.provider") 
public class MySQLProvider implements ReportProvider{
	private static final String NAME = "mysql-provider";
	
        // 特定前缀,ureport底层会调用 getPrefix 方法来获取报表操作的Provier类
	private String prefix = "mysql:";

	// 是否禁用
	private boolean disabled; 

	@Autowired
	private UreportFileMapper ureportFileMapper;

	@Override
	public InputStream loadReport(String file)
	{
		UreportFileEntity ureportFileEntity = ureportFileMapper.queryUreportFileEntityByName(getCorrectName(file));
		byte[] content = ureportFileEntity.getContent();
		ByteArrayInputStream inputStream = new ByteArrayInputStream(content);
		return inputStream;
	}

	@Override
	public void deleteReport(String file) 
	{
		ureportFileMapper.deleteReportFileByName(getCorrectName(file));
	}

	@Override
	public List<ReportFile> getReportFiles() 
	{
		List<UreportFileEntity> list = ureportFileMapper.queryReportFileList();
		List<ReportFile> reportList = new ArrayList<>();
		for (UreportFileEntity ureportFileEntity : list) {
			reportList.add(new ReportFile(ureportFileEntity.getName(), ureportFileEntity.getUpdateTime()));
		}
		return reportList;
	}

	@Override
	public void saveReport(String file, String content) 
	{
		file = getCorrectName(file);
		UreportFileEntity ureportFileEntity = ureportFileMapper.queryUreportFileEntityByName(file);
		Date currentDate = new Date();
		byte[] cString = null;
		try {
				cString = content.getBytes("utf-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		if(ureportFileEntity == null){
			ureportFileEntity = new UreportFileEntity();
			ureportFileEntity.setName(file);
			ureportFileEntity.setContent(cString);
			ureportFileEntity.setCreateTime(currentDate);
			ureportFileEntity.setUpdateTime(currentDate);
			ureportFileMapper.insertReportFile(ureportFileEntity);
		}else{
			ureportFileEntity.setContent(cString);
   			ureportFileEntity.setUpdateTime(currentDate);
			ureportFileMapper.updateReportFile(ureportFileEntity);
		}
	}

	@Override
	public String getName() {
		return NAME;
	}
 
	@Override
	public boolean disabled() {
		return disabled;
	}
 
	@Override
	public String getPrefix() {
		return prefix;
	}

	/**
	 * 获取没有前缀的文件名
	 * @param name
	 * @return
	 */
	private String getCorrectName(String name)
	{
		if(name.startsWith(prefix))
		{
			name = name.substring(prefix.length(), name.length());
		}
		return name; 
	}
}

重写方法后,重启项目。保存时会看到

 mysql-provider为数据库保存地址。服务器文件系统为ureport默认保存地址。选择服务器文件系统可保存至系统内,但需要创建保存路径。输入文件名,选择mysql-provider后点击保存,即可保存到数据库中。此处可看到源码UReport2 报表存储与数据源配置_w3cschool

五.与业务结合并导出excel文件(从数据库中获取文件)

保存至数据库后,可以看到保存的文件。

导出excel文件需要创建一个导出excel的工具类。

import com.bstek.ureport.export.ExportConfigureImpl;
import com.bstek.ureport.export.ExportManager;
 
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Map;
import java.util.Objects;
/**
导出excel、pdf
 */
public class ExportUtils {
    public static void exportPdf(ExportManager exportManager, String sourcePath, String targetPath, Map<String, Object> param) throws Exception {
        try {
            OutputStream fos = new FileOutputStream(targetPath);
            try {
                ExportConfigureImpl exportConfigure = new ExportConfigureImpl(sourcePath, param, fos);
                exportManager.exportPdf(exportConfigure);
            } catch (Exception e) {
                throw new Exception("exportPdf error", e);
            } finally {
                if (fos != null) {
                    try {
                        fos.close();
                    }catch(Exception e) {
                        throw new Exception("exportPdf error", e);
                    }
                }
            }
        } catch (Exception e) {
            throw new Exception("exportPdf error", e);
        }
    }
    public static void exportExcel(ExportManager exportManager, String sourcePath, String targetPath, Map<String, Object> param) throws Exception {
        try {
            OutputStream fos = new FileOutputStream(targetPath);
            try {
                String ext = targetPath.substring(targetPath.indexOf(".") + 1);
                ExportConfigureImpl exportConfigure = new ExportConfigureImpl(sourcePath, param, fos);
                if (Objects.equals(ext, "xls")) {
                    exportManager.exportExcel97(exportConfigure);
                } else {
                    if (!Objects.equals(ext, "xlsx")) {
                        throw new Exception("File name is not support!");
                    }
                    exportManager.exportExcel(exportConfigure);
                }
            } catch (Exception e) {
                throw new Exception("exportExcel error", e);
            } finally {
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (Exception e) {
                        throw new Exception("exportExcel error", e);
                    }
                }
            }
        } catch (Exception e) {
            throw new Exception("exportExcel error", e);
        }
    }
 
}

调用工具类方法

ExportUtils.exportExcel(exportManager,sourcePath,filePath,dataMap);

参数可在工具类中看到

第一个参数是调用导出方法的接口,自动注入即可。导出接口源码。

ExportManager接口源码。


import com.bstek.ureport.export.html.HtmlReport;
import java.util.Map;

public interface ExportManager {
   String BEAN_ID = "ureport.exportManager";

   HtmlReport exportHtml(String var1, String var2, Map<String, Object> var3);

   HtmlReport exportHtml(String var1, String var2, Map<String, Object> var3, int var4);

   void exportPdf(ExportConfigure var1);

   void exportExcel(ExportConfigure var1);

   void exportExcel97(ExportConfigure var1);

   void exportExcelWithPaging(ExportConfigure var1);

   void exportExcel97WithPaging(ExportConfigure var1);

   void exportExcelWithPagingSheet(ExportConfigure var1);

   void exportExcel97WithPagingSheet(ExportConfigure var1);

   void exportWord(ExportConfigure var1);
}

第二个参数sourcePath为String类型,此参数为你想导出模板的名称,对应数据库name的名称。

比如保存到数据库中模板的名称为测试导出模板.ureport.xml。

String sourcePath = "mysql:测试导出模板.ureport.xml";

mysql: 是名称前缀,与重写的MySQLProvider 类中prefix一致。为特定前缀,不写或者写file: 

前者会报错,后者不会进入到重写的MySQLProvider类中的方法,会进入ureport底层默认的查询服务器文件地址。此处重点~

第三个参数filePath为导出文件下载的地址,根据情况写即可。

String filePath = "D:/ureport/xxx.xlsx";

第四个参数dataMap存放写在模板中sql需要的参数。根据业务填写即可。

本文因将模板存储到项目中,部署到服务器后,导出一直报错,找不到模板位置,所以将模板修改至保存到数据库中调用。

Logo

快速构建 Web 应用程序

更多推荐