2012-10-31 9 views
6

Ho letto più post sulla questione, e nessuno sembra giungere a una conclusione decente alla mia domanda. (Forse sto cercando di vedere se qualcosa è spuntato di recente.)Come lavoro con i documenti di Word senza utilizzare l'automazione COM?

Ho una piccola app di beneficenza che gestisce gli impegni. In tal modo, ha bisogno di lavorare e stampare documenti.

In questo caso, se Word è aperto sullo sfondo, il thread dell'app si bloccherà e non risponderà alla chiusura di Word, e devo eseguire il rollback manualmente e chiudere la parola. Certo, tutto funziona bene, ma semplicemente non posso garantire che l'utente chiuderà Word, anche se inserisco le istruzioni in un manuale utente.

Non sono troppo preoccupato per la velocità, ma immagino che se può essere migliorato, sarebbe un bel bonus.

Sono state rilasciate librerie per Delphi che consentiranno di aprire, modificare, stampare e salvare documenti? In caso contrario, esiste un modo per utilizzare l'automazione di Word in modo tale da non entrare in conflitto con un altro handle aperto di Word all'apertura?

+0

Puoi provare Aspose on .net. Niente di così completo per Delphi. Forse l'opzione migliore è usare qualcosa di diverso da un documento di Word. Qualcosa basato su file di testo. –

+0

Non sono molto entusiasta di scrivere wrapper e cose, se ciò è possibile anche con Aspose. Non l'ho davvero guardato comunque, semplicemente perché è .Net. Per essere onesti, Word mi offre la massima flessibilità con i documenti, in particolare per un utente finale. Quindi non usare Word non è davvero un'opzione. Grazie comunque. :) –

+0

* Il thread dell'app si bloccherà *, su quale chiamata esattamente? –

risposta

5

Se si utilizza GetActiveOleObject, verrà visualizzata l'istanza di Word in esecuzione. Utilizzando CreateOleObject, si otterrà una nuova istanza e non dovrebbe essere turbato da altre istanze in esecuzione.

Se si utilizza il wrapper TWordApplication, è possibile impostare ConnectKind su ckNewInstance per eseguire questa operazione. Per impostazione predefinita, TWordApplication proverà a connettersi con un'istanza in esecuzione.

+0

C'è un modo per impostare ConnectKind (o qualcosa di simile) senza usare TWordApplication? Tendo a preferire l'utilizzo di funzioni Ole non elaborate, se sai cosa intendo. Io uso CreateOleObject. –

+5

Perché preferisci la COM legata in un secondo momento? Sicuramente il legame precoce è migliore. –

+0

Potrei farlo, e non è un'idea terribile, ma è l'unico modo per cambiare ConnectKind? Sono sicuro che ci sono alcuni altri vantaggi del binding precoce, ma non sono sicuro di averne bisogno. –

0

Se si desidera aprire modificare e stampare documenti di Word e non ti dispiace usare il formato RTF per quello che stai facendo, investigare TRichView.

Genera documenti ricchi che sono in formato RTF, che è uno dei formati supportati da MS Word. Non penso che legga direttamente i file .DOC ma puoi convertire .DOC e .DOCX in formato RTF, per la maggior parte dei file semplici, ma alcune funzionalità di formattazione avanzate andrebbero perse nella conversione.

Ha il vantaggio di funzionare senza che sia necessario installare alcuna copia di MS Word sulla macchina che eseguirà l'elaborazione del documento. Per la produzione di ricevute e altri documenti semplici, questa sarebbe la tecnica più affidabile; Non usare Word direttamente, a tutti.

+1

Il problema con il formato di file RTF è che intestazioni e piè di pagina non sono supportati, per quanto ne so. Non sarebbe saggio limitare le capacità di un cliente. È la stessa ragione per cui non eseguirò la migrazione completa a OpenOffice per questo scopo (mentre è supportato). –

1
procedure PrintViaWord (const filename: string); 
const 
wdUserTemplatesPath = 2; 

var 
    wrdApp, wrdDoc, wrdSel: variant; 

begin 
wrdApp:= CreateOleObject ('Word.Application'); // create new instance 
sleep (5000); // this fixes a bug in Word 2010 to do with opening templates 
wrdDoc:= wrdApp.documents.add (
      wrdApp.Options.DefaultFilePath[wdUserTemplatesPath] + '\mytemplate.dot'); 

wrdDoc.Select; 
wrdSel:= wrdApp.selection; 
wrdApp.Options.CheckSpellingAsYouType:= 0; 
wrdSel.paragraphformat.alignment:= 1; 
wrdSel.typetext ('This is a program demonstrating how to open Word in the background' 
        + ' and add some text, print it, save it and exit Word'); 
wrdDoc.SaveAs (filename + '.doc'); 
wrdApp.ActivePrinter:= 'Konica Minolta 211'; 
wrdApp.PrintOut; 
WrdDoc.SaveAs (filename + '.doc'); 
wrdApp.quit; 

wrdSel:= unassigned; 
wrdDoc:= unassigned; 
wrdApp:= unassigned 
end;