Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > преобразовать doc в jpg


Автор: matriza 21.6.2008, 18:17
Приветствую всех =)

Вобщем такая проблема...

Имеется три файла (один doc и  два xls)

1) doc файл, состоящий из трех страниц, нужно, соответствнно, преобразовать в три jpg-файла. Причем в третьем файле на месте определенной фразы или ниже ее нужно вставить водяной знак, ну или другими словами определенную картинку

2) с xls файлами, которые каждый состоят из одного листа нужно проделать такую же операцию... так как лист один преобразовать ее в один jpg-файли и на месте определенной фразы или ниже ее нужно вставить водяной знак...

знаю что нужно применять Word.Application Excel.Application и Canvas, но как именно происходит преобразование, а самое главное вставка водяного знака не знаю... и очень хотелось бы узнать как реализовать данную задачу




заранее огромное спасибо!!!

Автор: ne0n 21.6.2008, 19:18
Цитата(matriza @  21.6.2008,  18:17 Найти цитируемый пост)
хотелось бы узнать как реализовать данную задачу


т.е. Сделать за вас? smile 

Автор: matriza 21.6.2008, 19:49
Цитата

т.е. Сделать за вас? 


нет... неверно...

натолкнуть как это сделать... если можно привести небольшой пример кода... а самое думаю сложное рассказать как вставить водяной знау в нужном месте...

Автор: ne0n 21.6.2008, 21:24
Цитата(matriza @  21.6.2008,  19:49 Найти цитируемый пост)
натолкнуть как это сделать

ладно попробуем натолкнуть)Для ворда вижу наиболее простое решение таким:
сохраняем файл как текствоый:
Код

procedure TForm1.Button1Click(Sender: TObject);
var

fname: string;

WordAppl, WordDoc: OleVariant;

begin
with TOpenDialog.Create(nil) do
try
 Filter := 'word documents (*.doc)|*.doc';
 if not Execute then Exit;
 fname := FileName;
finally
  Free;
end;

WordAppl := CreateOleObject('Word.Application');
try
  WordDoc := WordAppl.Documents.Open(fname);
  fname := ExtractFilePath(fname) + 'test.txt';
  WordDoc.SaveAs(FileName := fname,FileFormat := 2);
finally
  WordAppl.Quit;
end;
end;


cчитываем содержимое файла, и собственно для отрисовки поступаем так:
Код

 var
 JpegIm: TJpegImage;
 bm: TBitMap;
begin
 bm := TBitMap.Create;
 bm.Height:=100;
 bm.Width:=100;
 bm.Canvas.TextOut(20,20,'Текст Текст Текст');
 JpegIm := TJpegImage.Create;
 jpegim.Assign(bm);
 JpegIm.SaveToFile('C:\Screen.jpg');
 bm.Destroy;
 JpegIm.Destroy;



ну это так в общем виде.... для xls будет наверно посложнее...

Автор: matriza 22.6.2008, 06:47
спасибо огромное за примеры =) 

сейчас пытаюсь сделать без перевода в текстовый формат чтобы не терялось форматирование ворда...

изображение должно получаться как отсканированное...

отрисовку думаю сегодня доделаю для ворда... для меня самым сложным кажется вставка водяного знака в нужное место документа... как я думаю это нужно делать во время отрисовки когда дойду циклом до нужной фразы но как именно вставить этот знак пока не знаю...

Автор: MetalFan 22.6.2008, 08:53
даю наводку: офис при копировании в буфер обмена содержания документа, позволяет получить его из буфера в разных форматах, в т.ч. в wmf,emf,bmp

Автор: ne0n 22.6.2008, 16:26
Цитата(MetalFan @  22.6.2008,  08:53 Найти цитируемый пост)
офис при копировании в буфер обмена содержания документа, позволяет получить его из буфера в разных форматах, в т.ч. в wmf,emf,bmp


хм, интересно...я тут ради интереса порылся, и единственно ечто нашел это метод CopyAsPicture, о нем идет речь?

Автор: matriza 22.6.2008, 17:02
я думаю да =) счс приведу пример что удалось пока написать... нехватает знание работы с word... очень мало работал с ним делал только примитивное создание документа... не могу понять как в ворд выделить все страницы или нужные мне страницы думаю что нужно применять WordDocument1.Range но пока не получается

вот код
Код

procedure TForm1.Button1Click(Sender: TObject);
var    
fil: OleVariant;
MetaFile : TMetafile; 
Bitmap : TBitmap;
begin
if OpenDialog1.Execute then
begin
  fil:=OpenDialog1.FileName;
  WordApplication1.Documents.Add(fil,EmptyParam,EmptyParam,EmptyParam);
  WordApplication1.Options.CheckSpellingAsYouType := False;
  WordApplication1.Options.CheckGrammarAsYouType := False;
  WordDocument1.Range.CopyAsPicture;
  //WordApplication1.Selection.CopyAsPicture;
  Clipboard.Open;
  {if Clipboard.HasFormat(CF_TEXT) then
     ShowMessage('áóôåð ñîäåðæèò òåêñò');
  if Clipboard.HasFormat(CF_BITMAP) then
      ShowMessage('áóôåð ñîäåðæèò èçîáðàæåíèå');
  if Clipboard.HasFormat(CF_METAFILEPICT) then
     ShowMessage('áóôåð ñîäåðæèò âåêòîðíîå èçîáðàæåíèå');
  if Clipboard.HasFormat(CF_PICTURE) then
     ShowMessage('áóôåð ñîäåðæèò îáüåêò òèïà TPicture');
  if Clipboard.HasFormat(CF_COMPONENT) then
     ShowMessage('áóôåð ñîäåðæèò êîìïîíåíò'); }
  Metafile := TMetaFile.Create;
  Bitmap := TBitmap.Create;
  try
   MetaFile.Assign(clipboard);
   with Bitmap do
   begin
    Height := Metafile.Height;
    Width := Metafile.Width;
    Canvas.Draw( 0 , 0 , MetaFile);
    Bitmap.SaveToFile('Test.bmp');
   end;
  finally
  Bitmap.Free;
  MetaFile.Free;
  end;

  Clipboard.Clear;
  Clipboard.Close;

  WordApplication1.Disconnect;
  end;    
end;    


было бы классно если бы кто нибудь объяснил про выделение страниц и если где то можно написать покорректнее также бы об этом рассказал

заранее огромное спасибо =)

буду дальше разбираться....  smile 

Автор: matriza 22.6.2008, 21:09
вобщем научился я делать из первой страницы картинку 

Код

procedure TForm1.Button1Click(Sender: TObject);
var    
fil: OleVariant;
MetaFile : TMetafile; 
Bitmap : TBitmap;
JpegIm: TJpegImage;
begin
if OpenDialog1.Execute then
begin
  fil:=OpenDialog1.FileName;
  WordApplication1.Documents.Add(fil,EmptyParam,EmptyParam,EmptyParam);
  WordApplication1.Options.CheckSpellingAsYouType := False;
  WordApplication1.Options.CheckGrammarAsYouType := False;
  WordDocument1.ConnectTo(WordApplication1.ActiveDocument);
  WordDocument1.Range.Select;
  WordDocument1.Range.CopyAsPicture;
  //WordApplication1.Visible := true;
  Clipboard.Open;
  {if Clipboard.HasFormat(CF_TEXT) then
     ShowMessage('áóôåð ñîäåðæèò òåêñò');
  if Clipboard.HasFormat(CF_BITMAP) then
      ShowMessage('áóôåð ñîäåðæèò èçîáðàæåíèå');
  if Clipboard.HasFormat(CF_METAFILEPICT) then
     ShowMessage('áóôåð ñîäåðæèò âåêòîðíîå èçîáðàæåíèå');
  if Clipboard.HasFormat(CF_PICTURE) then
     ShowMessage('áóôåð ñîäåðæèò îáüåêò òèïà TPicture');
  if Clipboard.HasFormat(CF_COMPONENT) then
     ShowMessage('áóôåð ñîäåðæèò êîìïîíåíò'); }
  Metafile := TMetaFile.Create;
  Bitmap := TBitmap.Create;
  try
   MetaFile.Assign(clipboard);
   with Bitmap do
   begin
    Height := Metafile.Height;
    Width := Metafile.Width;
    Canvas.Draw( 0 , 0 , MetaFile);
    //Bitmap.SaveToFile('Test.bmp');
    JpegIm := TJpegImage.Create;
    JpegIm.Assign(Bitmap);
    JpegIm.SaveToFile('Test.jpg');
   end;
  finally
  Bitmap.Free;
  MetaFile.Free;
  JpegIm.Free;
  end;

  Clipboard.Clear;
  Clipboard.Close;

  WordApplication1.Disconnect;
  end;    
end;    


а вот как добраться до третьей страницы пока не знаю....

Автор: MetalFan 22.6.2008, 21:48
вот что у меня получилось на позднем связывании:
код сохраняет рядом с исходным файлом страницы в отдельных BMPшках
Код

function ConvertMSWORDToImages( const AFileName: string ): Integer;
var
  lWord: Variant;
  lFN: string;
  lPages: Variant;
  lPageNum: Integer;
  lPage: Variant;
  lRect: Variant;
  lRange: Variant;
  i, j: longword;
  lBmp: TBitmap;
  lMF:  TMetafile;
begin
  Result := -1;
  lWord := CreateOleObject( 'Word.Application' );
  lBmp := TBitmap.Create;
  lMF := TMetafile.Create;
  try
    lWord.Documents.Open(FileName := AFileName, ReadOnly := True );
    lPages := lWord.ActiveDocument.ActiveWindow.Panes.Item(1).Pages;
    for i := 1 to lPages.Count do
    begin
//без этого изварата почемуто с первого раза не получался доступ к страницам > 1
      try
        lPages.Item(i);
      except
      end;
//конец изврата

      lPage := lPages.Item(i);
      for j := 1 to lPage.Rectangles.Count do
      begin
        lRect := lPage.Rectangles.Item(j);
        lRange := lRect.Range;
        lRange.CopyAsPicture;

        if Clipboard.HasFormat(CF_METAFILEPICT) then
        begin
           lMF.Assign( Clipboard );
            if not lMF.Empty then
            begin
              lBmp.SetSize( lMF.Width, lMF.Height );
              lBmp.Canvas.Draw(0,0, lMF );
              lBmp.SaveToFile( Format( '%s%s%d_%d.bmp', [ExtractFilePath(AFileName), ExtractFileName(AFileName), i, j]) );
              lMF.Clear;
              lBmp.Free;
              lBmp := TBitmap.Create;
            end;
        end;
      end;
    end;
  finally
    lBmp.Free;
    lMF.Free;
    lWord.Quit;
    lWord := Unassigned;
  end;
end;

код сырой. стоит вылизать.

Автор: matriza 23.6.2008, 05:25
огромное спасибо за пример =)

но у меня при обработке документа пишет такю ошибку "запрашиваемый номер семейства не существует" и ругается на эту часть функции

Код

      try    
        lPages.Item(i);    
      except    
      end;    


можжет нужно в uses что то особенное указать???

Автор: MetalFan 23.6.2008, 11:39
matriza, у меня тоже самое... возможно стоит попробовать зациклить обращение к lPages.Item до тех пор, пока не будет получена страница.
либо сделать ворд видимым... в этом случае у меня ошибки не возникало...

Автор: matriza 23.6.2008, 16:16
ладно... с вордом более мнее разобрались =) 

теперь сижу мучаю excel 

не могу найти что то похожее на CopyAsPicture в ворде...

Автор: MetalFan 23.6.2008, 18:24
да пофигу. используй просто Copy. судя по документации к VBA для ворда - это одно и то же.

Автор: matriza 24.6.2008, 17:28
все таки вроде бы как в excel copy это не одно и то же

например применяя вот такой код 
Код

ExcelApplication1.Sheets.Copy(EmptyParam,EmptyParam,0);

и проверяя что будет в буфере обмена при проверке срабатывает то что в буфере текст а не картинка CF_TEXT

и проблемы при вставке рисунка 
Код

  Clipboard.Assign(Image1.Picture);
  vstart:=1;
  vend:=2;
  WordApplication1.Selection.InsertAfter('Ìýí Õóà');
  //i:=1;
  //WordDocument1.Frames.Item(i).Height:=Image1.Height;
  //WordDocument1.Frames.Item(i).Width:=Image1.Width;
  //WordDocument1.Frames.Item(i).Select;


те места что закомментированы не срабатывают

Автор: MetalFan 24.6.2008, 21:56
со знаками препинания не дружим?

Автор: Aragami 1.7.2011, 14:05
 Остался ли у кого-нибудь готовый пример перевода из формата doc в jpeg? smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)