【问题标题】:Find and replace string inside BLOB for Work or Excel File在 BLOB for Work 或 Excel 文件中查找和替换字符串
【发布时间】:2021-02-24 18:41:58
【问题描述】:

我需要查找和替换存储在数据库中的数千个文档中过时的超链接。

目前我有一些函数可以将 BLOB 转换为 CLOB 进行查找和替换,然后再转换回 BLOB。

但最终结果不会使文件保持其原始状态,例如我存储了一个 word 文档,我找到超链接 www.google.co.uk 并替换,BLOB 数据不再是 word 文档类型,我无法打开它。

是否有推荐的方法来执行上述操作。

非常感谢,

【问题讨论】:

    标签: oracle plsql replace blob


    【解决方案1】:

    Microsoft Word 和 Excel 文件不是文本文件,您只能在上面替换文本,而且绝对不能与 BLOB 一起使用。 docxxlsx 文件实际上是包含文档的 XML 定义的 zip 文件(尝试更改文件扩展名并解压缩以查看)。所以你需要:

    1. 解压文件
    2. 将需要更改的文件从BLOB 转换为CLOB
    3. 修改适当的 XML 文件的内容
    4. 将文件从CLOB 转换回BLOB
    5. 将修改后的文件重新添加到 zip 文件中

    我编写了下面的代码作为如何替换 docx 文件的示例。对于 xlsx 文件,每个 Excel 工作表都包含在不同的 XML 文件中,因此您需要稍微修改代码以使其适用于两种文件类型。

    代码确实使用了APEX_ZIP 包,它极大地简化了对 zip 文件的处理,并使示例代码更清楚地了解正在发生的事情。如果您没有安装 APEX,则需要弄清楚如何使用您拥有的 Oracle 包对文件进行解压缩/重新压缩。

    DECLARE
        l_old_file       BLOB;
        l_new_file       BLOB;
        l_files          apex_zip.t_files;
        l_document       BLOB;
        l_clob           CLOB;
        l_dest_offsset   INTEGER;
        l_src_offsset    INTEGER;
        l_lang_context   INTEGER := DBMS_LOB.default_lang_ctx;
        l_warning        INTEGER;
    BEGIN
        -- Get the blob you want to "correct"
        SELECT blob_content
          INTO l_old_file
          FROM apex_application_temp_files
         WHERE ROWNUM = 1;
    
        -- Get a list of all the file names contained within the zip
        l_files := apex_zip.get_files (l_old_file);
    
        -- Loop through all the files adding each one to the new zip
        FOR i IN l_files.FIRST .. l_files.LAST
        LOOP
            l_document := apex_zip.get_file_content (l_old_file, l_files (i));
    
            IF l_files (i) = 'word/document.xml'
            THEN
                -- if the file name is word/document.xml then make the changes to it
                
                DBMS_LOB.createTemporary (lob_loc => l_clob, cache => FALSE);
    
                l_dest_offsset := 1;
                l_src_offsset := 1;
    
                DBMS_LOB.converttoclob (dest_lob       => l_clob,
                                        src_blob       => l_document,
                                        amount         => DBMS_LOB.lobmaxsize,
                                        dest_offset    => l_dest_offsset,
                                        src_offset     => l_src_offsset,
                                        blob_csid      => DBMS_LOB.default_csid,
                                        lang_context   => l_lang_context,
                                        warning        => l_warning);
    
                --------------------
                -- This is where you would do any replacements
                --------------------
                l_clob := REPLACE (l_clob, 'www.google.co.uk', 'www.google.com');
                --------------------
    
                l_dest_offsset := 1;
                l_src_offsset := 1;
    
                DBMS_LOB.CONVERTTOBLOB (dest_lob       => l_document,
                                        src_clob       => l_clob,
                                        amount         => DBMS_LOB.lobmaxsize,
                                        dest_offset    => l_dest_offsset,
                                        src_offset     => l_src_offsset,
                                        blob_csid      => DBMS_LOB.default_csid,
                                        lang_context   => l_lang_context,
                                        warning        => l_warning);
            END IF;
    
            apex_zip.add_file (l_new_file, l_files (i), l_document);
        END LOOP;
    
        apex_zip.finish (l_new_file);
        --Do whatever you want with the "new" file here
    END;
    

    【讨论】:

    • 我似乎遇到了 blob 文件似乎损坏的问题,例如Word 文档文件将无法打开和引用的权限错误、空间问题和/或使用文本恢复工具。
    • 这可能有几个原因。您如何解压缩/重新压缩文件?如果您下载“新文件”,将扩展名更改为.zip 并尝试解压,是否解压成功,修改后的 XML 文件是否如您所愿?
    • 感谢您的回复,目前我所做的只是使用 l_new_file 在您提到的 apex_zip.finish 部分之后直接更新表 BLOB 值。我已经做了一个 dbms_output 来显示在 clob 上替换之前和之后的 xml 字符串,并且看不到任何差异。
    猜你喜欢
    • 2011-05-25
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 2020-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多