Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2009.08.16;
Скачать: [xml.tar.bz2];

Вниз

BLOB->OLEConrtainer->File?   Найти похожие ветки 

 
GRAND ©   (2009-06-18 14:36) [0]

Здравствуйте, уважаемые! :)

Вот такая вот палка о двух концах у меня приключилась. Вобщем, имеется некий набор документов, хранимый в BLOB-полях таблицы с деревянной структурой (FB 1.5). Документы довольно разнообразны - там и Word, и PDF, и TIF и еще может быть все, что угодно. Когда я пытался отобразить содержимое документа в OLEContainer, то вылетала ошибка "Invalid stream format". Ну, думаю, нас не проведешь, мы не сдадимся - выгрузил все документы в файлы, после чего заставил OLEContainer эти файлы перечитать и зашарабанить их в базу заново (т.е. получается, что OLEContainer хавает только то, что когда-либо проходило через его "руки"). Все получилось, красота - документы хранятся, в контейнере отображаются, казалось бы, о чем еще мечтать? Ан нет, нарисовалась-таки проблемка. Захотел дать пользователю возможность выгружать любой документ из базы в произвольно заданный файл - и вот тут-то она ему и сказала. Файл создается, но никак не открывается потом родной для него программой. Причем, заметил, что если файл изначально был в формате Word 97-2003, то все работает и открывается, а вот *.docx, *.xlsx (MS Office 2007) и особенно *.pdf (львиная доля всех документов!) ни в какую. Получается, что я могу одно из двух: либо тупо хранить документы в базе без какой-либо возможности превью либо с превью, но без экспорта. Подскажите пожалуйста, как победить? Я понимаю, что формат данных OLE-контейнера от формата исходного файла отличается, но как же его все-таки заставить сохранять файлы в их первозданном виде?

P.S. SaveToFile, SaveAsDocument - результат один и тот же.


 
Игорь Шевченко ©   (2009-06-18 14:46) [1]

Знакомый вопрос :)

Blob save to stream не помогает ?


 
GRAND ©   (2009-06-18 14:49) [2]


> Blob save to stream не помогает ?


Привет, Игорь! А какой смысл блоб сохранять в потоке, если содержимое в конечном итоге нужно выплюнуть в файл (корректный файл)? Ну TMemoryStream, допустим, позволит сохранить себя в файле, но формат-то этого файла будет все равно не тот, который нужен.


 
Andy BitOff ©   (2009-06-18 14:51) [3]


> GRAND ©   (18.06.09 14:49) [2]
> но формат-то этого файла будет все равно не тот, который нужен

Это почему? Уже проверил?


 
GRAND ©   (2009-06-18 14:53) [4]

Да, уже проверил.


 
Игорь Шевченко ©   (2009-06-18 14:56) [5]

GRAND ©   (18.06.09 14:49) [2]

Привет, Володя!

Почему не тот формат ? FB у меня сейчас нету, а в оракле я тебе могу пример набросать :)


 
GRAND ©   (2009-06-18 15:00) [6]


> Почему не тот формат ? FB у меня сейчас нету, а в оракле
> я тебе могу пример набросать :)


Вообще-то оно абсолютно фиолетово, в какой базе это все хранится, и FB тут не при чем. Вопрос заключается в отличии форматов Ole-контейнера, потока и исходного файла. Если файл затянуть в блоб as is, то он не покажется в контейнере (превью не будет), а если протащить его через жернова контейнера, то его формат изменится! И потом выкинутые из блоба снова в файл данные уже бесполезны, т.к. не открываются. Поэтому, Игорь, если ты сможешь набросать примерчик, где все то, что нужно, будет работать хоть в Оракле, хоть в Постгре, то буду тебе очень благодарен!


 
GRAND ©   (2009-06-18 15:03) [7]

Вот так файл затягивается в базу через контейнер:

 Var
   St : TStream;
begin
 St:=DM.tbClDocs.CreateBlobStream(DM.tbClDocsCD_BODY,bmReadWrite);
 If OpenDialog1.Execute Then
   Begin
     cxButtonEdit1.Text:=OpenDialog1.FileName;
     Screen.Cursor:=crHourGlass;
     If Not (DM.tbClDocs.State In [dsInsert, dsEdit]) Then DM.tbClDocs.Edit;
     OLEContainer1.CreateObjectFromFile(OpenDialog1.FileName,False);
     OLEContainer1.SaveToStream(St);
     DM.tbClDocsCD_STATE.AsInteger:=1;
     DM.tbClDocsCD_EXT.AsString:=ExtractFileExt(OpenDialog1.FileName);
     Screen.Cursor:=crDefault
   End;
 St.Free
end;


OLEContainer1.SaveToStream(St) - это одновременно и сохранение файла в блоб. Далее, уже за пределами этого обработчика, производится Post и вуа-ля.


 
Игорь Шевченко ©   (2009-06-18 16:23) [8]

Насчет примера - у меня не получается загрузить файл в OleContainer, причем, даже в примере из Demos - приложение висит. Оказывается, проблема известная и на experts-exchange не решенная.

Сам пример:
1. Таблица в базе:
CREATE TABLE files_data (
 name VARCHAR2(40) NOT NULL,
 data BLOB,
 CONSTRAINT files_data_pk PRIMARY KEY(name) USING INDEX TABLESPACE hs_idx
) TABLESPACE hs_dat
/


2. Главная форма

unit main;

interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, Menus, Grids, DBGridEh, OleCtnrs;

type
 TfMain = class(TForm)
   MainMenu1: TMainMenu;
   File1: TMenuItem;
   Open1: TMenuItem;
   Saveas1: TMenuItem;
   Preview1: TMenuItem;
   N1: TMenuItem;
   Exit1: TMenuItem;
   Grid: TDBGridEh;
   OpenDialog1: TOpenDialog;
   SaveDialog1: TSaveDialog;
   OleContainer1: TOleContainer;
   procedure Exit1Click(Sender: TObject);
   procedure FormShow(Sender: TObject);
   procedure Open1Click(Sender: TObject);
   procedure Saveas1Click(Sender: TObject);
   procedure Preview1Click(Sender: TObject);
   procedure OleContainer1Activate(Sender: TObject);
 end;

var
 fMain: TfMain;

implementation
uses
 data;

{$R *.dfm}

procedure TfMain.Exit1Click(Sender: TObject);
begin
 Close;
end;

procedure TfMain.FormShow(Sender: TObject);
begin
 OleContainer1.Visible := false;
 Grid.DataSource := dm.dsData;
end;

procedure TfMain.OleContainer1Activate(Sender: TObject);
begin
 OleContainer1.Modified := True;
end;

procedure TfMain.Open1Click(Sender: TObject);
begin
 with OpenDialog1 do
   if Execute then
     dm.LoadFile(FileName);
end;

procedure TfMain.Preview1Click(Sender: TObject);
begin
 with OpenDialog1 do
 if Execute then
 begin
   OLEContainer1.CreateObjectFromFile(dm.GetSavedTempFileName, false);
   OleContainer1.Visible := true;
 end;
end;

procedure TfMain.Saveas1Click(Sender: TObject);
begin
 with SaveDialog1 do
 begin
   FileName := Grid.DataSource.DataSet.FieldByName("name").AsString;
   if Execute then
     dm.SaveFile(FileName);
 end;
end;

end.


датамодуль:

unit data;

interface
uses
 SysUtils, Classes, DB, hsOraCursor, hsOraDataSet, hsOraDatabase;

type
 Tdm = class(TDataModule)
   db: ThsOraDatabase;
   qData: ThsOraDataSet;
   qDataNAME: TStringField;
   qDataDATA: TOraMemoField;
   dsData: TDataSource;
   qInsert: ThsOraDataSet;
   qUpdateBlob: ThsOraDataSet;
   procedure DataModuleCreate(Sender: TObject);
 public
   procedure LoadFile (const FileName: string);
   procedure SaveFile (const FileName: string);
   function GetSavedTempFileName: string;
 end;

var
 dm: Tdm;

implementation
uses
 Windows;

{$R *.dfm}

procedure Tdm.DataModuleCreate(Sender: TObject);
begin
 db.Open;
 qData.Open;
end;

function Tdm.GetSavedTempFileName: string;
var
 L: Integer;
 F: TFileStream;
begin
 Setlength(Result, MAX_PATH);
 L := GetTempPath(MAX_PATH, PChar(Result));
 if L > 0 then
 begin
   SetLength(Result, L);
   Result := IncludeTrailingPathDelimiter(Result) +
     qData.FieldByName("name").AsString;
   F := TFileStream.Create(Result, fmCreate);
   try
     TBlobField(qData.FieldByName("data")).SaveToStream(F);
   finally
     F.Free;
   end;
 end;
end;

procedure Tdm.LoadFile(const FileName: string);
var
 F: TFileStream;
 N, E: string;
begin
 E := ExtractFileExt(FileName); //. тъы■ўхэр
 N := Copy(ChangeFileExt(ExtractFileName(FileName), ""), 1, 40-Length(E))+E;
 qInsert.ParamByName("name").AsString := N;
 qInsert.ExecSQL;
 F := TFileStream.Create(FileName, fmOpenRead);
 try
   qUpdateBlob.ParamByName("name").AsString := N;
   qUpdateBlob.ParamByName("data").LoadFromStream(F, ftBlob);
   qUpdateBlob.ExecSQL;
   db.Commit;
   qData.Close;
   qData.Open;
 finally
   F.Free;
 end;
end;

procedure Tdm.SaveFile(const FileName: string);
var
 F: TFileStream;
begin
 F := TFileStream.Create(FileName, fmCreate);
 try
   TBlobField(qData.FieldByName("data")).SaveToStream(F);
 finally
   F.Free;
 end;
end;

end.


запросы:

qData.SQL - "SELECT name,data FROM files_data ORDER BY name"
qInsert.SQL - "INSERT INTO files_data (name) VALUES (:name)"
qUpdateBlob.SQL - "UPDATE files_data SET data = :data WHERE name = :name
                         RETURNING data INTO :data"

Сохраненный файл до бита идентичен загруженному


 
GRAND ©   (2009-06-19 10:05) [9]

Игорь, спасибо тебе большое за проделанную работу! Вчера не смог отреагировать, т.к. был срочно выдернут на совещание, продлившееся до глубокого вечера. Сегодня попробовал действовать по твоей схеме и напоролся на проблему с OLEContainer, которую уже проходил ранее. Проблема вот в чем: при организации превью файл через TFileStream создается, он железно лежит там, где ему и положено лежать, своей родной программой открывается, но при попытке грузануть его в контейнер через CreateObjectFromFile вылетает EOleSysError: "Не удается найте %1". Что это за хрень, я не знаю, предположил только лишь, что это чем-то похоже на запуск чего-то с параметром (как в bat"ах пишут, помнишь? %1 %2...). Вот как с этим быть? У тебя контейнер все показывает и ничего эдакого не выдает?


 
Игорь Шевченко ©   (2009-06-19 10:37) [10]

GRAND ©   (19.06.09 10:05) [9]

Володя, у меня не получается вообще загрузить файл в контейнер :) Никакой, хоть с диска, хоть из базы.

ситуация аналогичная

http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_23747098.html


 
GRAND ©   (2009-06-19 10:58) [11]


> Володя, у меня не получается вообще загрузить файл в контейнер
> :) Никакой, хоть с диска, хоть из базы.


Вон, выше я привел код, где файл грузится в контейнер :)


 
GRAND ©   (2009-06-19 11:03) [12]

Наверное придется-таки грузить файл в 2 блоба - один будет хранить его в олешном виде, а другой в исходном.  ППЦ!!! :)))


 
GRAND ©   (2009-06-19 11:11) [13]

Еще глюк: иногда при попытке открыть филе из контейнера (по дабл-клику) вылазит ошибка "Не удается открыть файл при помощи специального имени". Это еще че, блин, такое?


 
Игорь Шевченко ©   (2009-06-19 11:32) [14]

GRAND ©   (19.06.09 10:58) [11]

Ты ссылку-то прочитай :)


 
GRAND ©   (2009-06-19 11:55) [15]


> Ты ссылку-то прочитай :)


Ну и? Беру спокойно pdf (не MS Office, правда?), гружу и вижу его в контейнере!


 
Игорь Шевченко ©   (2009-06-19 12:13) [16]

GRAND ©   (19.06.09 11:55) [15]

А я не вижу, я зависаю. Об чем написано в ссылке "on some pc"

Потому не могу тебя проконсультировать по поведению OleContainer. Я знаю, что выгруженный из базы в моем примере файл идентичен загруженному (сравнивалось по fc /b), чего тебе тоже рекомендую - сравнить, что выходит из OleContainer, то, что сохраняется твоей выгрузкой из базы и то, что загружается в базу.


 
GRAND ©   (2009-06-19 12:57) [17]


> А я не вижу, я зависаю. Об чем написано в ссылке "on some
> pc"


И если написать обработчик так, как у меня, тоже виснешь?


 
Игорь Шевченко ©   (2009-06-19 13:06) [18]

GRAND ©   (19.06.09 12:57) [17]

Я висну даже на примере из Demos


 
GRAND ©   (2009-06-19 14:20) [19]

Как все запущено! :)

Ну, а у меня наконец-то все заработало, ура! Теперь вот чешу репу, возможен ли в контейнере мультистраничный просмотр или ну его на фиг?



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2009.08.16;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.011 c
15-1244611324
pasha_golub
2009-06-10 09:22
2009.08.16
Не пойму сути компонентов а-ля TTransaction


15-1245251682
Kerk
2009-06-17 19:14
2009.08.16
Посоветуйте аналоги Visio


2-1245310159
abhtr
2009-06-18 11:29
2009.08.16
Как распечатать текст из TMemo?


2-1245284214
<AIRDIGER>
2009-06-18 04:16
2009.08.16
web сторку к норамальному пути


1-1211907969
Smart
2008-05-27 21:06
2009.08.16
Нужен алгоритм.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский