Файловете на Microsoft Word и Excel не са текстови файлове, в които можете просто да замените текст и които определено няма да работят с BLOB
. docx и xlsx файловете всъщност са zip файлове (опитайте да промените файловото разширение и да разархивирате, за да видите сами), които съдържат XML дефиниция на документа. Така че ще трябва да:
- Разархивирайте файла
- Конвертирайте файла, който трябва да бъде променен от
BLOB
къмCLOB
- Променете съдържанието на правилния XML файл
- Конвертирайте файла обратно в
BLOB
отCLOB
- Добавете модифицирания файл обратно в 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;