Oracle”文本”报表输出

Oracle”文本报表输出

Sam.T

2012-12-12

现象:

一个普通的XML或者PL/SQL过程导出的Oracle报表,用Excel打开,第一次存档的时候,可能很大(之前碰到过,一财务的MMXML报表导2年的数据,文档体积超过50M,而她们的电脑配置低,文档没法打开。尴尬。);但是用Excel另存为一个新的Excel文档之后,容量会小很多。为什么?

就是因为,通常我们看到的文档内容,事实上后面有大量的格式控制代码(特别是XML),这些代码也会占用很多容量,导致打开文档的时候会很慢。当你将这个Excel文档另存之后,Excel会将这些代码去掉,所以容量小很多。

XML的格式代码见下图,每个栏位都有:

实现思路:

先说明一下,此方法只适合(大量的)数据导出。就是对数据的显示格式没要求的话可以考虑用这个方法。如果对格式要求很高(例如发货单/销售单打印),还是乖乖用XML开发吧,这种一般是单对单的打印,容量大不了哪里去。

所以现在的目的主要是为了节省输出的文本字符。通常的包输出Excel文档的Procedure报表的开发,实际上是开发网页,一个显示Excel文档的网页。众多的网页控制代码(tr/td等等的网页格式控制代码),占用了很大空间。别小看这个,如果一个报表要输出几十万行的数据,就是网页格式控制代码都占用不少空间。同理,XML的也一样。

所以,基于这个思路,可以考虑直接输出文本txt,就是纯输出内容的文本,用制表符TAB按键作为栏位的分隔符。主要的步骤还是用FND_FILE.PUT_LINE输出用户要的内容,下面有例子。

因为后期是用Excel直接查看输出的内容(相当于用Excel打开txt文本),所以貌似没出现乱码等的问题。比较方便。

我自己实际测试过,用这个方法制作的报表导出的文档的容量,和在Toad里面直接导出Excel文档的容量几乎一样。

注意地方:

注意的是,如果您的报表的栏位本身就包含制表符,就是说,这个栏位会被自动分行。要特别注意的。可以用RAPLACE的办法,将栏位内容的TAB符号替代为空或者空格就行。

 

 

例子:

   --XYG_XXXX公司物料编码信息报表

   --All Inclusive GUI

   PROCEDURE XYG_INV_ITEM_MSG_RPT(

      X_ERR_MSG                OUTVARCHAR2

     ,X_ERR_CODE               OUTNUMBER

     ,P_ORGANIZATION_ID     IN    NUMBERDEFAULT107--跑哪个组织下的所有物料。默认是主组织的

     ,P_ITEM_NUMBER         IN    VARCHAR2DEFAULTNULL---物料编码以什么开头(因为抓所有的太多)

     ,P_AUTO_MAIL_RECEIVER  IN    VARCHAR2--发邮件通知的人,不填就是不自动发邮件。填错当然也发不了

   );

 

 

   PROCEDURE XYG_INV_ITEM_MSG_RPT(

      X_ERR_MSG                OUTVARCHAR2

     ,X_ERR_CODE               OUTNUMBER

     ,P_ORGANIZATION_ID     IN    NUMBERDEFAULT107--跑哪个组织下的所有物料。默认是主组织的

     ,P_ITEM_NUMBER         IN    VARCHAR2DEFAULTNULL---物料编码以什么开头(因为抓所有的太多)

     ,P_AUTO_MAIL_RECEIVER  IN    VARCHAR2--发邮件通知的人,不填就是不自动发邮件。填错当然也发不了

   )

   IS

     V_ORGANIZATION_CODE ORG_ORGANIZATION_DEFINITIONS.ORGANIZATION_CODE%TYPE;

     V_ORGANIZATION_NAME ORG_ORGANIZATION_DEFINITIONS.ORGANIZATION_NAME%TYPE;

      V_MAIL_TITLE  VARCHAR2(1000);

      V_MAIL_RECEIVERVARCHAR2(1000);

      V_MAIL_CONTENTVARCHAR2(4000);

      V_REQUEST_ID  NUMBER;

      V_RPT_LINK    VARCHAR2(500);

      V_RPT_LINK_CONTENTVARCHAR2(2000);

      C_NULL CONSTANTVARCHAR2(10):=null;

 

      CURSOR C_ALL_ITEM

      IS

      SELECT MSIB.ROWID ROW_ID,MSIB.SEGMENT1 ITEM_NUMBER

                 ,MSIB.DESCRIPTION

                 ,TO_CHAR(MSIB.CREATION_DATE,'YYYY-MM-DD HH24:MI:SS')

                     CREATION_DATE

                 ,MSIB.PRIMARY_UOM_CODE

             FROM MTL_SYSTEM_ITEMS_B MSIB

            WHERE1=1--MSIB.ORGANIZATION_ID = OOD.ORGANIZATION_ID

              AND MSIB.ENABLED_FLAG='Y'

              AND MSIB.INVENTORY_ITEM_STATUS_CODE='Active'

              ANDSYSDATEBETWEENNVL(TRUNC(MSIB.START_DATE_ACTIVE),SYSDATE)

                             AND NVL(TRUNC(MSIB.END_DATE_ACTIVE),SYSDATE)

              AND MSIB.ORGANIZATION_ID= P_ORGANIZATION_ID

              AND MSIB.SEGMENT1LIKE P_ITEM_NUMBER ||'%'

         ORDERBY2;

 

      ----

      V_ERROR_LOG_IDNUMBER;

      V_PROGRAM_POSITION XYG_PROGRAM_ERROR_LOG.PROGRAM_POSITION%TYPE;

      V_ERROR_CODE   XYG_PROGRAM_ERROR_LOG.ERROR_CODE%TYPE;

      V_ERROR_MESSAGE XYG_PROGRAM_ERROR_LOG.ERROR_MESSAGE%TYPE;

      V_USER_ID      NUMBER:=FND_GLOBAL.USER_ID;

      V_LOGIN       NUMBER:=FND_GLOBAL.LOGIN_ID;

   BEGIN

      V_REQUEST_ID:=FND_GLOBAL.CONC_REQUEST_ID;

      -- Output Report Head

      LOG('Output Report Head');

      OUTPUT ('XYG_XXXXX物料编码信息报表');

      SELECT ORGANIZATION_CODE,ORGANIZATION_NAME

       INTO V_ORGANIZATION_CODE,V_ORGANIZATION_NAME

       FROM ORG_ORGANIZATION_DEFINITIONS

       WHERE ORGANIZATION_ID= P_ORGANIZATION_ID;

      

      --CHR(9),就是TAB制表符作为栏位的分割。用Excel可以直接打开。

      OUTPUT(  '编码组织:'||CHR(9)|| V_ORGANIZATION_CODE||'-'||V_ORGANIZATION_NAME);

      OUTPUT ('物料编码'||CHR(9)||'物料描述'||CHR(9)||'主单位');

     

      FOR RECIN C_ALL_ITEMLOOP

         --DBMS_OUTPUT.PUT_LINE(REC.ROW_ID);

         OUTPUT(NVL(REC.ITEM_NUMBER, C_NULL)||CHR(9)||NVL(REC.DESCRIPTION, C_NULL)||CHR(9)||NVL(REC.PRIMARY_UOM_CODE, C_NULL));

         --DBMS_OUTPUT.PUT_LINE(NVL (REC.ITEM_NUMBER, C_NULL)||CHR(9)||NVL (REC.DESCRIPTION, C_NULL)||CHR(9)||NVL (REC.PRIMARY_UOM_CODE, C_NULL));

         --DBMS_OUTPUT.PUT_LINE(LENGTHB(NVL (REC.ITEM_NUMBER, C_NULL))||CHR(9)

         --||LENGTHB(NVL (REC.DESCRIPTION, C_NULL))||CHR(9)||LENGTHB(NVL (REC.PRIMARY_UOM_CODE, C_NULL)));

      ENDLOOP;

     

 

      V_PROGRAM_POSITION:='END';

   EXCEPTION

      WHENFND_API.G_EXC_ERRORTHEN

         X_ERR_CODE:=1;

         LOG(X_ERR_MSG);

         RAISE;

      WHENOTHERSTHEN

         X_ERR_CODE:=2;

         X_ERR_MSG:=SQLERRM;

         --NULL;

         V_ERROR_CODE:=SQLCODE;

         V_ERROR_MESSAGE:=SQLERRM;

         LOG(SQLERRM);

         RAISE;

         DBMS_OUTPUT.PUT_LINE(V_ERROR_CODE ||'-' || V_ERROR_MESSAGE);

   END XYG_INV_ITEM_MSG_RPT;

 

实际运行样例:

报表注册:

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值