You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle APEX中如何为生成的PDF附加XML文件?

在Oracle APEX中为PDF附加XML附件的实现方案

方法1:Java存储过程 + iText(推荐)

iText是成熟的PDF处理库,通过Java存储过程集成到Oracle数据库后,能轻松实现PDF附件添加:

  1. 部署iText库:将iText的jar包(如itextpdf-5.5.13.jar)加载到Oracle数据库中(需DBA权限,使用loadjava命令)。
  2. 创建Java处理类:
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfFileSpecification;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

public class PdfAttacher {
    public static byte[] attachXml(byte[] pdfData, byte[] xmlData, String xmlFileName) throws Exception {
        PdfReader reader = new PdfReader(new ByteArrayInputStream(pdfData));
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        PdfStamper stamper = new PdfStamper(reader, outputStream);
        
        // 嵌入XML附件
        PdfFileSpecification attachment = PdfFileSpecification.fileEmbedded(
            stamper.getWriter(), null, xmlFileName, xmlData
        );
        stamper.addFileAttachment(attachment);
        
        stamper.close();
        reader.close();
        return outputStream.toByteArray();
    }
}
  1. 创建PL/SQL包装函数:
CREATE OR REPLACE FUNCTION ATTACH_XML_TO_PDF(
    p_pdf_blob IN BLOB,
    p_xml_blob IN BLOB,
    p_xml_filename IN VARCHAR2
) RETURN BLOB
IS
    LANGUAGE JAVA NAME 'PdfAttacher.attachXml(byte[], byte[], java.lang.String) return byte[]';
/
  1. 在APEX中调用:
    • 先获取生成好的PDF BLOB(比如通过APEX_PDF生成,或从表中读取)。
    • 获取要附加的XML BLOB(可通过APEX_DATA_EXPORT生成,或从XMLType转换)。
    • 调用函数得到带附件的PDF,再通过APEX_UTIL.DOWNLOAD_BLOB提供下载:
      DECLARE
          l_pdf BLOB;
          l_xml BLOB;
          l_final_pdf BLOB;
      BEGIN
          -- 假设从表中读取PDF和XML
          SELECT pdf_content INTO l_pdf FROM pdf_table WHERE id = 1;
          SELECT xml_content INTO l_xml FROM xml_table WHERE id = 1;
          
          l_final_pdf := ATTACH_XML_TO_PDF(l_pdf, l_xml, 'data.xml');
          
          -- 输出给用户下载
          APEX_UTIL.DOWNLOAD_BLOB(
              p_content_type => 'application/pdf',
              p_blob => l_final_pdf,
              p_filename => 'document_with_attachment.pdf'
          );
      END;
      

方法2:命令行工具 + APEX外部进程

如果服务器允许执行外部命令,可使用开源工具pdftk(PDF Toolkit):

  1. 安装pdftk:在APEX应用服务器上安装pdftk。
  2. 配置数据库权限:
    • 创建UTL_FILE可用的临时目录,授予读写权限。
    • 确保DBMS_SCHEDULER能执行外部命令。
  3. PL/SQL调用逻辑:
    DECLARE
        l_temp_pdf_dir VARCHAR2(100) := 'TEMP_PDF_DIR';
        l_temp_pdf_path VARCHAR2(200) := 'temp.pdf';
        l_temp_xml_path VARCHAR2(200) := 'attachment.xml';
        l_output_path VARCHAR2(200) := 'final.pdf';
        l_final_pdf BLOB;
    BEGIN
        -- 将PDF和XML写入临时文件
        UTL_FILE.PUT_RAW(UTL_FILE.FOPEN(l_temp_pdf_dir, l_temp_pdf_path, 'WB'), p_pdf_blob);
        UTL_FILE.PUT_RAW(UTL_FILE.FOPEN(l_temp_pdf_dir, l_temp_xml_path, 'WB'), p_xml_blob);
        
        -- 调用pdftk添加附件
        DBMS_SCHEDULER.CREATE_JOB(
            job_name => 'ADD_PDF_ATTACH_JOB',
            job_type => 'EXECUTABLE',
            job_action => '/usr/bin/pdftk',
            arguments => l_temp_pdf_path || ' attach_files ' || l_temp_xml_path || ' output ' || l_output_path,
            job_class => 'DEFAULT_JOB_CLASS',
            enabled => TRUE,
            auto_drop => TRUE
        );
        
        -- 等待任务完成后读取结果BLOB(需添加等待逻辑或异步处理)
        -- 示例读取逻辑
        l_final_pdf := UTL_FILE.GET_BLOB(l_temp_pdf_dir, l_output_path);
        
        -- 输出下载
        APEX_UTIL.DOWNLOAD_BLOB(
            p_content_type => 'application/pdf',
            p_blob => l_final_pdf,
            p_filename => 'document_with_xml.pdf'
        );
    END;
    
可用工具选项
  • iText:功能全面,支持复杂PDF操作,适合集成到数据库内部处理,无外部依赖(除了jar包)。
  • pdftk:轻量命令行工具,语法简单,适合快速实现,但需要服务器权限支持。
  • PL_PDF:纯PL/SQL的PDF处理包,无需Java环境,直接在Oracle中使用,需自行下载安装。

内容的提问来源于stack exchange,提问作者Rana mari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 04:35:56