Topic: вставить изображение в word документ

Всем Добрый
Кто нибудь уже задавался вопросом вставки изображение с таблицы в word документ?
На данный момент имеется таблица Client, в таблице колонка Photo
Я использую SQLQuery для заготовленного уже шаблона word, для последующей замены текста шаблона на данные с таблицы
Само собой функция Word.FindAndReplace ругается на слишком длинный строковый параметр в замене {Photo}
может кто знает и может подсказать какую функцию правильно будет использовать или пример?

procedure PrintClient(idClient: integer);
var
    Word: TWord;
    sName, sAddress, sPhone, sEmail: string;
    sWordTemp: string;
    sWordFinal: string;

    ResultsPhotoClient: TDataSet;
    ResultsClient: TDataSet;
begin
    SQLQuery('SELECT Photo, Photo_filename FROM Client WHERE Client.id='+IntToStr(idClient), ResultsPhotoClient);
    SQLQuery('SELECT ClientName FROM Client WHERE Client.id='+IntToStr(idClient), ResultsClient);
    sWordTemp  := ExtractFilePath(Application.ExeName)+'\WordTemplate\template2.doc';
    sWordFinal := GetEnvironmentVariable('TEMP') + '\'+ResultsClient.FieldByName('ClientName').AsString+' - '+FormatDateTime('dd.mm.yyy', now)+'.doc';
    CopyFile(sWordTemp, sWordFinal);

    Word := TWord.Create;
    Word.Visible := True;
    Word.Open(sWordFinal);

    Word.FindAndReplace('{Photo}',  ResultsPhotoClient.FieldByName('Photo').AsString );
    Word.FindAndReplace('{ClientName}',  ResultsClient.FieldByName('ClientName').AsString );

на просторах интернета нашел вот такой образец, но пока не удается прикрутить в MVD

uses
  ComObj;
 
procedure TForm1.Button1Click(Sender: TObject);
const
  //Имя файла шаблона и изображения.
  FnDoc = 'Шаблон.doc';
  FnPic = 'Изображение.bmp';
 
  //Продолжить поиск.
  wdFindContinue = 1;
 
  //Виды расположения текста относительно изображения.
  wdWrapInline = 7;
  wdWrapNone = 3;
  wdWrapSquare = 0;
  wdWrapThrough = 2;
  wdWrapTight = 1;
  wdWrapTopBottom = 4;
var
  wdApp, wdDoc, wdRng, wdSh : Variant;
  FNameDoc, FNamePic : String;
  Cnt : Integer;
begin
  //Путь к файлу шаблона. Предполагаем, что файл шаблона лежит в папке с программой.
  FNameDoc := ExtractFilePath(ParamStr(0)) + FnDoc;
  if not FileExists(FNameDoc) then begin
    MessageBox(0, 'Файл шаблона не найден. Действие отменено.',
      'Ошибка', MB_OK + MB_ICONERROR + MB_APPLMODAL);
    Exit;
  end;
  //Путь к файлу изображения. Предполагаем, что файл изображения лежит в папке с программой.
  FNamePic := ExtractFilePath(ParamStr(0)) + FnPic;
  if not FileExists(FNamePic) then begin
    MessageBox(0, 'Файл изображения не найден. Действие отменено.',
      'Ошибка', MB_OK + MB_ICONERROR + MB_APPLMODAL);
    Exit;
  end;
 
  //Запуск MS Word и подключение к его корневому объекту.
  try
    wdApp := CreateOleObject('Word.Application');
  except
    MessageBox(0, 'Не удалось запустить MS Word. Действие отменено.',
      'Ошибка', MB_OK + MB_ICONERROR + MB_APPLMODAL);
    Exit;
  end;
 
  wdApp.Visible := True;
  wdApp.DisplayAlerts := False; //Отключить режим показа предупреждений.
  try
    wdDoc := wdApp.Documents.Open(FNameDoc);
    wdRng := wdDoc.Content; //Диапазон, охватывающий всё содержимое документа.
 
    //Настройка поиска.
    wdRng.Find.ClearFormatting;
    wdRng.Find.Text := '<PICTURE>';
    //True - начать поиск сначала документа.
    wdRng.Find.Forward := True;
    //wdFindContinue - продолжать поиск "по кругу" с текущего места.
    wdRng.Find.Wrap := wdFindContinue;
    //False - не учитывать регистр букв.
    wdRng.Find.MatchCase := False;
    //False - шаблон может не являться отдельным словом.
    wdRng.Find.MatchWholeWord := False;
 
    //Поиск шаблона и замена его на изображение.
    Cnt := 0;
    while wdRng.Find.Execute do begin
      Inc(Cnt);
      //Стираем найденный текст.
      wdRng.Text := '';
      //Поиск следующего совпадения начинать с текущего места.
      if Cnt = 1 then wdRng.Find.Forward := False;
      //Создаём фигуру с изображением. Изображение грузим из файла и привязываем
      //его к началу найденного диапазона.
      wdSh := wdDoc.Shapes.AddPicture(FileName:=FNamePic,
        LinkToFile:=False, SaveWithDocument:=True, Anchor:=wdRng);
      //На всякий случай добавляем вверху диапазона (перед картинкой) знаки
      //перевода строки.
      wdRng.InsertBefore(#13#10);
      //Расположение текста вокруг изображения: wdWrapTopBottom - только сверху и снизу.
      wdSh.WrapFormat.Type := wdWrapTopBottom
    end;
  finally
    wdApp.DisplayAlerts := True; //Включение режима показа предупреждений.
  end;
end;

Re: вставить изображение в word документ

Добавил для класса TWord метод FindAndInsertPicture
Скачайте пожалуйста последнюю бета версию 6.4
https://www.dropbox.com/s/vyne4lvinpjzl … a.zip?dl=0


пример

Word.FindAndInsertPicture('{photo}',  'c:\picture.jpg');

Но необходимо указывать имя файла на диске.


В вашем примере вы пытаетесь вставить изображение из ResultsPhotoClient.FieldByName('Photo').AsString
что неправильно. Если вы сохраняете изображение непосредственно в базе данных, то сперва необходимо данное изображение сохранить в файл на диск.

Dmitry.

3 (edited by eugene1995miroshnikov 2020-04-11 21:26:04)

Re: вставить изображение в word документ

DriveSoft wrote:

Добавил для класса TWord метод FindAndInsertPicture
Скачайте пожалуйста последнюю бета версию 6.4
https://www.dropbox.com/s/vyne4lvinpjzl … a.zip?dl=0


пример

Word.FindAndInsertPicture('{photo}',  'c:\picture.jpg');

Но необходимо указывать имя файла на диске.


В вашем примере вы пытаетесь вставить изображение из ResultsPhotoClient.FieldByName('Photo').AsString
что неправильно. Если вы сохраняете изображение непосредственно в базе данных, то сперва необходимо данное изображение сохранить в файл на диск.

Спасибо большое за все возможности вашей программа, очень нравится
Завтра уже опробую новый метод..

Скажите пожалуйста как мне правильно получить имя файла на диске?
В Данный момент DBImage1 (свойства CopyTo =  \Фото ; Type = LinkFile )
Загрузка изображения в базу может происходить с любого места на диске (с помощью свойства 'CopyTo =  \Фото' изображение копируется в папку с программой), так вот как получать имя файла на диске именно которое скопировалось в папку с программой? При условии что изображение загружалось с другого места

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

4 (edited by derek 2020-04-12 00:41:11)

Re: вставить изображение в word документ

Здравствуй Eugene,
Я не уверен, правильно ли я понимаю ваш вопрос (с помощью переводчика Google), но помогает ли это вам?
С уважением,
Derek.

Post's attachments

Attachment icon photofilename.zip 805.16 kb, 270 downloads since 2020-04-12 

5 (edited by eugene1995miroshnikov 2020-04-12 14:00:49)

Re: вставить изображение в word документ

derek wrote:

Здравствуй Eugene,
Я не уверен, правильно ли я понимаю ваш вопрос (с помощью переводчика Google), но помогает ли это вам?
С уважением,
Derek.

Thank You, Derek, but I can’t understand how use in SQLite script
I create column 'PhotoFile (Calculated:photo_filename \r\n)' in Table 'Client'
Script:

 
var
PhotoFile: string;
begin
    PhotoFile:=SQLExecute('SELECT PhotoFile FROM Client WHERE id='+IntToStr(Form1.gridClient.dbItemID));
    Word.FindAndInsertPicture('{Photo}', '+IntToStr(PhotoFile)');

Don't work (error - no such column: PhotoFile)

Script:

procedure PrintClientCard(idClient: integer); 
var
ResultsClientPhoto: TDataSet;
begin
    SQLQuery('SELECT PhotoFile FROM Client WHERE Client.id='+IntToStr(idClient), ResultsClientPhoto);
    Word.FindAndInsertPicture('{Photo}', ResultsClientPhoto.FieldByName('PhotoFile').AsString);
    ResultsClientPhoto.Free;

Don't work (error - no such column: PhotoFile)
Whats Wrong?

P.S. Sorry for my english...

Re: вставить изображение в word документ

Привет,
Когда вы используете опцию 'link file' для хранения фотографий, MVD создает в вашей таблице внутреннее поле (имя_файла_файла) для хранения местоположения и имени файла. Вы не можете обратиться к этому внутреннему полю напрямую, поэтому я использую вычисляемое поле.
Однако вычисляемые поля не хранятся в базе данных - они являются временными только во время работы программы. Поэтому вы не можете использовать вычисляемые поля в скрипте.
Итак, если вы хотите сослаться на имя файла, вам сначала нужно скопировать внутреннее поле (имя_файла_файла) в определенное пользователем поле (в моем примере test.photofilename). Тогда остальная часть вашего сценария должна работать нормально.
Я предпочитаю использовать вычисляемые поля, где это возможно, потому что это более эффективно для данных, но на самом деле это просто личное предпочтение.
Это звучит сложнее, чем есть на самом деле - взгляните на вложение (где я заменил вычисляемое поле пользовательским полем).
С Уважением,
Derek.
.
When you use the 'link file' option to store photos, MVD creates an internal field (photo_filename) in your table to hold the location and filename.  You can't refer to this internal field directly which is why I use a calculated field.
However, calculated fields are not held in the database - they are only temporary while the program is running.  Therefore you cannot use calculated fields in a script.
So, if you want to refer to the filename,  you first need to copy the internal field (photo_filename) to a user defined field (in my example test.photofilename).  Then the rest of your script should work okay.
I prefer to use calculated fields, where possible, because it is more data efficient, but it's really just a personal preference.
This sounds  more complicated than it actually is - have a look at the attachment (where I have replaced the calculated field with a user defined field).

Post's attachments

Attachment icon photofilename2.zip 805.56 kb, 281 downloads since 2020-04-12 

Re: вставить изображение в word документ

Я запутался, поэтому все это привело к ошибкам
На самом деле в первом посте я правильный запрос указал

SQLQuery('SELECT Photo, [b]Photo_filename[/b] FROM Client WHERE Client.id='+IntToStr(idClient), ResultsPhotoClient);

Необходимо было лишь добавить свойства в DBImage ---> Что я и сделал в третьем посте после поста DriveSoft'a

В Данный момент DBImage1 (свойства CopyTo =  \Фото ; Type = LinkFile ) 

Далее я начал работать с примером derek'a четвертый пост, но немного не то... запрос в SQLite скриптом я уже правильно сделал
Далее

var
ResultsClientPhoto: TDataSet;
begin
SQLQuery('SELECT Photo, [b]''C:\MyProject'' ||[/b] Photo_filename FROM Client WHERE Client.id='+IntToStr(idClient), ResultsClientPhoto);

Word.FindAndInsertPicture('{Photo}', ResultsClientPhoto.FieldByName('[b]''C:\MyProject'' ||[/b] Photo_filename').AsString);
end;

  все получается, изображение ставится в шаблон word, но как мне изменить то что жирным выделено (это путь до самого проекта)
  как можно заменить чтобы не прописывать путь до программы? Чтобы было ExtractFilePath(Application.ExeName)
  каким способом можно прикрутить?

изображение вставляется полным размером, возможно ли изменить пропорции?

Re: вставить изображение в word документ

Thank you, I'll see an example tomorrow
I just got confused, but now I figured it out and understand ...
at the moment the problem is
1. Getting the path to the program with the project

SQLQuery('SELECT Photo, ''C:\MyProject'' || Photo_filename FROM Client WHERE Client.id='+IntToStr(idClient), ResultsClientPhoto);

How can I replace with function ''C:\MyProject'' || Photo_filename  on ExtractFilePath(Application.ExeName)

 Word.FindAndInsertPicture('{Photo}', ResultsClientPhoto.FieldByName('''C:\MyProject'' || Photo_filename').AsString);

so as not to prescribe the path to the program itself
2. The image is inserted in full size, I would like to change / reduce the size while maintaining the aspect ratio

P.S. Sorry for my English

Re: вставить изображение в word документ

Thank you, derek, I looked at your example, there is no problem

Re: вставить изображение в word документ

DriveSoft wrote:

Добавил для класса TWord метод FindAndInsertPicture
Скачайте пожалуйста последнюю бета версию 6.4
https://www.dropbox.com/s/vyne4lvinpjzl … a.zip?dl=0


пример

Word.FindAndInsertPicture('{photo}',  'c:\picture.jpg');

Но необходимо указывать имя файла на диске.


В вашем примере вы пытаетесь вставить изображение из ResultsPhotoClient.FieldByName('Photo').AsString
что неправильно. Если вы сохраняете изображение непосредственно в базе данных, то сперва необходимо данное изображение сохранить в файл на диск.

Приветствую DriveSoft
изображение вставляется полным размером, необходима функция изменения пропорций или хотя бы задавать размеры в пикселях

Re: вставить изображение в word документ

Скачайте снова бета версию
https://www.dropbox.com/s/vyne4lvinpjzl … a.zip?dl=0


Добавил параметры Width и Height

function FindAndInsertPicture(const FindText, PictureFilename: string; ReplaceAll: boolean = true, Width: integer = -1; Height: integer = -1): boolean

пример

Word.FindAndInsertPicture('{photo}',  'd:\picture.jpg', True, 100, 50);
Dmitry.

Re: вставить изображение в word документ

DriveSoft wrote:

Скачайте снова бета версию
https://www.dropbox.com/s/vyne4lvinpjzl … a.zip?dl=0


Добавил параметры Width и Height

function FindAndInsertPicture(const FindText, PictureFilename: string; ReplaceAll: boolean = true, Width: integer = -1; Height: integer = -1): boolean

пример

Word.FindAndInsertPicture('{photo}',  'd:\picture.jpg', True, 100, 50);

Всё прекрасно работает, спасибо