反馈已提交

网络繁忙

当前为10.0版本文档,只有最新版本的文档支持在线编辑修改,如果想创建/编辑文档,请移步至 最新版帮助文档

导出API

  • 文档创建者:lu123
  • 历史版本:74
  • 最近更新:Carly 于 2023-09-12
  • 1. 概述

    1.1 应用场景

    FineReport 支持预览报表时将报表导出成各种通用的文件格式,如 PDF 、Excel 、Word 等;FineReport 设计器中也支持将模板导出成通用的文件格式或者内置数据模板。如下图所示:

    如果用户不想通过预览报表或操作设计器导出文件,想直接后台导出,该如何实现呢?

    1.2 实现思路

    FineReport 提供了强大的输入输出功能,所有的这些输入输出的类都在 com.fr.report.io 包里面。

    报表的输入指从报表的模板文件( XML 格式的 )创建 WorkBook 对象,在报表调用章节已经介绍过;输出则指将报表保存为各种格式文件,即通过编译 Java 程序调用工程资源后台将模板导出成 cpt 、内置数据 cpt 、PDF 、Excel 、Word 、SVG 、CSV 、image (包含 png 、 jpg 、gif 、bmp )等多种文件格式,导出后释放进程。 

    注:示例代码方案不支持 cptx 模板的导出。

    1.3 接口介绍

    注:导出时,不同的预览方式将对应不同的计算结果报表代码。填报预览导出:Writeactor、分析预览导出:Viewactor,分页预览导出:PageActor

    1)导出成内置数据集模板

    导出成内置数据集模板就是将原模板的数据源根据参数条件查询出结果并转为内置数据集,然后把模板导出,不需要对原模板进行计算。代码如下:

    // 将未执行模板工作薄导出为内置数据集模板  
     outputStream = new FileOutputStream(new File("C:\\test\\EmbExport.cpt"));
     EmbeddedTableDataExporter templateExporter = new EmbeddedTableDataExporter();
     templateExporter.export(outputStream, workbook)

    当要导出模板的数据集使用的是文件数据集 XML 的时候,需要多传一个参数:parameterMap,代码如下:

    // 将未执行模板工作薄导出为内置数据集模板  
      outputStream = new FileOutputStream(new File("C:\\test\\EmbExport.cpt"));
       EmbeddedTableDataExporter templateExporter = new EmbeddedTableDataExporter();
      templateExporter.export(outputStream, workbook,  parameterMap)

    2)导出成模板文件

    可以将原模板通过程序编辑后再次导出为模板文件,或者将某一路径下的模板保存至另一路径下。代码如下:

    // 将模板工作薄导出模板文件,在导出前您可以编辑导入的模板工作薄,可参考报表调用章节  
      outputStream = new FileOutputStream(new File("C:\\test\\TmpExport.cpt"));
      ((WorkBook) workbook).export(outputStream)

     3)导出成 2003Excel 文件

    模板工作薄 WorkBook 执行后为结果工作薄 ResultWorkBook,可以把计算后的结果导出成 Excel 文件。代码如下:

    // 将结果工作薄导出为 2003Excel 文件  
     outputStream = new FileOutputStream(new File("C:\\test\\ExcelExport.xls"));
     ExcelExporter ExcelExport = new ExcelExporter();
     ExcelExport.setVersion(true);
     ExcelExport.export(outputStream, workbook.execute(parameterMap, new WriteActor()))

    注:如果需要导出 2007 版 Excel,需要将 ExcelExporter ExcelExport = new ExcelExporter() 改成StreamExcel2007Exporter ExcelExport = new StreamExcel2007Exporter();

    具体代码如下:

    // 将结果工作薄导出为 Excel 文件  
     outputStream = new FileOutputStream(new File("C:\\test\\ExcelExport.xlsx"));
     StreamExcel2007Exporter ExcelExport1 = new StreamExcel2007Exporter();
     ExcelExport1.export(outputStream, workbook.execute(parameterMap, new WriteActor()))

    4)导出 Word 文件 

    注:FineReport 报表导出 Word 不支持导出悬浮元素,若您需导出的模板中包含悬浮元素如图表,请将其改为单元格元素如单元格中插入图表。

    // 将结果工作薄导出为 Word 文件  
      outputStream = new FileOutputStream(new File("C:\\test\\WordExport.doc"));
      WordExporter WordExport = new WordExporter();
      WordExport.export(outputStream, workbook.execute(parameterMap, new WriteActor()))

    5)导出 PDF 文件

    // 将结果工作薄导出为 PDF 文件  
     outputStream = new FileOutputStream(new File("C:\\test\\PdfExport.pdf"));
     PDFExporter PdfExport = new PDFExporter();
      PdfExport.export(outputStream, workbook.execute(parameterMap, new WriteActor()))

    6)导出 Txt 文件

    // 将结果工作薄导出为 Txt 文件(txt 文件本身不支持表格、图表等,被导出模板一般为明细表)  
      outputStream = new FileOutputStream(new File("C:\\test\\TxtExport.txt"));
      TextExporter TxtExport = new TextExporter();
      TxtExport.export(outputStream, workbook.execute(parameterMap, new WriteActor()))

    7)导出 CSV 文件

    // 将结果工作薄导出为 CSV 文件  
      outputStream = new FileOutputStream(new File("C:\\test\\CsvExport.csv"));
      CSVExporter CsvExport = new CSVExporter();
      CsvExport.export(outputStream, workbook.execute(parameterMap, new WriteActor()))

    8)导出 SVG 文件

    //将结果工作薄导出为 SVG 文件  
     outputStream = new FileOutputStream(new File("C:\\test\\SvgExport.svg"));
     SVGExporter SvgExport = new SVGExporter();
     SvgExport.export(outputStream, workbook.execute(parameterMap, new WriteActor()))

    9)导出 Image 文件

    注:Image 图片支持 png、jpg、 gif、 bmp 格式,这里示例是 png 格式,默认为 jpg。

    //将结果工作薄导出为 image 文件  
     outputStream = new FileOutputStream(new File("C:\\test\\PngExport.png"));
     ImageExporter ImageExport = new ImageExporter();
     ImageExport.export(outputStream, workbook.execute(parameterMap, new WriteActor()))

    10)释放进程

    通过导出 API 在后台导出 Excel 等文件,会产生很多进程,在导出完成之后添加如下代码可释放进程:

    outputStream.close();
    ModuleContext.stopModules()

    2. 示例

    下面实现后台导出 GettingStarted.cpt 模板,参数为报表参数,且设置默认值为华东。

    2.1 准备编译环境

    编译程序前,需先创建一个 Java 工程环境,并且需要一个 Java 编辑器,如 Eclipse 或 idea 。

    在编辑器工程中引入 FineReport 工程 JAR 包。包括安装的报表工程

    • %FR_HOME%\webapps\webroot\WEB-INF\lib目录下 fine 开头的 12 个 JAR 包。

    • %FR_HOME%\webapps\webroot\WEB-INF\lib目录下的 sqlite-jdbc.jar

    • %Tomcat_HOME%\libTomcat目录下的 servlet-api.jar

    • %JAVA_HOME%\jdk\lib JDK 目录下的 tools.jar

    • slf4j-simple-1.7.25.jar ,点击可下载:slf4j-simple-1.7.25.jar

    • 如果报表中需要查询数据库,还需要导入对应的 jdbc 驱动或者插件的 JAR 包(如使用 JSON 数据集,就要引入 JSON 数据集插件下的 JAR 包)。

    详细引入过程可参考:编译Java程序 

    2.2 编写 Java 程序

    在编辑器中编写 Java 程序 ExportApi.java,即引入必要类后,获取模板,将模板导出成指定格式的文件。完整代码可参见:

    注1:代码中 StateServiceActivator 是针对 2020.4.26 JAR 包之后的改动,若之前版本报错将其改为 StateServerActivator 即可。

    注2:用户使用时,注意将示例代码中的工程路径、模板名称和导出路径替换为用户自己工程下的

    普通报表 cpt 代码:

    https://code.fanruan.com/demo/example/src/branch/persist/10.0/src/main/java/com/fr/io/ExportApi.java

    决策报表 frm 代码:

    https://code.fanruan.com/demo/example/src/branch/persist/10.0/src/main/java/com/fr/io/ExportApi_frm.java

    2.3 编译 Java 文件

    Java 程序编写完成后,在编译器中编译 ExportApi.java ,编译通过后,就会在代码中导出路径的文件夹下生成不同格式的文件,这样就导出成功了。如下图所示:

    如果想自动触发程序导出,可以通过 Java 写定时任务触发执行;也可以通过「定时调度>自定义附件处理」功能实现定时触发。如下图所示:

    了解自定义附件处理功能可查看:自定义上传文件至磁盘

    3. 注意事项

    3.1 FineDB 锁死

    问题描述:

    运行编译好的代码时,会弹出错误提示:SQLException : Database lock acquisition failure: lockFile:.....。如下图所示:


    原因分析:

    导出的时候启用了运行环境,如打开了设计器,因为报表内置的数据库为 HSQL 数据库,HSQL 数据库不能多线程访问,所以在导出时启用运行环境就会把 FineDB 锁死,导出时报错。

    解决方案:

    方法一:

    关闭 java 编辑器,如 idea、 Eclipse 进程,将代码中导出模板工程 %FR_HOME%\webapps\webroot\WEB-INF\embed\finedb 下的 db.lck 文件删除,再次打开java 编辑器运行代码运即可。

    注:该方法在运行一次后仍会报错,需要反复删除 db.lck 文件。

    方法二:

    报表工程内置的 HSQL 数据库不能多线程访问,可以将其迁移为其他数据库。迁移方法可参考文档:配置外接数据库

    3.2 角标效果失效

    问题描述:

    如果报表的文字内容中包含特殊的角标,例如下图所示的化学符号角标:

    1.png

    API 导出后,角标的效果跟预览的效果不一致,如下图所示:

    1584338316440929.png

    原因分析:

    后台 API 不支持导出角标。

    解决方案:

    可以利用导出 URL 接口将文件导出到 JVM 内存里面,然后从内存中利用字节输出流写出到操作系统指定盘符,代码如下:

    package com.fr.io;
    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLConnection;
    public class testUrl {
        public static void main(String[] args){
            String pdfPath =  "D:"+File.separator+"TEST.pdf";
            try {
                URL url = new URL("http://localhost:8020/FR10/decision/view/report?viewlet=WorkBook48.cpt&format=pdf&aa=9");
                URLConnection connection = url.openConnection();
                BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
                FileOutputStream outputStream = new FileOutputStream(new File(pdfPath));
                byte[] buff = new byte[1024];
                int byteRead;
                while (-1!=(byteRead=bis.read(buff,0,buff.length))){
                    outputStream.write(buff,0,byteRead);
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    注:Web工程也可以调用性能插件的 PDF 打印方法显示角标,但是实现方式与文档中提供的代码不一样。代码不需要额外写 startModule,否则插件效果不会生效。

    附件列表


    主题: 二次开发
    已经是第一篇
    已经是最后一篇
    • 有帮助
    • 没帮助
    • 只是浏览

    售前咨询电话

    400-811-8890转1

    在线技术支持

    请前往「服务平台」,选择「在线支持」

    热线电话:400-811-8890转2

    总裁办24H投诉

    热线电话:173-1278-1526