Oracle
 sql >> Base de données >  >> RDS >> Oracle

Rechercher et remplacer une chaîne dans BLOB for Work ou Excel File

Les fichiers Microsoft Word et Excel ne sont pas des fichiers texte sur lesquels vous pouvez simplement remplacer du texte et qui ne fonctionneront certainement pas avec un BLOB . docx et xlsx Les fichiers sont en fait des fichiers zip (essayez de changer l'extension de fichier et de décompresser pour voir par vous-même) qui contiennent une définition XML du document. Vous devrez donc :

  1. Décompressez le fichier
  2. Convertir le fichier à modifier à partir d'un BLOB à un CLOB
  3. Modifier le contenu du fichier XML approprié
  4. Reconvertir le fichier en BLOB depuis un CLOB
  5. Ajouter le fichier modifié dans le fichier zip

J'ai écrit le code ci-dessous comme exemple sur la façon de remplacer un docx dossier. Pour xlsx fichiers, chaque feuille Excel est contenue dans un fichier XML différent, vous devrez donc modifier légèrement le code pour qu'il fonctionne avec les deux types de fichiers.

Le code utilise le APEX_ZIP package qui simplifie grandement le travail avec les fichiers zip et rend également l'exemple de code un peu plus clair quant à ce qui se passe. Si APEX n'est pas installé, vous devrez trouver comment décompresser/recommencer les fichiers à l'aide des packages Oracle dont vous disposez.

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;