Oracle APEX动态经典报表实现无跳转文件上传及动态类型扩展
Oracle APEX无跳转动态文件上传报表实现方案
一、表结构规范(可选优化)
如果表2尚未设置主键,建议新增type_id作为主键字段,表1的file_type字段关联此主键,确保数据关联的规范性。最终表结构示例:
- 表1:
id(主键/序列)、file_type(外键关联表2.type_id)、file_name(VARCHAR2)、content(BLOB) - 表2:
type_id(主键/序列)、file_type_name(VARCHAR2,存储“简历”“求职信”这类名称)
二、创建动态经典报表
- 新建经典报表,数据源直接查询表2,SQL语句:
SELECT type_id, file_type_name FROM 表2 ORDER BY type_id - 报表默认显示
file_type_name列;新增第二列,类型选择HTML表达式,用于渲染上传按钮。
三、实现无跳转上传按钮(核心)
1. 报表列嵌入上传控件
在第二列的HTML表达式中输入以下代码:
<input type="file" id="upload_&TYPE_ID." accept="*" style="display:none;" onchange="submitFile(&TYPE_ID., this)"> <button type="button" onclick="document.getElementById('upload_&TYPE_ID.').click()">上传&FILE_TYPE_NAME.</button>
&TYPE_ID.和&FILE_TYPE_NAME.是报表绑定变量,自动生成每行唯一的控件ID和按钮文本accept="*"支持所有文件类型,可按需修改为特定格式(如.pdf,.doc,.docx)
2. 编写AJAX上传JS函数
在页面的「函数和全局变量声明」中添加以下代码:
function submitFile(typeId, fileInput) { const file = fileInput.files[0]; if (!file) return; // 可选:文件大小限制(示例10MB) if (file.size > 10 * 1024 * 1024) { apex.message.showErrors([{message: '文件大小不能超过10MB'}]); fileInput.value = ''; return; } // 构造上传参数 const formData = new FormData(); formData.append('P_TYPE_ID', typeId); formData.append('P_UPLOAD_FILE', file); // 调用APEX AJAX进程 apex.server.process( 'UPLOAD_FILE_ACTION', // 对应后台AJAX进程名称 formData, { success: function(res) { if (res.status === 'success') { apex.message.showPageSuccess('上传成功'); // 可选:刷新报表同步状态 apex.region('你的报表区域ID').refresh(); } else { apex.message.showErrors([{message: '上传失败:' + res.msg}]); } }, error: function() { apex.message.showErrors([{message: '网络异常,请重试'}]); } } ); // 重置控件,允许重复选择同文件 fileInput.value = ''; }
3. 创建后台AJAX处理进程
进入页面「进程」菜单,新建AJAX回调类型进程,命名为UPLOAD_FILE_ACTION,PL/SQL代码如下:
DECLARE l_type_id NUMBER := apex_application.g_x01; l_file apex_application.t_blob_files := apex_application.g_blob_files; BEGIN -- 插入表1 INSERT INTO 表1 (id, file_type, file_name, content) VALUES (表1_SEQ.NEXTVAL, l_type_id, l_file(1).filename, l_file(1).blob_content); COMMIT; -- 返回成功响应 apex_json.open_object; apex_json.write('status', 'success'); apex_json.close_object; EXCEPTION WHEN OTHERS THEN apex_json.open_object; apex_json.write('status', 'error'); apex_json.write('msg', SQLERRM); apex_json.close_object; ROLLBACK; END;
注:表1_SEQ为表1主键的序列,需提前创建。
四、动态扩展实现
由于报表数据源直接查询表2,只要在表2中新增记录(如“成绩单”),刷新报表后会自动新增对应行和上传按钮,无需修改任何页面配置。
可选优化:显示上传状态
修改报表SQL,关联表1展示已上传状态:
SELECT t2.type_id, t2.file_type_name, CASE WHEN t1.id IS NOT NULL THEN '已上传' ELSE '未上传' END AS upload_status FROM 表2 t2 LEFT JOIN 表1 t1 ON t2.type_id = t1.file_type ORDER BY t2.type_id
在报表中新增upload_status列,即可直观查看各文件的上传状态。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

