-1

I have template of document in RTF format and it contains some text and some images (created with WordPad, Win 7). I need to change some text and save it. I am trying to do it like this (Delphi XE7, Win32 platform, Windows 7 x64 SP1):

  RichEdit1.Lines.LoadFromFile('1.rtf');
  RichEdit1.Lines.SaveToFile('2.rtf');

So i didn't change anything yet, but 2.rtf doesn't contain any images anymore and has much smaller size than 1.rtf. Everything else (tables/text/fonts/...) seems to be ok. Any ideas how to preserve all images (and other objects)?

UPDATE1. Just found workaround. I have DevExpress components, if i use TcxRichEdit instead of TRichEdit, then i can keep all objects:

cxRichEdit1.Properties.AllowObjects := True;
cxRichEdit1.Lines.LoadFromFile('e:\Work\InvoiceGenerator\bin\Invoice2.rtf');
cxRichEdit1.Lines.SaveToFile('e:\Work\InvoiceGenerator\bin\Invoice3.rtf');

But i can't find similar functionality in TRichEdit.

Andrei Galatyn
  • 3,322
  • 2
  • 24
  • 38
  • Basic Delphi `TRichEdit` control does not support images and other OLE objects – Dalija Prasnikar Feb 22 '15 at 14:25
  • @Dalija: I don't need "support" of objects (by the way, images are not stored as OLE objects), i just need to save all objects without changes, "as is". Component don't have to understand (all) objects, but i believe it should not delete them too. – Andrei Galatyn Feb 22 '15 at 14:33
  • `TRichEdit` doesn't have this functionality because when it was designed it was never meant to encapsulate an `RTF` file. A Rich Edit was designed to display rich text in an edit control that a user can modify - loading/saving `RTF` files was just an added bonus to that control. There are numerous other `RTF` things which a `TRichEdit` does not support. The solution is to not even think about using a `TRichEdit` as I see you have already found your solution using a third-party library. – Jerry Dodge Feb 22 '15 at 16:27
  • On another note, seeing this is an "Invoice Generator" of a "Template", why don't you use one of the vast reporting engines in Delphi? – Jerry Dodge Feb 22 '15 at 16:31
  • @Jeryy Customer would like to be able to edit templates, best of all - in regular word processor (Word/WordPad), so it was supposed to be simplest way just to replace some parts of RTF file. – Andrei Galatyn Feb 22 '15 at 16:56
  • I don't understand what you are trying to do? Are you trying to parse and emit .rtf files? In which case, why are you using a GUI control? If you wanted to read a text file, would you create a `TMemo`? – David Heffernan Feb 22 '15 at 17:02
  • @David: I am trying to use RTF file as template for reports. And i would like to keep it as simple as possible (with minimal usage of 3th party components). Do you know how to do it without TRichEdit control? – Andrei Galatyn Feb 22 '15 at 17:19
  • You need to show the document to the user in your app, is that right? – David Heffernan Feb 22 '15 at 17:28
  • @David No, i don't need to show anything. I just need to generate report (RTF) based on template (RTF). And customer should be able to edit templates in regular way - in Word/WordPad. So i am trying to replace some substrings in the RTF file (like #address# -> actual data, ...). – Andrei Galatyn Feb 22 '15 at 17:33
  • TRichEdit is categorically the wrong choice. That's a GUI control. I suspect that PDF is really what you need. – David Heffernan Feb 22 '15 at 17:36
  • @David as i told, the customer should be able to edit templates in normal/simple way, for example in MS Word or WordPad. It means, PDF is not the option. – Andrei Galatyn Feb 22 '15 at 17:40
  • Well, if you insist on RTF, then you need an RTF parser. – David Heffernan Feb 22 '15 at 17:41

2 Answers2

2

The TRichEdit control won't load images. So, you won't have any success that way. In any case, TRichEdit is for display and editing of rich text. It is not intended for background document processing. A visual control is simply wrong here.

The simplest way to achieve your goals will be to treat the RTF file as an ASCII encoded text file and parse it. Look for agreed place holders and replace them with the required text. This will require you to be able to parse RTF. Exactly how advanced a parser you need will depend somewhat on how ambitious you are. It's plausible that you could produce something effective with little more than regular expression type processing. However, that might also be somewhat brittle.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • I already tried to go this way (it's easier than way suggested by mjn), for numeric values it can be done as simple substring replacement, but for more complex string/text values it's not so simple. And of course I prefer to avoid of writing fully functional RTF parser for such simple task. Probably for now i will use workaround (yes, it's just UI control, but i don't see better solution). Thank you for some considerations! – Andrei Galatyn Feb 23 '15 at 11:21
1

A RTF typically is just a ASCII text file (except when binary data is used, stored after a \bin token. So you can try to extract the image and object data from the file and replace it with placeholders. Later, when you want to save the file, you can insert the image and object data again, using StringReplace. The hard part is the extraction of images and other objects, as you need some RTF parser logic to detect their start and end locations.

mjn
  • 36,362
  • 28
  • 176
  • 378
  • Possibly it would be enough for the OP to simply replace some literal text in the RTF file (without even using the `TRichEdit`). – Andreas Rejbrand Feb 22 '15 at 17:58
  • @AndreasRejbrand That is precisely what this answer suggests – David Heffernan Feb 22 '15 at 19:18
  • @DavidHeffernan Not exactly. He is suggesting in his answer to *save/extract the image* from rtf-text and **then** read it and save it with richedit after which he can insert the image-source again. Andreas suggested changing the text you want to replace directly in the RTF-source which would be probably much easier (instead of saving all the images (which could be multiple) and inserting them again in the right place. – Rik Feb 23 '15 at 09:53
  • @Rik OK, I misread that. That would be a rather odd thing to do. I'd put the placeholders in the RTF as plain text and then simply treat the RTF file as a text file. – David Heffernan Feb 23 '15 at 09:56