OAF中输出PDF报表文件超链接

OAF中输出PDF报表文件超链接解决方案

解决思路

获取PDF文件的输出流

获取输出流之后将其转换为BLOB

将转化后的BLOB存储在附件表fnd_blobs中

构造该BLOB文件的URL

将URL存储在客户化表里形成一条唯一的记录,返回唯一ID FORM通过返回得唯一ID找到URL,调用方法,在浏览器打开URL

技术要点

  1. 使用TemplateHelper.processTemplate方法生成目标PDF的InputStream流
  2. 调用程序包将InputStream传入数据库中的BLOB字段中,并生成对应的记录

    . 获取到唯一记录的 file_id,使用API生成对应的 URL

实现过程

  1. 使用TemplateHelper.processTemplate方法生成目标PDF的InputStream流

    首先选择页面数据代码,点击多选框后,需要在触发事件中写入

    /**
    
    - 查询界面  选择需要输出的数据(多选),调用获取xmlClob的程序包
    - @param pageContext
    - @param webBean
      */
      public static void doPrint_req(OAPageContext pageContext, OAWebBean webBean,String poNumber) {
          OAApplicationModule am =
              pageContext.getApplicationModule(webBean); //getRootApplicationModule();
          CUX90POOrderDateilsVOImpl vo =
              (CUX90POOrderDateilsVOImpl)am.findViewObject("CUX90POOrderDateilsVO1");
          CUX90POOrderDateilsVORowImpl row = null;
          String str = "";
          String param = "";
          boolean flag3 = true;
          int i = 0;
          int j = 0;
          row = (CUX90POOrderDateilsVORowImpl)vo.first(); //定位记录指针到第一条
          while (row != null) {
      //            String checkFlag = row.getCheckFlag();
              if (poNumber.equals(row.getDocumentNum())) {
                  j = j + 1;
              }
              if (vo.hasNext()) {
                  row = (CUX90POOrderDateilsVORowImpl)vo.next();
              } else {
                  break;
              }
          }
          if (j != 0) {
              Number[] params = new Number[j]; //iface_line_id
              row = (CUX90POOrderDateilsVORowImpl)vo.first(); //定位记录指针到第一条
              while (row != null) {
                   if (poNumber.equals(row.getDocumentNum())) {
                      Number lineId = row.getLineId();
                      System.out.println("lineId:"+lineId);
                      params[i] = lineId;
                     // param = param + lineId + ",";
                      i = i + 1;
                  }
                  if (vo.hasNext()) {
                      row = (CUX90POOrderDateilsVORowImpl)vo.next();
                  } else {
                      break;
                  }
             }
             //获取XMLClob。
              getXMLClob_req(pageContext, webBean, params,poNumber);
          }
      }
    
    

    然后看一下获取选择数据的xmlClob的方法getXMLClob_req

        /**
         * (有多选框版本)调用AM执行PLSQL返回CLOB类型
         * @param pageContext
         * @param webBean
         */
        public static void getXMLClob_req(OAPageContext pageContext, OAWebBean webBean,
                                      Number[] params,String poNumber) {
            OAApplicationModule am = pageContext.getApplicationModule(webBean);
            Serializable[] methodParams = { params };
            Class[] methodParamTypes = { params.getClass() };
            CLOB tempClob =
                (CLOB)am.invokeMethod("getXmlColb", methodParams, methodParamTypes);
            //在EBS中定义好之后报表需要输出的RTF模板,写入模板名称。
            String templateName = "CUXEBSPODOCUMENTRPT";
            //调用打印PDF的方法,将xml数据对象以及数据模板作为参数传入
            PrintPDF_req(pageContext, webBean, tempClob,templateName,poNumber);
        }
    

    可以看一下AM中调用getXmlColb的方法,其中大概就是使用OAF调用获取xml数据的程序包,将参数传入,然后将XML数据返回,跟做xml报表并无区别,只是将xml作为CLOB数据返回,具体就不细看了。

    
        /**
         * 执行PLSQL  返回CLOB类型数据
         * @param params 数值类型参数,存放选择数据的LINE_ID
         * @return
         */
        public CLOB getXmlColb(Number[] params) {
            String result = null;
            String num = null;
            CLOB tempClob = null;
            OADBTransaction oadbtransaction = getOADBTransaction();
            OracleConnection oracleConnection = (OracleConnection)oadbtransaction.getJdbcConnection();
            if (params[0] != null)
            {
              ARRAY vdrArray = null;
              try
              {
                ArrayDescriptor tableOfNumber =
                  oracle.sql.ArrayDescriptor.createDescriptor("FND_TABLE_OF_NUMBER",
                                                              oracleConnection);
                vdrArray = new ARRAY(tableOfNumber, oracleConnection, params);
                String sql = "BEGIN cux_ebs_po_equipment_unitrpt.main(errbuf => :1, retcode=>:2, p_order_type=>:3, p_id_arr=>:4, x_out_xml=>:5);end;";
                OracleCallableStatement oraclecallablestatement =
                  (OracleCallableStatement)oadbtransaction.createCallableStatement(sql, 1);
    
                //PLSQL 输入参数
                 oraclecallablestatement.setString(3,"POORDER");
                oraclecallablestatement.setARRAY(4, vdrArray);
                //PACKAGE 输出参数
                oraclecallablestatement.registerOutParameter(1, OracleTypes.VARCHAR);
                oraclecallablestatement.registerOutParameter(2, OracleTypes.VARCHAR);
                oraclecallablestatement.registerOutParameter(5, OracleTypes.CLOB);
                //实行SQL
                oraclecallablestatement.execute();
                //获取值
                tempClob = oraclecallablestatement.getCLOB(5);
              } catch (Exception ex)
              {
                ex.printStackTrace();
              }
            }
            return tempClob;
        }
    

    接下来看一下调用PrintPDF_req打印PDF文件的方法。

        /**
         * 调用模板生成PDF文件
         * @param pageContext
         * @param webBean
         * @param xmlClob PLSQL返回的CLOB类型参数
         * @param templateName 系统中模板的名称
         * @param poNumber 订单编号
         */
        public static void PrintPDF_req(OAPageContext pageContext, OAWebBean webBean,
                                    CLOB xmlClob, String templateName,String poNumber) {
    //        HttpServletResponse response =
    //            (HttpServletResponse)pageContext.getRenderingContext().getServletResponse();
            OAApplicationModule am = pageContext.getApplicationModule(webBean);
            OADBTransaction oadbTransaction = am.getOADBTransaction();
            String fileName = "PurchaseOrder_"+poNumber+".pdf";
            try {
                Reader inputReader = xmlClob.getCharacterStream();
                //定义一个接收数据的输出流,将PDF的文件流输出。
                ByteArrayOutputStream pdfFile = new ByteArrayOutputStream();
                OADBTransactionImpl oaTrans = (OADBTransactionImpl)pageContext.getApplicationModule(webBean).getOADBTransaction();
    //            参数--应用缩写,模板名称
                TemplateHelper.processTemplate(oaTrans.getAppsContext(), "CUX",
                                               templateName, "zh", "CN",
                                               inputReader,
                                               TemplateHelper.OUTPUT_TYPE_PDF,
                                               null, pdfFile);
                byte[] bytes = pdfFile.toByteArray();
                //定义一个输入流,将PDF文件流输入进去
                InputStream in= new ByteArrayInputStream(bytes);
                //调用程序包,将blob放进数据库。
                 OADBTransaction oadbtransaction = am.getOADBTransaction();
                 OracleConnection oracleConnection = (OracleConnection)oadbtransaction.getJdbcConnection();
                 String sql = "BEGIN apps.cux_ebs_po_oacreatepo_pkg.update_file(errbuf => :1, retcode=>:2,p_file_name=>:3,p_blob=>:4,x_file_id=>:5,p_po_number=>:6);end;";
                 OracleCallableStatement oraclecallablestatement =
                   (OracleCallableStatement)oadbtransaction.createCallableStatement(sql, 1);
                 //PLSQL 输入参数
                 oraclecallablestatement.setString(3, fileName);
                 oraclecallablestatement.setBlob(4,in);
                 oraclecallablestatement.setString(6,poNumber);
                 //PACKAGE 输出参数
                 oraclecallablestatement.registerOutParameter(1, OracleTypes.VARCHAR);
                 oraclecallablestatement.registerOutParameter(2, OracleTypes.VARCHAR);
                 oraclecallablestatement.registerOutParameter(5, OracleTypes.VARCHAR);
                 //执行SQL
                 oraclecallablestatement.execute();
                 String  resultError = oraclecallablestatement.getString(1);
                 System.out.println("resultError:"+resultError);
                 String  retcode = oraclecallablestatement.getString(2);
                 System.out.println("retcode:"+retcode);
                 String fileId=oraclecallablestatement.getString(5);
                 System.out.println("fileId:"+fileId);
            } catch (Exception e) {
    //            response.setContentType("text/html");
                throw new OAException(e.getMessage(), OAException.ERROR);
            }
        }
    

    接下里看一下程序包中接收BLOB之后的处理

    /*==================================================
      Procedure Name :
          update_file
      Description:
          将获取到的PDF文件输入流插入fnd_lobs表中,生成一条唯一的记录,并使用API生成超链接更新进传OA的接口表中。
    
      Argument:
          errbuf          : concurrent return message buffer
          retcode         : concurrent return status code
                              0 success / 1 warning / 2 error
          x_file_id       :OAF调试中每次生成的file_id
          p_file_name     :文件名称
          p_blob          :接收到的文件BLOB
          p_po_number     :订单编号
      History:
          1.00  2019-08-22 kaikai.zhang Creation
      ==================================================*/
      PROCEDURE update_file(errbuf      OUT VARCHAR2
                           ,retcode     OUT VARCHAR2
                           ,x_file_id   OUT VARCHAR2
                           ,p_file_name IN VARCHAR2
                           ,p_blob      IN BLOB
                           ,p_po_number IN VARCHAR2) IS
        l_return_status VARCHAR2(30);
        l_msg_count     NUMBER;
        l_msg_data      VARCHAR2(2000);
        l_file_id       NUMBER;
        l_url           VARCHAR2(240);
      BEGIN
        retcode := ‘0‘;
        SELECT fnd_lobs_s.nextval INTO l_file_id FROM dual;
        --插入文件内容到附件表
        INSERT INTO fnd_lobs
          (file_id
          ,file_name
          ,file_content_type
          ,file_data
          ,upload_date
          ,expiration_date
          ,program_name
          ,program_tag
          ,LANGUAGE
          ,file_format)
        VALUES
          (l_file_id
          ,p_file_name
          ,‘application/pdf‘ --SELECT * FROM fnd_mime_types 查询文件类型
          ,p_blob
          ,SYSDATE
          ,SYSDATE
          ,‘ERPTOOAORDER‘
          ,‘XDO:10‘
          ,‘ZHS‘
          ,‘binary‘);
        x_file_id := l_file_id;
         -------------------------------------------------------------------------
        /* 使用file_id生成唯一的URL */
        -------------------------------------------------------------------------
        l_url := fnd_gfm.construct_download_url(fnd_web_config.gfm_agent,
                                                l_file_id,
                                                TRUE);
        -------------------------------------------------------------------------
        /*  将生成的超链接更新进接口表中  */
        -------------------------------------------------------------------------
        IF l_url IS NOT NULL THEN
          UPDATE cux_oa_po_approval_iface t
          SET    t.attchment      = l_url
                ,t.attchment_flag = ‘Y‘
          WHERE  1 = 1
          AND    t.document_num = p_po_number;
        ELSE
          UPDATE cux_oa_po_approval_iface t
          SET    t.attchment_flag = ‘N‘
          WHERE  1 = 1
          AND    t.document_num = p_po_number;
        END IF;
        COMMIT;
      EXCEPTION
        WHEN fnd_api.g_exc_error THEN
          cux_30_fnd_conc_utl.log_message_list;
          retcode := ‘1‘;
          fnd_msg_pub.count_and_get(p_encoded => fnd_api.g_false,
                                    p_count   => l_msg_count,
                                    p_data    => l_msg_data);
          IF l_msg_count > 1 THEN
            l_msg_data := fnd_msg_pub.get_detail(p_msg_index => fnd_msg_pub.g_first,
                                                 p_encoded   => fnd_api.g_false);
          END IF;
          errbuf := NULL;
          errbuf := l_msg_data;
        WHEN fnd_api.g_exc_unexpected_error THEN
          cux_30_fnd_conc_utl.log_message_list;
          retcode := ‘2‘;
          fnd_msg_pub.count_and_get(p_encoded => fnd_api.g_false,
                                    p_count   => l_msg_count,
                                    p_data    => l_msg_data);
          IF l_msg_count > 1 THEN
            l_msg_data := fnd_msg_pub.get_detail(p_msg_index => fnd_msg_pub.g_first,
                                                 p_encoded   => fnd_api.g_false);
          END IF;
          errbuf := NULL;
          errbuf := l_msg_data;
        WHEN OTHERS THEN
          fnd_msg_pub.add_exc_msg(p_pkg_name       => g_pkg_name,
                                  p_procedure_name => ‘MAIN‘,
                                  p_error_text     => substrb(SQLERRM, 1, 240));
          cux_30_fnd_conc_utl.log_message_list;
          retcode := ‘2‘;
          errbuf  := NULL;
          errbuf  := SQLERRM;
      END update_file;
    

    这样超链接就生成到传OA的接口表中,每次OA只需从接口表中获取对应记录的链接就可以获取相应的PDF报表

原文地址:https://www.cnblogs.com/kaikai-wanna-know/p/12590053.html

时间: 2024-10-10 16:42:05

OAF中输出PDF报表文件超链接的相关文章

mvc 在view视图中直接输出rdlc报表文件(Excel、PDF、Word)

给一段代码做参考 public ActionResult RdlcReport(string code) { LocalReport localReport = new LocalReport(); EasyMan.Dtos.ErrorInfo err = new EasyMan.Dtos.ErrorInfo(); err.IsError = false; try { var report = _reportAppService.GetReport(code, 0, false); DataTa

JSP中调用Ireport报表文件并展示效果源码

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.io.*, net.sf.jasperreports.engine.*, net.sf.jasperreports.engine.util.*, java.util.*,java.sql.*, net.s

MVC中生成PDF并在web中显示

最近接到一个新需求,需要将原先下载到用户电脑的PDF报表文件显示在新开的网页页面中,用户自己选择在页面内嵌的PDF上进行另存和打印. 代码如下: FastReport.Report rpt = MakeProposalReport(xxx,xxx,xxx,xxx,xxx); byte[] buffer = ExportPDFToByteArray(rpt); //刪除旧的PDF文件 DeleteTempPdfFile();//取档名string fName = MakeReportFileNam

从BIRT报表文件中获取页面设置信息(页边距、纸张大小、输出方向)的方法

报表打印时,尤其是套打的报表,页面设置信息非常重要,比如页边距,纸张大小,输出方向等,而且每个报表的相关参数有可能不同,因此相关参数从具体报表中获取是一个非常正常而且合理的想法. 如果采用BIRT作为报表的开发工具,报表设计器负责报表的制作,BIRT运行时负责处理报表文件,对于浏览器来说,BIRT后端输出的是网页,并不包含页面设置相关信息,浏览器有自己的打印设置选项,也不会从网页中读取,但是报表设计器在报表设计时提供页面设置信息的设置界面,因此我们需要通过运行时API手工写代码从具体报表中获取页

将一个目录中所有PDF文件合并到一个新的PDF文件中

将一个目录中所有PDF文件合并到一个新的PDF文件中 using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System;using System.Collections.Generic;using System.Text;using Syst

如何在PDF文档内容中插入/添加图片文件

现在很多人都会使用PDF格式文件,但是却很少会有人知道怎么编辑这种文件,我们所见的PDF格式文档是一种及其特殊的文件,这种文不论是修改还是编辑都非常的困难,因此,如果我们需要在PDF文件中插入图片的话该怎么做呢?今天小编就来为大家详细的介绍下如何使用专业软件在PDF文件中插入图片! 需要使用的软件是迅捷PDF编辑器,是一款专业的PDF编辑软件,下载很简单,只要在浏览器上搜索到迅捷PDF编辑器是官方网站,点击软件下载后选择下路径就可以了.安装运行也极为简单,还要按照提示点击下一步就可以了,在官网下

把存储过程获取的数据输出到报表的html模板中

制作报表的html模板 <HTML><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><TITLE>报表模板</TITLE> <BODY> <TABLE BORDER="1" cellpadding="0" cellspacing="0"> <

怎么用PHP在HTML中生成PDF文件

原文:Generate PDF from html using PHP 译文:使用PHP在html中生成PDF 译者:dwqs 利用PHP编码生成PDF文件是一个非常耗时的工作.在早期,开发者使用PHP并借助FPDF来生成PDF文件.但是如今,已经有很多函数库可以使用了,并且能够从你提供的HTML文件生成PDF文档.这让原先耗时的工作变得非常简单了. FPDF是很早就被使用的,其特点如下: FPDF FPDF是一个允许使用纯PHP生成PDF文档的PHP类,换句话说,没有使用PDFlib 函数库.

Rhel7 grep在文件中查找指定的字符串,将其输出到指定文件

Rhel7 grep在文件中查找指定的字符串,将其输出到指定文件 [[email protected] findfiles]# cat /usr/share/dict/words |grep seismic anaseismic antiseismic aseismic -- [[email protected] findfiles]# cat /usr/share/dict/words |grep seismic >>/root/wordlist [[email protected] fin