Sign in Join
Wiki copytemporary

Office Automation: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11*(Windows only)*
22
33The ability to interact with Office software and generate spreadsheets, text documents and presentations from code can be invaluable in the office, and save a lot of time otherwise spent on repetitive tasks.
44
55One example of this is the creation of applications that can read files in an arbitrary format and output an Excel file, a task that can be done much more efficiently with code than manually.
66
77## Using the OpenOffice UNO Bridge
88
99OpenOffice has language bindings for C++, Java, JavaScript and Python. On Windows, OpenOffice can also be manipulated in Pascal via COM Automation (see below), but there is currently no easy way of using OpenOffice's UNO (Universal Network Objects) from Pascal on OS X and Linux. If you're interested in developing an OO "bridge" for Pascal, please refer to these links for more information (caution: these links are quite techie in true Sun fashion):
1010
1111[api.openoffice.org](http://api.openoffice.org/)
1212
1313[About Bridges](http://wiki.services.openoffice.org/wiki/Uno/Article/About_Bridges)
1414
1515## Using COM Automation to interact with OpenOffice and Microsoft Office
1616
1717Automation is unique to Windows so the following two examples won't work on OS X or Linux. For those platforms, please refer to [Making do without Windows COM Automation](http://wiki.lazarus.freepascal.org/Multiplatform_Programming_Guide#Making_do_without_Windows_COM_Automation). If you only need to create and/or view a word processing document from your program, take a look at the [[XDev Toolkit]].
1818
1919### OpenOffice/LibreOffice on Windows
2020
2121Here's a simple example of how to open a document with your program using the OpenOffice Automation server. Note that this works only on Windows.
2222
2323``` pascal
2424program TestOO;
2525
2626{$IFDEF FPC}
2727 {$MODE Delphi}
2828{$ELSE}
2929 {$APPTYPE CONSOLE}
3030{$ENDIF}
3131
3232uses
3333 SysUtils, Variants, ComObj;
3434
3535const
3636 ServerName = 'com.sun.star.ServiceManager';
3737var
3838 Server : Variant;
3939 Desktop : Variant;
4040 LoadParams : Variant;
4141 Document : Variant;
4242 TextCursor : Variant;
4343begin
4444 if Assigned(InitProc) then
4545 TProcedure(InitProc);
4646
4747 try
4848 Server := CreateOleObject(ServerName);
4949 except
5050 WriteLn('Unable to start OO.');
5151 Exit;
5252 end;
5353
5454 Desktop := Server.CreateInstance('com.sun.star.frame.Desktop');
5555
5656 LoadParams := VarArrayCreate([0, -1], varVariant);
5757
5858 {Create new document}
5959 Document := Desktop.LoadComponentFromURL('private:factory/swriter', '_blank', 0, LoadParams);
6060
6161 {or Open existing} //you must use forward slashes, not backward!
6262 //Document := Desktop.LoadComponentFromURL('file:///C:/my/path/mydoc.doc', '_blank', 0, LoadParams);
6363
6464 TextCursor := Document.Text.CreateTextCursor;
6565
6666 {Insert existing document} //Substitute your path and doc
6767 TextCursor.InsertDocumentFromURL('file:///C:/my/path/mydoc.doc', LoadParams);
6868end.
6969```
7070
7171More comprehensive examples can found [here](https://bitbucket.org/blikblum/pascal-demos/src/04a4d10bf30b59215ff3ad4cd41dba71405ae5fc/fpc/LibreOfficeOLE/?at=master):
7272
7373- OLECreateTextDoc: Create and populate a text document with paragraph, table and frame
7474- OLEEditTextDoc: Load an existing text document, search with regular expression, replace text and add rows to a table
7575
7676### Office on Windows
7777
7878Here's a simple example of how to open a document with your program using the Word Automation server. Note that this example works only on Windows. This will work with both delphi and fpc.
7979
8080``` pascal
8181program TestMsOffice;
8282
8383{$IFDEF FPC}
8484 {$MODE Delphi}
8585{$ELSE}
8686 {$APPTYPE CONSOLE}
8787{$ENDIF}
8888
8989uses
9090 SysUtils, Variants, ComObj;
9191
9292const
9393 ServerName = 'Word.Application';
9494var
9595 Server : Variant;
9696 w:widestring;
9797begin
9898 if Assigned(InitProc) then
9999 TProcedure(InitProc);
100100
101101 try
102102 Server := CreateOleObject(ServerName);
103103 except
104104 WriteLn('Unable to start Word.');
105105 Exit;
106106 end;
107107
108108 {Open existing document} //Substitute your path and doc
109109 w:= UTF8Decode('c:\my\path\mydoc.doc');
110110 Server.Documents.Open(w); //OLE uses BSTR (http://msdn.microsoft.com/en-us/library/windows/desktop/ms221069(v=vs.85).aspx). Only widestring is compatible with BSTR in FPC, so conversion is needed for nonlatin chars.
111111 Server.Visible := True; {Make Word visible}
112112
113113end.
114114```
115115
116116Here is a sample code how to work in an open Word document, using the Word Automation server.
117117
118118``` pascal
119119var
120120 Server: Variant;
121121begin
122122 try
123123 Server := GetActiveOleObject('Word.Application');
124124 except
125125 try
126126 ShowMessage('Word not already open create a Word Object');
127127 // If no instance of Word is running, try to Create a new Word Object
128128 Server := CreateOleObject('Word.Application');
129129 except
130130 ShowMessage('Cannot start Word/Word not installed ?');
131131 Exit;
132132 end;
133133 end;
134134end;
135135```
136136
137137Limitations: Since **End** is a reserved word in FPC it shall be used as a parameter after the *&* sign.
138138
139139``` pascal
140140Server.ActiveDocument.Application.Selection.start:=Server.ActiveDocument.Application.Selection.&end+1;
141141```
142142
143143A lot of examples for Excel are available on the German wiki page [[ExcelAutomation/de]].
144144
145145## Using the fpXMLXSDExport unit
146146
147147FPC 2.6 and newer contain the **fpXMLXSDExport** unit, part of the FCL-DB export components. With that, you can export datasets to various XML formats, including a Microsoft Access-compatible format and a Microsoft Excel-compatible format.
148148
149149The Access format can output XML with or without an embedded XSD data/table definition. Note that exporting binary/BLOB type data needs additional action at the Access import end, as Access does not support proper binary fields, only OLE fields.
150150
151151In the Excel format, multiline text fields are not supported at the moment: the line ends are removed during the export.
152152
153153Lazarus provides a visual component for this: after installing the **lazdbexport** package, you will see the **TXMLXSDExporter** component on the **Data Export** tab
154154
155155See [[fpXMLXSDExport]] for details.
156156
157157## Using the FPSpreadsheet Library
158158
159159Another way to automate repetitive work with spreadsheets is to use the [[FPSpreadsheet]] library. It can read and write spreadsheets in several formats and it doesn't require having any external application installed on the machine.
160160
161161The advantages are that fpspreadsheet is 100% [[Object Pascal]] code, and it requires no external libraries or programs.
162162
163163## Writing an Excel file using ADO
164164
165165please write me.
166166
167167## Reading/Writing an Excel file using OLE
168168
169169This method needs Excel to be installed on the user's machine because it uses OLE to access it.
170170
171171***Keep in mind that this method starts Excel in the background, which opens the file and works with it like a real user.***
172172
173173- Create a new form with button, stringgrid and edit.
174174- Create a new Excel file and fill a few cells.
175175
176-<figure>
177-<img src="excel123.png" title="excel123.png" />
178-<figcaption>excel123.png</figcaption>
179-</figure>
176+![](/wiki-images/7/74/Excel123.png)
180177
181178Example - Open/Read Excel file:
182179
183180``` pascal
184181uses ..... comobj;
185182
186183procedure TForm1.Button1Click(Sender: TObject);
187184
188185Var XLApp: OLEVariant;
189186 x,y: byte;
190187 path: variant;
191188
192189begin
193190 XLApp := CreateOleObject('Excel.Application'); // requires comobj in uses
194191 try
195192 XLApp.Visible := False; // Hide Excel
196193 XLApp.DisplayAlerts := False;
197194 path := edit1.Text;
198195 XLApp.Workbooks.Open(Path); // Open the Workbook
199196 for x := 1 to 4 do
200197 begin
201198 for y := 1 to 6 do
202199 begin
203200 SG.Cells[x,y] := XLApp.Cells[y,x].Value; // fill stringgrid with values
204201 end;
205202 end;
206203 finally
207204 XLApp.Quit;
208205 XLAPP := Unassigned;
209206 end;
210207```
211208
212209If you want to make some changes and you want them to write back into the Excel, file you can use:
213210
214211``` pascal
215212XLApp.Cells[x,y].Value := SG.Cells[y,x];
216213```
217214
218215If you want to save:
219216
220217``` pascal
221218XLApp.ActiveWorkBook.Save;
222219```
223220
224221## Read/Writing an Excel file using the SpreadSheet Interface Component
225222
226223The component provides a library interface, abstracting the Excel COM and the Calc Open Office UNO interfaces. The component is available here: <http://tcoq.free.fr/composants.html> (Link verified in May 2016)
227224
228225Since Automation is not yet available, but COM is available, the Excel interface component provides a set of Lazarus classes encapsulating calls to the Excel COM interface (the one below the Automation). It hides most of the drudgery of working with low-level code. Be careful, this is a work-in-progress. Use it at your own risk.
229226
230227**Functionality:**
231228
232229- creating and loading excel workbooks,
233230- saving workbooks,
234231- creating and accessing sheets,
235232- getting values and setting values (and formulas) in cells,
236233- getting and changing color of cells,
237234- getting and changing column height and row width,
238235- creating comments,
239236- creating shapes,
240237- creating charts.
241238
242239**Inits first.**
243240
244241``` pascal
245242 IMPLEMENTATION
246243 USES
247244 ExcelUtilities,
248245 SpreadSheetInterfaces ;
249246
250247 VAR
251248 aCell : IRange ;
252249 aValue : OleVariant ; // Not sure about this, but it works. ie( Edit.Text := STRING(aValue); )
253250 ExcelApp : TExcelApplication ;
254251 ExcelWbs : IWorkBooks ;
255252
256253 ExcelBook : IWorkBook ;
257254 ExcelSheet : ISheet ;
258255 ExcelSheets : ISheets ;
259256```
260257
261258Getting a sheet is simple:
262259
263260``` pascal
264261 // Initializing the common excel workbook:
265262 ExcelApp := TExcelApplication.Create(nil) ;
266263 ExcelApp.Active := True ;
267264 ExcelApp.Visible := True ;
268265
269266 ExcelWbs := ExcelApp.WorkBooks ;
270267 ExcelBook := ExcelWbs.Add ;
271268 ExcelSheets := ExcelBook.Sheets ;
272269 ExcelSheet := ExcelSheets.Sheet(1) ;
273270```
274271
275272Playing around with cells is simple too:
276273
277274``` pascal
278275 // adding a value
279276 aCell := ExcelSheet.Cells(1, 1) ;
280277 aCell.Value := 10;
281278
282279 // adding a formula
283280 aCell := ExcelSheet.Cells(2,1) ;
284281 aCell.Formula := '=A1+10' ;
285282
286283 // getting the value computed in Excel
287284 aValue := aCell.Value ;
288285```
289286
290287The test case provided has many more examples.
291288
292289## Copy HTML to the clipboard
293290
294291You can copy HTML to the clipboard which is understood by many applications. This way you can copy formatted text. For those applications that only understand text put plain text too.
295292
296293Microsoft Office applications require HTML to be pasted onto the clipboard in a more complex format than described here. [[Clipboard|See here for an example that works with Microsoft Office.]]
297294
298295``` pascal
299296uses
300297 ClipBrd;
301298...
302299 // register the mime type for text/html. You can do this once at program start:
303300 ClipbrdFmtHTML:=RegisterClipboardFormat('text/html');
304301...
305302 // Clear any previous formats off the clipboard before starting
306303 Clipboard.Clear;
307304
308305 // put text and html on the clipboard. Other applications will choose the best format automatically.
309306 ClipBoard.SetAsHtml('<b>Formatted</b> text', 'Simple Text');
310307```
311308
312309## See also
313310
314311- [[Clipboard]]
315312- [[PowerpointAutomation/de|Powerpoint Automation]]
316313
317314## External links
318315
319316- [Excel file format](http://sc.openoffice.org/excelfileformat.pdf) - description on OpenOffice website
320317
321318---
322319*From the Free Pascal wiki, page "Office Automation", as it stood on 2023-11-03 after a change by Bart, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history