历史版本37 :导出API 返回文档
编辑时间: 内容长度:图片数:目录数: 修改原因:

目录:

1. 描述编辑


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

报表的输入指从报表的模板文件( XML 格式的)创建 WorkBook 对象,在报表调用章节已经介绍过。

输出则指将报表保存为各种格式文件,FineReport 支持将报表保存为 cpt 、内置数据 cpt 、pdf 、excel 、word 、svg 、csv 、image (包含 png 、 jpg 、gif 、bmp )等多种文件格式,释放导出进程。 


2. 原理编辑

我们以 Parameter.cpt 模板作为被导出模板,参数为报表参数,且设置默认值为华东

2.1 导出成内置数据集模板

导出成内置数据集模板,顾名思义是将原模板的数据源根据参数条件查询出结果并转为内置数据集,然后把模板导出,不需要对原模板进行计算(数据列扩展、公式计算等)。

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

2.2 导出模板文件

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

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

2.3 导出2003Excel文件

模板工作薄WorkBook执行后为结果工作薄ResultWorkBook,我们可以把计算后的结果导出成Excel文件。

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

注:导出Excel的其他格式可以参考文档:Excel导出的多种方式章节

注:如果需要导出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()));

2.4 导出Word文件 

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

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

2.5 导出Pdf文件

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

2.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()));

2.7 导出Csv文件

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

2.8 导出Svg文件

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

2.9 导出Image文件

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

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

2.10 释放进程

通过导出API在后台导出excel等文件,会产生很多进程,通过下面的方案释放进程。

在导出完成之后添加下面代码:

outputStream.close();
ModuleContext.stopModules();

3. 示例编辑


3.1 完整可执行代码

package com.fr.io;

import com.fr.base.Parameter;
import com.fr.base.operator.common.CommonOperator;
import com.fr.chart.activator.ChartBaseActivator;
import com.fr.config.activator.BaseDBActivator;
import com.fr.config.activator.ConfigurationActivator;
import com.fr.data.impl.config.activator.RestrictionActivator;
import com.fr.env.operator.CommonOperatorImpl;
import com.fr.general.ModuleContext;
import com.fr.io.exporter.CSVExporter;
import com.fr.io.exporter.EmbeddedTableDataExporter;
import com.fr.io.exporter.ExcelExporter;
import com.fr.io.exporter.ImageExporter;
import com.fr.io.exporter.PDFExporter;
import com.fr.io.exporter.SVGExporter;
import com.fr.io.exporter.TextExporter;
import com.fr.io.exporter.WordExporter;
import com.fr.io.exporter.excel.stream.StreamExcel2007Exporter;
import com.fr.main.impl.WorkBook;
import com.fr.main.workbook.ResultWorkBook;
import com.fr.module.Module;
import com.fr.module.tool.ActivatorToolBox;
import com.fr.report.ReportActivator;
import com.fr.report.module.ReportBaseActivator;
import com.fr.stable.WriteActor;
import com.fr.store.StateServerActivator;
import com.fr.workspace.simple.SimpleWork;

import java.io.File;
import java.io.FileOutputStream;


public class ExportApi {
    public static void main(String[] args) {
        // 定义报表运行环境,用于执行报表
        Module module = ActivatorToolBox.simpleLink(new BaseDBActivator(),
                new ConfigurationActivator(),
                new StateServerActivator(),
                new ReportBaseActivator(),
                new RestrictionActivator(),
                new ReportActivator(),
                new ChartBaseActivator());
        SimpleWork.supply(CommonOperator.class, new CommonOperatorImpl());
        String envpath = "//Applications//FineReport10_325//webapps//webroot//WEB-INF";//工程路径
        SimpleWork.checkIn(envpath);
        module.start();
        ResultWorkBook rworkbook = null;
        try {
            // 未执行模板工作薄
            WorkBook workbook = (WorkBook) TemplateWorkBookIO
                    .readTemplateWorkBook("//doc//Primary//Parameter//Parameter.cpt");
            // 获取报表参数并设置值,导出内置数据集时数据集会根据参数值查询出结果从而转为内置数据集
            Parameter[] parameters = workbook.getParameters();
            parameters[0].setValue("华东");
            // 定义parametermap用于执行报表,将执行后的结果工作薄保存为rworkBook
            java.util.Map parameterMap = new java.util.HashMap();
            for (int i = 0; i < parameters.length; i++) {
                parameterMap.put(parameters[i].getName(), parameters[i]
                        .getValue());
            }
            // 定义输出流
            FileOutputStream outputStream;
            // 将未执行模板工作薄导出为内置数据集模板
            outputStream = new FileOutputStream(new File("/Users//susie//Downloads//EmbExport.cpt"));
            EmbeddedTableDataExporter templateExporter = new EmbeddedTableDataExporter();
            templateExporter.export(outputStream, workbook);
            // 将模板工作薄导出模板文件,在导出前您可以编辑导入的模板工作薄,可参考报表调用章节
            outputStream = new FileOutputStream(new File("/Users//susie//Downloads//TmpExport.cpt"));
            ((WorkBook) workbook).export(outputStream);
            // 将结果工作薄导出为2003Excel文件
            outputStream = new FileOutputStream(new File("/Users//susie//Downloads//ExcelExport.xls"));
            ExcelExporter ExcelExport = new ExcelExporter();
            ExcelExport.export(outputStream, workbook.execute(parameterMap, new WriteActor()));
            // 将结果工作薄导出为Excel文件
            outputStream = new FileOutputStream(new File("/Users//susie//Downloads//ExcelExport.xlsx"));
            StreamExcel2007Exporter ExcelExport1 = new StreamExcel2007Exporter();
            ExcelExport1.export(outputStream, workbook.execute(parameterMap, new WriteActor()));
            // 将结果工作薄导出为Word文件
            outputStream = new FileOutputStream(new File("/Users//susie//Downloads//WordExport.doc"));
            WordExporter WordExport = new WordExporter();
            WordExport.export(outputStream, workbook.execute(parameterMap, new WriteActor()));
            // 将结果工作薄导出为Pdf文件
            outputStream = new FileOutputStream(new File("/Users//susie//Downloads//PdfExport.pdf"));
            PDFExporter PdfExport = new PDFExporter();
            PdfExport.export(outputStream, workbook.execute(parameterMap, new WriteActor()));
            // 将结果工作薄导出为Txt文件(txt文件本身不支持表格、图表等,被导出模板一般为明细表)
            outputStream = new FileOutputStream(new File("/Users//susie//Downloads//TxtExport.txt"));
            TextExporter TxtExport = new TextExporter();
            TxtExport.export(outputStream, workbook.execute(parameterMap, new WriteActor()));
            // 将结果工作薄导出为Csv文件
            outputStream = new FileOutputStream(new File("/Users//susie//Downloads//CsvExport.csv"));
            CSVExporter CsvExport = new CSVExporter();
            CsvExport.export(outputStream, workbook.execute(parameterMap, new WriteActor()));
            //将结果工作薄导出为SVG文件
            outputStream = new FileOutputStream(new File("/Users//susie//Downloads//SvgExport.svg"));
            SVGExporter SvgExport = new SVGExporter();
            SvgExport.export(outputStream, workbook.execute(parameterMap, new WriteActor()));
            //将结果工作薄导出为image文件
            outputStream = new FileOutputStream(new File("/Users//susie//Downloads//PngExport.png"));
            ImageExporter ImageExport = new ImageExporter();
            ImageExport.export(outputStream, workbook.execute(parameterMap, new WriteActor()));
            outputStream.close();
            module.stop();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            SimpleWork.checkOut();
        }
    }
}

注:在使用API导出不同类型文件时,除了需要导入FineReport默认jar包之外,还需要导入%FR_HOME%\webroot\WEB-INF\lib下面的sqlite-jdbc.jartomcat\lib下面的serverlet-api.jar

编译运行该代码后,就会在对应的文件夹下生成不同格式的文件,这样就导出成功了,如下图:


222

3.2 代码优化

表单导出代码写法优化。

结果工作簿改用以下方法即可:

ResultWorkBook re = FSFormletHandler.executeForm("xxxx.frm", new HashMap<String, Object>());  

同时头文件引入 FSFormletHandler:

import com.fr.fs.web.FSFormletHandler;  

代码优化示例如下:

package com.fr.io;  
import java.io.File;
import java.io.FileOutputStream;
import com.fr.base.FRContext;
import com.fr.general.ModuleContext;
import com.fr.dav.LocalEnv;
import com.fr.fs.web.FSFormletHandler;
import com.fr.io.exporter.PDFExporterProcessor;
import com.fr.io.exporter.ImageExporter;
import com.fr.main.workbook.ResultWorkBook;
import com.fr.report.module.EngineModule;
import com.fr.web.core.reserve.PDFExporterFactory;  

public class ExportApi {    
   public static void main(String[] args) {        
       // 定义报表运行环境,才能执行报表        
       String envpath = "//Applications//FineReport10_325//webapps//webroot//WEB-INF";        
       FRContext.setCurrentEnv(new LocalEnv(envpath));        
       ModuleContext.startModule(EngineModule.class.getName());              
       try {            
            java.util.Map paraMap = new java.util.HashMap();              
            paraMap.put("company", "VINET");            
            ResultWorkBook re = FSFormletHandler.executeForm("//doc//Primary//Parameter//Parameter.cpt",paraMap);                      
            FileOutputStream outputStream;              
            // 将结果工作薄导出为Pdf文件            
            outputStream = new FileOutputStream(new File("/Users//susie//Downloads//PdfExport.pdf"));            
            PDFExporterProcessor PdfExport = PDFExporterFactory.getPDFExporter();            
            PdfExport.export(outputStream,re);                    
            //将结果工作薄导出为image文件            
            outputStream = new FileOutputStream(new File("/Users//susie//Downloads//PngExport.png"));            
            ImageExporter ImageExport = new ImageExporter();            
            ImageExport.export(outputStream,re);                                
            outputStream.close();            
            ModuleContext.stopModules();        
          } catch (Exception e) {            
            e.printStackTrace();        
          }    
       }
   }

4. 错误代码:1120出现原因及解决方法编辑


运行编译好的代码时,会弹出错误提示:错误代码:1120 当前Hsql数据库已被另一线程锁定。

原因:导出的时候使用了运行环境,所以会把db.lck给死锁,导出一次后再次导出就会报错。

解决方法:

方法一:关闭eclipse进程,%FR_HOME%\webapps\webroot\WEB-INF\embed\finedbdb.lck文件删除,再次运行eclipse即可。

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

方法二:迁移平台数据,具体可以参考配置外接数据库




索引:

Excel导出的多种方式

后台批量导出Excel

Excel直接转成模板cpt

多个报表导入一个Excel