spring-boot整合ureport
创建项目相关配置
创建maven依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version> <!-- 此版本号,boot号 所有子类参考 -->
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
</dependency>
<dependency>
<groupId>com.bstek.ureport</groupId>
<artifactId>ureport2-console</artifactId>
<version>2.2.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
<!--end pageHelper-->
</dependencies>
<!-- 普通打包 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<mainClass>com.shir.test.Application</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
创建application.yml
server:
servlet:
context-path: /
port: 9020
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ureport?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&useLegacyDatetimeCode=false
username: root
password: root
resources:
static-locations: classpath:/,classpath:/static/
创建启动类SpringBootApplicationMain
package com.cn;
/**
* SpringBootApplication
*
* @author wangyq
* @create 2023/10/11
*/
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
/**
spring boot 启动类
@author wang
*/
@SpringBootApplication
public class SpringBootApplicationMain {
public static void main(String[] args) {
SpringApplication.run(SpringBootApplicationMain.class, args);
}
}
配置ureport可视化编辑界面
创建com.cn.report后在下面创建类
1.创建MyExportExcelServletAction
package com.cn.report ;
import com.bstek.ureport.build.ReportBuilder;
import com.bstek.ureport.console.cache.TempObjectCache;
import com.bstek.ureport.console.excel.ExportExcelServletAction;
import com.bstek.ureport.console.exception.ReportDesignException;
import com.bstek.ureport.definition.ReportDefinition;
import com.bstek.ureport.exception.ReportComputeException;
import com.bstek.ureport.export.ExportConfigure;
import com.bstek.ureport.export.ExportConfigureImpl;
import com.bstek.ureport.export.ExportManager;
import com.bstek.ureport.export.excel.high.ExcelProducer;
import com.bstek.ureport.model.Report;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Map;
/**
* 为解决ie下载文件中含有中文名时,文件名乱码的问题,
* 实现ureport的excel导出功能
* @author guoyka
* @version 1.0, 2019/11/7
*/
@Component(value = "ureport.myExportExcelServletAction")
public class MyExportExcelServletAction extends ExportExcelServletAction {
@Autowired
private ReportBuilder reportBuilder;
@Autowired
private ExportManager exportManager;
private ExcelProducer excelProducer = new ExcelProducer();
@Override
public void buildExcel(HttpServletRequest request, HttpServletResponse resp, boolean withPage, boolean withSheet) throws IOException {
String file = request.getParameter("_u");
file = this.decode(file);
if (StringUtils.isBlank(file)) {
throw new ReportComputeException("Report file can not be null.");
} else {
String fileName = request.getParameter("_n");
fileName = this.buildDownloadFileName(file, fileName, ".xlsx");
//判断是否是IE11
Boolean flag= request.getHeader("User-Agent").indexOf("like Gecko")>0;
if (request.getHeader("User-Agent").toLowerCase().indexOf("msie") >0||flag){
fileName = URLEncoder.encode(fileName, "UTF-8");//IE浏览器
}else {
//先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码,
//这个文件名称用于浏览器的下载框中自动显示的文件名
fileName = new String(fileName.replaceAll(" ", "").getBytes("UTF-8"), "ISO8859-1");
//firefox浏览器
//firefox浏览器User-Agent字符串:
//Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0
}
resp.setContentType("application/octet-stream;");
resp.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
Map<String, Object> parameters = this.buildParameters(request);
OutputStream outputStream = resp.getOutputStream();
if (file.equals("p")) {
ReportDefinition reportDefinition = (ReportDefinition) TempObjectCache.getObject("p");
if (reportDefinition == null) {
throw new ReportDesignException("Report data has expired,can not do export excel.");
}
Report report = this.reportBuilder.buildReport(reportDefinition, parameters);
if (withPage) {
this.excelProducer.produceWithPaging(report, outputStream);
} else if (withSheet) {
this.excelProducer.produceWithSheet(report, outputStream);
} else {
this.excelProducer.produce(report, outputStream);
}
} else {
ExportConfigure configure = new ExportConfigureImpl(file, parameters, outputStream);
if (withPage) {
this.exportManager.exportExcelWithPaging(configure);
} else if (withSheet) {
this.exportManager.exportExcelWithPagingSheet(configure);
} else {
this.exportManager.exportExcel(configure);
}
}
outputStream.flush();
outputStream.close();
}
}
@Override
public String url() {
return "/excelIE";
}
}
2.创建ReportConfig
package com.cn.report ;
import com.bstek.ureport.definition.datasource.BuildinDatasource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
@Configuration
@ImportResource("classpath:ureport-console-context.xml")
public class ReportConfig {
/**
* 进行注册Servlet
* 配置 UReport2 需要使用到的servlet
*/
@Bean
public ServletRegistrationBean buildUReportServlet() {
/**
* @param servlet
* @param urlMappings 值为“/ureport/*”的 urlMappings 是一定不能变的,否则系统将无法运行。
*/
return new ServletRegistrationBean(new MyReportServlet(), "/ureport/*");
}
@Component
@Slf4j
public static class MyDataSource implements BuildinDatasource {
@Autowired
private DataSource dataSource;
@Override
public String name() {
return "source";
}
@Override
public Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
log.error(e.getMessage() + "-" + e.getSQLState());
}
return null;
}
}
}
3.创建MyReportServlet
package com.cn.report ;
import com.bstek.ureport.console.RequestHolder;
import com.bstek.ureport.console.ServletAction;
import com.bstek.ureport.console.UReportServlet;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.WebApplicationContext;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class MyReportServlet extends UReportServlet {
private static final long serialVersionUID = 633049461276487971L;
private Map<String, ServletAction> actionMap = new HashMap<>();
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
WebApplicationContext applicationContext = getWebApplicationContext(config);
Collection<ServletAction> handlers = applicationContext.getBeansOfType(ServletAction.class).values();
for (ServletAction handler : handlers) {
String url = handler.url();
if (actionMap.containsKey(url)) {
throw new RuntimeException("Handler [" + url + "] already exist.");
}
actionMap.put(url, handler);
}
}
private void outContent(HttpServletResponse resp, String msg) throws IOException {
resp.setContentType("text/html");
PrintWriter pw = resp.getWriter();
pw.write("<html>");
pw.write("<header><title>UReport Console</title></header>");
pw.write("<body>");
pw.write(msg);
pw.write("</body>");
pw.write("</html>");
pw.flush();
pw.close();
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String path = req.getContextPath() + URL;
String uri = req.getRequestURI();
String targetUrl = uri.substring(path.length());
if (targetUrl.length() < 1) {
outContent(resp, "Welcome to use ureport,please specify target url.");
} else {
int slashPos = targetUrl.indexOf("/", 1);
if (slashPos > -1) {
targetUrl = targetUrl.substring(0, slashPos);
}
ServletAction targetHandler = actionMap.get(targetUrl);
if (targetHandler == null) {
this.outContent(resp, "Handler [" + targetUrl + "] not exist.");
} else {
RequestHolder.setRequest(req);
try {
targetHandler.execute(req, resp);
} catch (Exception ex) {
log.error("error---> {}", ex.getMessage());
throw new ServletException(ex);
} finally {
RequestHolder.clean();
}
}
}
}
}
可视化界面初步配置完成
此时访问网址:http://localhost:9020/ureport/designer可以看到ureport。但是此时只能保存报表到session中不能持久化保存。
持久化到服务器中
创建在report中创建reportFile包,
1.resources中创建config.properties
#配置文件系统对应的报表文件地址
ureport.fileStoreDir=./src/main/java/com/cn/report/reportFile/
# 是否禁用
ureport.disableFileProvider=false
ureport.debug=true
ureport.disableHttpSessionReportCache=false
# 配置ureport根路径
ureport.contextPath=/ureport
2.resources中创建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">
<!-- 创建context.xml是第六步,引入ureport2报表xml配置文件 -->
<import resource="classpath:ureport-console-context.xml" />
<bean id="propertyConfigurer" parent="ureport.props">
<property name="location">
<value>classpath:config.properties</value>
</property>
</bean>
</beans>
3.在report包中创建UreportConfig类
package com.cn.report;
import com.bstek.ureport.console.UReportServlet;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
/**
* UreportConfig
*
* @author wangyq
* @create 2023/10/11
*/
@ImportResource("classpath:context.xml")
@EnableAutoConfiguration
@Configuration
@ComponentScan(basePackages = "com.cn")
public class UreportConfig {
@Bean
public ServletRegistrationBean buildUreportServlet() {
return new ServletRegistrationBean(new UReportServlet(), "/ureport/*");
}
}
此时访问http://localhost:9020/ureport/designer保存报表即可存到本地
持久化到数据库中
1.创建数据库表结构
CREATE TABLE `t_report_tpl` (
`ID` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '',
`NAME` varchar(255) DEFAULT NULL,
`CONTENT` text,
`CREATE_DATE` datetime DEFAULT NULL,
`LAST_UPDATE` datetime DEFAULT NULL,
`display` varchar(100) DEFAULT NULL,
`status` char(1) DEFAULT NULL,
PRIMARY KEY (`ID`) USING BTREE,
KEY `name_index` (`NAME`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC;
2.创建实体类ReportTpl
package com.cn.pojo;
import com.bstek.ureport.provider.report.ReportFile;
import com.cn.report.RptUpdateSerializer;
import org.apache.ibatis.annotations.AutomapConstructor;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 报表模板,包装类,实现了一些定制化需求
* @author guoyka
* @version 1.0, 2019/6/20
*/
public class ReportTpl extends ReportFile implements Serializable{
private String id;
/*报表名称*/
private String name;
/*报表模板内容,xml格式的文本*/
private String content;
private int status;
/*说明*/
private String display;
private Date create_date;
private Date last_update;
/*使用自定义的序列化工具*/
@JsonSerialize(using = RptUpdateSerializer.class)
private Date updateDate;
/*正常*/
public static final int S_NORMAL = 1;
/*删除*/
public static final int S_DELETE = 0;
/*向mybatis声明使用本构造器*/
@AutomapConstructor
public ReportTpl(String id, String name, String display, String content, Date create_date, Date last_update) {
super(name, new MyDate(last_update));
MyDate myDate = (MyDate)super.getUpdateDate();
this.id = id;
this.name = name;
this.content = content;
this.display = display;
this.create_date = new MyDate(create_date);
this.last_update = myDate;
this.updateDate = myDate;
myDate.setReportTpl(this);
}
public ReportTpl(String name, String display) {
super(name, new MyDate(new Date()));
MyDate myDate = (MyDate)super.getUpdateDate();
this.display = display;
this.updateDate = myDate;
myDate.setReportTpl(this);
}
public ReportTpl(String name, Date updateDate) {
super(name, new MyDate(updateDate));
MyDate myDate = (MyDate)super.getUpdateDate();
this.updateDate = myDate;
this.last_update = myDate;
myDate.setReportTpl(this);
}
public static final String name_tail = ".ureport.xml";
public ReportFile getReportFile(){
if( display ==null || display.equals("")){
return new ReportFile(name, last_update);
}else {
return new ReportFile(name, last_update);
}
}
public static Map<String, String> parseName(String name){
int index_start = name.indexOf("#"), index_end= name.indexOf(ReportTpl.name_tail);
if(index_start > -1){
String dis = name.substring(index_start +1, index_end);
return new HashMap<String, String>(){{
put("display", dis);
put("name", name.replace("#" + dis, ""));
}};
}
return Collections.singletonMap("name", name);
}
public void display(){
String name = this.getName();
if(name != null){
int index_start = name.indexOf("#"), index_end= name.indexOf(ReportTpl.name_tail);
if(index_start > -1){
this.setDisplay(name.substring(index_start +1, index_end));
this.setName(name.replace("#" + this.display, ""));
}
}
}
@Override
public Date getUpdateDate() {
return updateDate;
}
@Override
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getDisplay() {
return display;
}
public void setDisplay(String display) {
this.display = display;
}
public Date getCreate_date() {
return create_date;
}
public void setCreate_date(Date create_date) {
this.create_date = create_date;
}
public Date getLast_update() {
return last_update;
}
public void setLast_update(Date last_update) {
this.last_update = last_update;
}
/**
* 自定义日期类,携带报表模板信息,在序列化时展示报表模板的说明
*/
public static class MyDate extends Date{
Date val;
ReportTpl reportTpl;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public MyDate(Date val) {
this.val = val;
}
public Date getVal() {
return val;
}
public void setVal(Date val) {
this.val = val;
}
public ReportTpl getReportTpl() {
return reportTpl;
}
public void setReportTpl(ReportTpl reportTpl) {
this.reportTpl = reportTpl;
}
public SimpleDateFormat getDateFormat() {
return dateFormat;
}
public void setDateFormat(SimpleDateFormat dateFormat) {
this.dateFormat = dateFormat;
}
/**
* 覆盖toString方法,此方法将在自定义的序列化工具类中调用
* @see
* @return
*/
@Override
public String toString() {
return "<span title='"+ getDateFormat().format(val)+ "' >" + getReportTpl().getDisplay() +"</span>";
}
}
}
3.创建ReportApi接口
package com.cn.service;
import com.bstek.ureport.export.html.HtmlReport;
import com.cn.pojo.ReportTpl;
import java.util.List;
import java.util.Map;
/**
* ureport2报表相关的接口
*
*/
public interface ReportApi {
/**
* 返回报表结构
*
* @param templateFileName 报表文件名 tpl:templateFileName.xml
* @param params 参数
* @return
*/
HtmlReport getHTML(String templateFileName, Map<String, Object> params);
/**
* 返回报表结构
*
* @param templateFileName 报表文件名 tpl:templateFileName.xml
* @param params 参数
* @param pageNum 页码
* @return
*/
HtmlReport getHTMLPage(String templateFileName, Map<String, Object> params, int pageNum);
/**
* 插入报表模板
*
* @param reportTpl
* @return
*/
int insertTpl(ReportTpl reportTpl);
/**
* 模板列表
*
* @return
*/
List<ReportTpl> listTpl();
/**
* 查找
*
* @param tplName
* @return
*/
ReportTpl findTplByName(String tplName);
/**
* 更新报表模板
*
* @param reportTpl
* @return
*/
int update(ReportTpl reportTpl);
/**
* 删除报表模板
*
* @param tplName
* @return
*/
int delete(String tplName);
}
4.创建ReportApiImpl实现类
package com.cn.service.impl;
import com.bstek.ureport.export.ExportManager;
import com.bstek.ureport.export.html.HtmlReport;
import com.cn.mapper.ReportTplMapper;
import com.cn.pojo.ReportTpl;
import com.cn.service.ReportApi;
import com.github.pagehelper.Page;
import lombok.extern.slf4j.Slf4j;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.regex.Pattern;
@Slf4j
@Service
public class ReportApiImpl implements ReportApi {
@Resource
private ReportTplMapper reportTplMapper;
@Resource
private ExportManager exportManager;
public static final String RPT_NEED_PAGE = "1";
public static final String RPT_NOT_NEED_PAGE = "0";
/**
* 返回报表结构
*
* @param templateFileName 报表文件名 file:templateFileName.xml
* @param params 参数
* @return
*/
@Override
public HtmlReport getHTML(String templateFileName, Map<String, Object> params) {
//是否需要分页
String needPage = params.getOrDefault("needPage", RPT_NOT_NEED_PAGE).toString();
if (needPage.equals(RPT_NEED_PAGE)) {
HtmlReport report = exportManager.exportHtml(templateFileName, "", params);
Page currentPage = (Page) params.get("currentPage");
report.setTotalPage(currentPage.getPages());
report.setPageIndex(currentPage.getPageNum());
report.setColumn((int) currentPage.getTotal());
log.debug("pages---->{}, pageNum={}, total={}, time -->{}", currentPage.getPages(), currentPage.getPageNum(), currentPage.getTotal(), System.currentTimeMillis());
return report;
} else {
return exportManager.exportHtml(templateFileName, "", params);
}
}
/**
* 返回报表结构
*
* @param templateFileName 报表文件名 file:templateFileName.xml
* @param params 参数
* @param pageNum 页码
* @return
*/
@Override
public HtmlReport getHTMLPage(String templateFileName, Map<String, Object> params, int pageNum) {
return exportManager.exportHtml(templateFileName, "", params, pageNum);
}
/**
* 插入报表模板
*
* @param reportTpl
* @return
*/
@Override
public int insertTpl(ReportTpl reportTpl) {
return reportTplMapper.insert(reportTpl);
}
/**
* 模板列表
*
* @return
*/
@Override
public List<ReportTpl> listTpl() {
return reportTplMapper.list();
}
/**
* 查找
*
* @param tplName
* @return
*/
@Override
public ReportTpl findTplByName(String tplName) {
return reportTplMapper.findByName(tplName);
}
/**
* 更新报表模板
*
* @param reportTpl
* @return
*/
@Override
public int update(ReportTpl reportTpl) {
return reportTplMapper.update(reportTpl);
}
/**
* 删除报表模板
*
* @param tplName
* @return
*/
@Override
public int delete(String tplName) {
return reportTplMapper.delete(tplName);
}
}
5.创建ReportTplMapper数据查询接口
package com.cn.mapper;
import com.cn.pojo.ReportTpl;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface ReportTplMapper {
@Insert("INSERT INTO T_REPORT_TPL(id, name, display, content, status, create_date, last_update) VALUES(#{id, jdbcType=VARCHAR}, #{name, jdbcType=VARCHAR}, #{display, jdbcType=VARCHAR}, #{content, jdbcType=VARCHAR}, #{status, jdbcType=INTEGER}, NOW(), NOW())")
int insert(ReportTpl reportTpl);
@Delete("UPDATE T_REPORT_TPL SET status='0' WHERE name=#{name} ")
int delete(Object name);
@Update("<script>UPDATE T_REPORT_TPL SET last_update = NOW() " +
"<if test=\"name != '' and name != null\">, name=#{name}</if>\n" +
"<if test=\"display != '' and display != null\">, display=#{display}</if>\n" +
"<if test=\"content != '' and content != null\">, content=#{content}</if>\n" +
" WHERE id =#{id}</script>")
int update(ReportTpl reportTpl);
@Select("SELECT id,name, display,content,create_date,last_update FROM T_REPORT_TPL WHERE ID=#{id}")
ReportTpl get(Object id);
@Select("SELECT id,name, display,content,create_date,last_update FROM T_REPORT_TPL WHERE NAME=#{name} AND status='1'")
ReportTpl findByName(String name);
@Select("SELECT id,name,display,content,create_date,last_update FROM T_REPORT_TPL WHERE status='1' ORDER BY name,last_update")
List<ReportTpl> list();
}
6.report包中创建ReportFileProvider
package com.cn.report ;
import com.bstek.ureport.provider.report.ReportFile;
import com.bstek.ureport.provider.report.ReportProvider;
import com.cn.pojo.ReportTpl;
import com.cn.service.ReportApi;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.InputStream;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
@Component
@Slf4j
public class ReportFileProvider implements ReportProvider, Serializable {
private static final String prefix = "tpl:";
@Resource
private ReportApi statisticsApi;
private String getFileName(String file){
return file.substring(prefix.length());
}
@Override
public InputStream loadReport(String file) {
String fileName = getFileName(file);
Map<String, String> nameInfo = ReportTpl.parseName(fileName);
ReportTpl reportTpl = statisticsApi.findTplByName(nameInfo.get("name"));
if(reportTpl == null){
log.error("未找到报表{}", fileName);
throw new RuntimeException("未找到报表模板!");
}else {
return IOUtils.toInputStream(reportTpl.getContent(), Charset.forName("UTF-8"));
}
}
@Override
public void deleteReport(String fileName) {
Map<String, String> nameInfo = ReportTpl.parseName(getFileName(fileName));
statisticsApi.delete(nameInfo.get("name"));
}
@Override
public List<ReportFile> getReportFiles() {
return statisticsApi.listTpl().stream().collect(Collectors.toList());
}
@Override
public void saveReport(String file, String content) {
String fileName = getFileName(file);
Map<String, String> nameInfo = ReportTpl.parseName(fileName);
ReportTpl reportTpl = statisticsApi.findTplByName(nameInfo.get("name"));
if(reportTpl != null){
reportTpl.setContent(content);
reportTpl.setDisplay(nameInfo.get("display"));
reportTpl.setLast_update(new Date());
statisticsApi.update(reportTpl);
} else {
reportTpl = new ReportTpl("", new Date());
reportTpl.setId(UUID.randomUUID().toString());
reportTpl.setContent(content);
reportTpl.setName(nameInfo.get("name"));
reportTpl.setDisplay(nameInfo.get("display"));
reportTpl.setStatus(ReportTpl.S_NORMAL);
statisticsApi.insertTpl(reportTpl);
}
}
@Override
public String getName() {
return "报表模板储存";
}
@Override
public boolean disabled() {
return false;
}
@Override
public String getPrefix() {
return this.prefix;
}
}
7.report包创建RptUpdateSerializer
package com.cn.report ;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
import java.io.IOException;
import java.util.Date;
/**
* 日期序列化,用于ureport列示报表时,展示报表说明
*/
public final class RptUpdateSerializer extends JsonSerializer<Date> {
/**
* Method that can be called to ask implementation to serialize
* values of type this serializer handles.
*
* @param value Value to serialize; can <b>not</b> be null.
* @param jgen Generator used to output resulting Json content
* @param provider Provider that can be used to get serializers for
*/
@Override
public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeString(value.toString());
}
}
创建报表查询
1.创建testController(参数须遵守该规则)
(String dsName, String datasetName, Map<String, Object> parameters)
package com.cn.controller;
import com.bstek.ureport.export.html.HtmlReport;
import com.cn.pojo.testPojo;
import com.cn.service.ReportApi;
import com.cn.service.testService;
import com.cn.util.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
/**
* testController
*
* @author wangyq
* @create 2023/10/11
*/
@RestController
public class testController {
@Autowired
private testService testService;
@Autowired
private ReportApi reportApi;
@GetMapping("/get")
private String get(){
return "test";
}
@GetMapping("/getuReport")
public List<testPojo> ureportList(String dsName, String datasetName, Map<String, Object> parameters){
return testService.ureportList();
}
//前端访问该接口获取数据
@GetMapping("/show")
public Result show(@RequestParam Map<String, Object> params) {
String fileName = params.get("templateFileName").toString();
return Result.success(reportApi.getHTML(fileName, params));
}
}
配置成功
此时访问网址:http://localhost:9020/ureport/designer可以保存报表到数据库中,通过springbean连接,根据类名创建,然后选择方法名。