PL/SQL操作EXCEL
PL/SQL操作EXCEL有多种方法,但都不理想。比较了一下,还是通过JAVA的方法比较适用。
1. 使用UTL_FILE包
declare l_file utl_file.file_type;
BEGIN
l_file :=utl_file.fopen('U_FIEL','test1.xls','w');
utl_file.put_line(l_file,'jobs表导出数据');
utl_file.fflush(l_file);
end;
说明:此方法操作文本尚可,对于EXCEL这种COM文件并不可行。网络大多数所谓的PL/SQL操作EXCEL, 也是使用cvs这种简单的格式。如果要读入稍微复杂点的EXCLE模板文件,utl_file就挂掉了。
2. 使用OLE2
declare
application OLE2.OBJ_TYPE;
workbooks OLE2.Obj_Type;
workbook OLE2.Obj_Type;
worksheets OLE2.Obj_Type;
worksheet OLE2.Obj_Type;
args OLE2.List_Type;
cell OLE2.Obj_Type;
begin
application:=OLE2.CREATE_OBJ('Excel.Application');
OLE2.Set_Property(application,'Visible','True');
workbooks := OLE2.GET_OBJ_PROPERTY(application,'Workbooks');
workbook:=OLE2.INVOKE_OBJ(workbooks,'Add');
worksheets := OLE2.GET_OBJ_PROPERTY(workbook, 'Worksheets');
worksheet:=OLE2.INVOKE_OBJ(worksheets,'Add');
args:=OLE2.CREATE_ARGLIST;
OLE2.ADD_ARG(args, 4);
OLE2.ADD_ARG(args, 2);
cell := OLE2.GET_OBJ_PROPERTY(worksheet,'CELLS',args);
OLE2.DESTROY_ARGLIST(args); OLE2.Set_Property(cell, 'Value', 'Hello Excel!');
args:=OLE2.CREATE_ARGLIST; OLE2.ADD_ARG(args, 5);
OLE2.ADD_ARG(args, 3);
cell := OLE2.GET_OBJ_PROPERTY(worksheet,'CELLS',args);
OLE2.DESTROY_ARGLIST(args);
OLE2.Set_Property(cell, 'Value', 'Hello Excel!');
exception when others then FND_MESSAGE.DEBUG('ERROR:'||SQLERRM);
end;
说明:Object Link and embed,有学过VB/VC的同学们应该很熟悉。可惜ORACLE本身并不支持OLE2,OLE2是ORACLE FORMS集成的一个OLE接口。所以限制此方法的使用范围。另外更重要的OLE2无法在B/S架构中使用,只能在传统的FORM C/S程序中使用。
3. 使用ORACLE COM函数 这种方法就与通过extproc来实现与excle通信,这种方法直接与window api打交道。大致的的代码是:ordcom.CreateObject(‘Excel.Application‘, 0, servername,applicationToken); 测试了一下,似乎只能要求ORACLE的宿主系统必须是window。这也就有严重的局限性了。
4. 使用JAVA存储过程(通过POI包,这也是本文的重点)
4.1至http://poi.apache.org 下载POI包,注意与ORACLE JVM版本匹配(旧版本的POI下载:
http://archive.apache.org/dist/jakarta/poi/release/bin/)。至ORACL官网下载JDBC驱动,这一步不是必须的,一般安装ORACLE时,都有内置了JDBC包。
4.2 在ORACLE注册POI。
4.2.1先将POI包上传至ORACLE服务器。目录为:$ORACLE_HOME/javavm/lib ,例:/data/book/bookdb/9.2.0/javavm/lib,必须是javavm/lib这个目录或其下层目录。
4.2.2使用DBMS_JAVA注册
call dbms_java.loadjava('-r -v -definer -g public /data/book/bookdb/9.2.0/javavm/lib/poi-2.5.1-final-20040804.jar');
call dbms_java.loadjava('-r -v -definer -g public /data/book/bookdb/9.2.0/javavm/lib/poi-contrib-2.5.1-final-20040804.jar');
call dbms_java.loadjava('-r -v -definer -g public /data/book/bookdb/9.2.0/javavm/lib/poi-scratchpad-2.5.1-final-20040804.jar');
注:这个问题折腾了我很久,注册JAR包有两种方法。1.使用DBMS_JAVA,这种方法要自行上传jar包到服务器上。2.是使用loadjava。这也是能google到最多的方法,但loadjava在ORACLE9i以后就不单独提供了,而是集成在JDeveloper中,而可恶的JDeveloper是有版本兼容性的问题。
4.2.3查询一下是否注册成功(注:如果注册成功,STATUS应该为VALID)。
Select OBJECT_NAME, OBJECT_TYPE, STATUS, SYS.DBMS_JAVA.LONGNAME(OBJECT_NAME) LONGNAME, LAST_DDL_TIME, OBJECT_ID, uo.created
from sys.user_objects uo
where object_type in
('JAVA CLASS', 'JAVA SOURCE', 'JAVA RESOURCE', 'JAVA DATA')
and uo.object_name like '%poi%'
4.3创建JAVA SOURCE
create or replace and compile java source named testjdbc as
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.*;
import java.io.*;
public class TestJDBC{
public static void exportExcel(){
try{
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("new sheet");
wb.setSheetName( 0, "SomeUnicodeName", HSSFWorkbook.ENCODING_UTF_16 );
HSSFRow r = sheet.createRow( 0 );
HSSFCell c = r.createCell( (short)0 );
c.setCellValue("X中国");
// Write the output to a file FileOutputStream fileOut = new FileOutputStream("/data/book/k.xls");
wb.write(fileOut);
fileOut.close();
}catch(Exception e){
System.out.println("poi error :"+e);
e.printStackTrace();
}
}
}
4.4创建调用的PL/SQL包
create or replace package TestJDBC is
procedure exportExcel;
procedure insert_table(t varchar2);
function query_table return varchar2;
end TestJDBC;
create or replace package body TestJDBC is
procedure exportExcel is
language java name 'TestJDBC.exportExcel()';
end TestJDBC;
4.5测试PL/SQL块
begin
testjdbc.exportExcel;
end;
5. 使用其他编程语言操作 说明:此方法完全脱离了ORACLE,已超出了ORACLE的范围,本文不讨论。