springboot整合ureport生成报表

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连接,根据类名创建,然后选择方法名。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Spring Boot整合UReport2可以通过以下步骤实现: 1. 引入UReport2的依赖 在pom.xml文件中添加以下依赖: ``` <dependency> <groupId>com.bstek.ureport</groupId> <artifactId>ureport2-core</artifactId> <version>2..6</version> </dependency> ``` 2. 配置UReport2的数据源 在application.properties文件中添加以下配置: ``` ureport.fileStoreDir=ureport_files ureport.ds.myds.driverClassName=com.mysql.jdbc.Driver ureport.ds.myds.url=jdbc:mysql://localhost:3306/test ureport.ds.myds.username=root ureport.ds.myds.password=root ``` 其中,ureport.fileStoreDir是UReport2报表文件存储的目录,ureport.ds.myds是数据源的配置,可以根据实际情况修改。 3. 创建UReport2报表 在resources目录下创建ureport文件夹,并在该文件夹下创建一个以ureport为后缀的文件,例如test.ureport.xml。 在该文件中可以使用UReport2提供的设计器创建报表。 4. 配置Spring Boot的Controller 在Spring Boot的Controller中注入UReportEngine对象,并在方法中调用UReportEngine的runReport方法生成报表。 ``` @RestController public class ReportController { @Autowired private UReportEngine uReportEngine; @GetMapping("/report") public void report(HttpServletResponse response) throws Exception { UReportFile reportFile = uReportEngine.getReportFile("test.ureport.xml"); UReport uReport = reportFile.parse(); Map<String, Object> parameters = new HashMap<>(); parameters.put("param1", "value1"); parameters.put("param2", "value2"); byte[] bytes = uReportEngine.generatePdf(uReport, parameters); response.setContentType("application/pdf"); response.getOutputStream().write(bytes); } } ``` 在上述代码中,调用了UReportEngine的getReportFile方法获取报表文件,然后调用parse方法解析报表文件,最后调用generatePdf方法生成PDF格式的报表。 5. 运行Spring Boot应用程序 在浏览器中访问http://localhost:808/report,即可生成报表并下载。 ### 回答2: Spring Boot是一种开源框架,可以用于快速构建基于Spring的企业级Web应用程序。而Ureport2是一个基于Java的开源报表引擎。将Spring BootUreport2结合起来,可以轻松构建出一个高效、稳定的报表系统。 首先,需要在Spring Boot的Maven依赖中添加Ureport2的依赖项,例如: ``` <dependency> <groupId>com.bstek.ureport</groupId> <artifactId>ureport2-console</artifactId> <version>2.8.14</version> </dependency> ``` 接下来,需要在Spring Boot中配置Ureport2,主要包括以下步骤: 1. 配置Ureport2的工作目录,可以通过在application.properties中添加以下一行代码来实现: ``` ureport2.fileStoreDir=/ureport/filestore ``` 2. 配置Ureport2的资源访问路径,可以通过在application.properties中添加以下一行代码来实现: ``` ureport2.urConfigFile=classpath:ureport-context.xml ``` 3. 在Spring Boot中添加Ureport2的配置文件,需要在src/main/resources目录下创建ureport-context.xml文件,并在其中添加以下代码: ``` <bean id="ureportHtmlViewResolver" class="com.bstek.ureport.view.UreportHtmlViewResolver"> <property name="ureportTemplate" value="classpath:report/"/> </bean> ``` 4. 如果需要使用Ureport2的自定义扩展功能,可以在Spring Boot中添加相关扩展。 最后,还需在Spring Boot中编写相关代码,实现与Ureport2的数据交互。这部分代码需要遵循Ureport2的API规范,可通过Ureport2的文档获取相关信息。 总之,通过以上步骤,就可以轻松地将Spring BootUreport2整合起来,构建出高效稳定的企业级报表系统。 ### 回答3: Spring Boot是一个开源的Java Web框架,它提供了一种快速创建和部署Web应用的方式。Ureport2是一款强大的Java报表引擎,可以快速生成多种格式和样式的报表。将Spring BootUreport2整合可以使开发人员更加轻松地创建和管理报表,提高开发效率。 整合步骤如下: 1.添加依赖库 在pom.xml文件中添加以下依赖库: ```xml <dependency> <groupId>com.bstek.ureport</groupId> <artifactId>ureport2-core</artifactId> <version>2.6.6</version> </dependency> <dependency> <groupId>com.bstek.ureport</groupId> <artifactId>ureport2-web</artifactId> <version>2.6.6</version> </dependency> <dependency> <groupId>com.bstek.ureport</groupId> <artifactId>ureport2-engine</artifactId> <version>2.6.6</version> </dependency> ``` 2.配置文件 在Spring Boot的配置文件application.properties中增加以下配置: ureport.enabled=true ureport.report_home=/ureport2_home ureport.designer.enabled=true 其中,ureport.enabled设置为true,表示启用ureportureport.report_home表示报表文件存储的根路径;ureport.designer.enabled表示是否启用报表设计器。 3.定义报表控制器 在Spring Boot中定义控制器类来处理生成和展示报表,可以使用Spring Boot提供的@RestController注解来实现。 ```java @RestController @RequestMapping("report") public class ReportController { @Autowired private ReportService reportService; @GetMapping("/pdf") public void generatePdfReport(HttpServletRequest request, HttpServletResponse response) { // 获取报表模板文件 InputStream inputStream = this.getClass().getResourceAsStream("/ureport/test.ureport.xml"); // 获取报表数据 List<Map<String, Object>> dataList = reportService.getDataList(); // 生成PDF格式的报表文件 OutputStream outputStream = null; try { outputStream = response.getOutputStream(); UReportUtils.generatePdf(inputStream, dataList, outputStream); } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.closeQuietly(outputStream); } } } ``` 在上述控制器类中,@GetMapping注解指定URL路径为“/report/pdf”,表示请求生成PDF格式的报表文件。通过报表模板文件和报表数据生成PDF格式的报表,并输出到response中。 4.定义报表服务类 在Spring Boot中定义服务类来获取数据并返回给报表控制器,可以使用Spring Boot提供的@Service注解来实现。 ```java @Service public class ReportService { public List<Map<String, Object>> getDataList() { // 从数据库或其他数据源获取数据 List<Map<String, Object>> dataList = new ArrayList<>(); Map<String, Object> data = new HashMap<>(); data.put("name", "张三"); data.put("age", 28); dataList.add(data); return dataList; } } ``` 在上述服务类中,getDataList方法从数据库或其他数据源获取数据,并返回给报表控制器使用。 整合完毕后,启动应用程序,访问“/report/pdf”即可生成PDF格式的报表文件并输出到浏览器中。Ureport2还支持多种格式和样式的报表输出,可以根据实际需求进行配置和使用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值