Microsoft Word- og Excel-filer er ikke tekstfiler, som du bare kan erstatte tekst på, og som bestemt ikke vil fungere med en BLOB
. docx og xlsx filer er faktisk zip-filer (prøv at ændre filtypenavnet og pakke ud for at se selv), der indeholder en XML-definition af dokumentet. Så du skal:
- Udpak filen
- Konverter den fil, der skal ændres, fra en
BLOB
til enCLOB
- Rediger indholdet af den korrekte XML-fil
- Konverter filen tilbage til en
BLOB
fra enCLOB
- Tilføj den ændrede fil tilbage til zip-filen
Jeg har skrevet koden nedenfor som et eksempel på, hvordan man laver en erstatning til en docx fil. Til xlsx filer, er hvert Excel-ark indeholdt i en anden XML-fil, så du bliver nødt til at ændre koden lidt for at få den til at fungere med begge filtyper.
Koden bruger APEX_ZIP pakke, som i høj grad forenkler arbejdet med zip-filer og også gør eksempelkoden en smule tydeligere med hensyn til, hvad der foregår. Hvis du ikke har APEX installeret, skal du finde ud af, hvordan du udpakker/genpakker filerne ved hjælp af de Oracle-pakker, du har.
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;