mercoledì 2 novembre 2011

[VB.NET] Gestire documenti Word con Interop

Descrizione :
Un semplice esempio di Report dati su Word 2007 con Microsoft.Office.Interop.

+ Articolo :

Unico Rif. richiesto è nei Riferimenti .NET : Microsoft.Office.Interop.Word v12.0.0.0.
L'esempio seguente crea un'Application Word, aggiunge un nuovo Document, e inserisce una Tabella Dati a runtime.

Seguono le operazioni di salvataggio / chiusura oggetti e relativo rilascio risorse con Marshal.ReleaseComObject().

--> Codice Esempio :

        'Esempio con Word 2007 :
        'RIF. a Microsoft.Office.Interop.Word v12.0.0.0 
        'Office 12 = Office 2007 / Office 14 = Office 2010

        'Percorso relativo Documents
        Dim percorso As String = Application.StartupPath & "\"

        'Applicazione Word : UNA sola per tutti i Documents
        'coinvolti nell'operazione
        Dim AppWord As New Microsoft.Office.Interop.Word.Application

        'Visibilità Applicazione Word
        AppWord.Visible = False

        'Oggetto Document
        Dim nomeFileOutput As String = "outputTable.docx"
        Dim wordDoc As Microsoft.Office.Interop.Word.Document
        wordDoc = AppWord.Documents.Add

        'Operazioni
        'Creazione Range 
        'wordDoc.Range = primo Range disponibile
        'in caso di bookmark usare wordDoc.Bookmarks(indice/nome As Object).Range
        Dim R As Microsoft.Office.Interop.Word.Range = wordDoc.Range
        'Creazione Tabella con Riga intestazione
        Dim T As Microsoft.Office.Interop.Word.Table = wordDoc.Tables.Add(R, 1, 5)
        T.Rows(1).Range.Bold = 1
        T.Cell(1, 1).Range.Text = "Colonna A"
        T.Cell(1, 2).Range.Text = "Colonna B"
        T.Cell(1, 3).Range.Text = "Colonna C"
        T.Cell(1, 4).Range.Text = "Colonna D"
        T.Cell(1, 5).Range.Text = "Colonna E"
        'Formattazione generale Tabella
        T.AutoFitBehavior(Microsoft.Office.Interop.Word.WdAutoFitBehavior.wdAutoFitWindow)
        T.Borders.OutsideLineStyle = Microsoft.Office.Interop.Word.WdLineStyle.wdLineStyleSingle
        T.Borders.InsideLineStyle = Microsoft.Office.Interop.Word.WdLineStyle.wdLineStyleSingle
        'Dati esempio : aggiunta di 10 righe di dati
        For i As Integer = 1 To 10
            T.Rows.Add()
            T.Rows(i + 1).Range.Bold = 0
            T.Cell(i + 1, 1).Range.Text = "Cella A" & i
            T.Cell(i + 1, 2).Range.Text = "Cella B" & i
            T.Cell(i + 1, 3).Range.Text = "Cella C" & i
            T.Cell(i + 1, 4).Range.Text = "Cella D" & i
            T.Cell(i + 1, 5).Range.Text = "Cella E" & i
        Next

        'Salvataggio / Chiusura Oggetti
        wordDoc.SaveAs(percorso & nomeFileOutput)
        wordDoc.Close()
        System.Runtime.InteropServices.Marshal.ReleaseComObject(wordDoc)

        'Chiusura Applicazione Word
        AppWord.Quit()
        System.Runtime.InteropServices.Marshal.ReleaseComObject(AppWord)

        MessageBox.Show("Processo completato.", "OK", MessageBoxButtons.OK, MessageBoxIcon.Information)
La Tabella Dati è solo d'esempio, ma con poche modifiche non è difficile ridattare il codice a casi di compilazione da dati reali provenienti da interrogazioni a DB : DataReader, cicli di lettura da DataSet, DataTable, DataView, DataGridView, ecc ...

+ Fine Articolo.

Un Click su "Mi Piace" è il modo migliore per ringraziare l'autore di questo articolo.



9 commenti:

Anonimo ha detto...

Howdy! This post could not be written any better!
Reading this post reminds me of my old room mate! He always kept talking about this.
I will forward this post to him. Pretty sure he will have a
good read. Many thanks for sharing!

Look at my web blog microsoft exchange 2003

Anonimo ha detto...

Ciao Marco sono Angelo, prendendo spunto da questo tuo articolo ho provato a fare delle modifiche per le mie esigenze: in pratica dovrei aprire un doc (Preventivo) e inserire una tabella (1,2) dove dovrei inserire
un log nella cella (1,1) e la ragione sociale in (1,2)
solo che in pratica così come ho fatto effetivamente inserisce la tab con
l'img e la ragione sociale ma poi mi cancella tutto il doc.
Inoltre vorei poter modificare il font e le dimensioni all'interno della cella (1,2)
ma non ci sono riuscito potresti dirmi dove sbaglio?


Dim AppWord As New Word.Application

'Visibilità Applicazione Word
AppWord.Visible = True

'Oggetto Document
Dim wordDoc As Word.Document
wordDoc = AppWord.Documents.Open(mioPath & "\Preventivi\p1.doc")

'Creazione Range
'wordDoc.Range = primo Range disponibile
Dim R As Microsoft.Office.Interop.Word.Range = wordDoc.Range

'Creazione Tabella con Riga intestazione
Dim T As Microsoft.Office.Interop.Word.Table = wordDoc.Tables.Add(R, 1, 2)

T.Rows(1).Range.Bold = 1
'Formattazione generale Tabella
T.AutoFitBehavior(Word.WdAutoFitBehavior.wdAutoFitWindow)
T.Borders.OutsideLineStyle = Word.WdLineStyle.wdLineStyleNone
T.Borders.InsideLineStyle = Word.WdLineStyle.wdLineStyleNone

T.Rows.Add()
T.Rows(2).Range.Bold = 1
T.Rows(2).Range.Font.Size = 12
T.Cell(1, 1).Range.InlineShapes.AddPicture(FileLogo)
T.Cell(1, 2).Range.Text = txtRagioneSociale.Text

Anonimo ha detto...

inoltre ho pravo con un' altro esempio che usa le selection ma senza successo!, con questo riesco a inserire sia l'img che i dati della ragione sociale e tutto il doc non viene cancellato come nel'esempio di prima, solo che in questo modo l'img viene inserita e allineata a sx subito dopo la ragione sociale viene inserita è allineata a dx: Ho provato a inserire la tab seguendo il tuo esempio proprio per averli logo a sx e ragione sociale a dx ma non mi inserisce nulla:

Private Sub crea()

Dim objWordApp As New Word.Application

Dim objDoc As New Word.Document
Dim R As Word.Range = objDoc.Range
'Creazione Tabella con Riga intestazione
Dim T As Word.Table = objDoc.Tables.Add(R, 1, 2)


'Show the Word application window if checked.
objWordApp.Visible = True

'Create a new Word document and add some text to it.
objDoc = objWordApp.Documents.Open(mioPath & "\Preventivi\p1.doc")


'T.Borders.InsideLineStyle = WdLineStyle.wdLineStyleNone

T.Rows(1).Range.Bold = 1
T.Cell(1, 1).Range.Text = "Colonna A"
T.Cell(1, 2).Range.Text = "Colonna B"

With objWordApp.Selection

.Paragraphs.Alignment = WdParagraphAlignment.wdAlignParagraphLeft
.InlineShapes.AddPicture(path_FileLogo)
.TypeParagraph()

.Paragraphs.Alignment = WdParagraphAlignment.wdAlignParagraphRight
.Font.Size = 12 'objWordApp.Selection.Font.Size + 2
.Font.Bold = 1
.Font.Underline = 0
.TypeText(nl & nl)
.TypeText("Spett.le")
.TypeParagraph()

.Paragraphs.Alignment = WdParagraphAlignment.wdAlignParagraphRight
.Font.Color = Word.WdColor.wdColorDarkBlue
.Font.Size = 12
.Font.Italic = 0
.Font.Bold = 0
.Font.Underline = 0
.TypeText(txtRagioneSociale.Text)
.TypeParagraph()

.Paragraphs.Alignment = WdParagraphAlignment.wdAlignParagraphLeft
'.Paragraphs.Format.SpaceAfter = 50 '24 pt spacing after paragraph.
.Font.Color = Word.WdColor.wdColorBlack
.Font.Size = 12 'objWordApp.Selection.Font.Size + 2
.Font.Bold = 1
.Font.Underline = 0
.TypeParagraph() '.TypeText(nl & nl)
.TypeText(txtnumPreventivo.Text)
.TypeParagraph()

.Paragraphs.Alignment = WdParagraphAlignment.wdAlignParagraphLeft
.Font.Size = 12 'objWordApp.Selection.Font.Size + 2
.Font.Bold = 1
.Font.Underline = 0
.TypeParagraph() '.TypeText(nl & nl)
.TypeText(txtOggetto.Text)
.TypeParagraph()

End With

End Sub


grazie Angelo

MarcoGG ha detto...

Ciao. Prova ad andare per gradi. Rispondo alla prima delle tue domande. Con la creazione di un nuovo Paragraph non sovrascrivi il contenuto dello stesso Range. Questo dovrebbe essere una prima soluzione :

Dim mioPath As String = Application.StartupPath
Dim AppWord As New Word.Application
Dim FileLogo As String = mioPath & "\logo.bmp"
Dim mioFont As New Microsoft.Office.Interop.Word.Font
With mioFont
.Size = 16
.Bold = 1
.Color = Word.WdColor.wdColorBlue
.Name = "Arial Narrow"
.Italic = 1
End With

'Visibilità Applicazione Word
AppWord.Visible = True

'Oggetto Document
Dim wordDoc As Word.Document
wordDoc = AppWord.Documents.Open(mioPath & "\p1.doc")

'Nuovo Paragrafo
Dim P As Word.Paragraph = wordDoc.Paragraphs.Add

'Creazione Tabella con Riga intestazione
Dim T As Microsoft.Office.Interop.Word.Table = wordDoc.Tables.Add(P.Range, 1, 2)

T.Rows(1).Range.Bold = 1
'Formattazione generale Tabella
T.AutoFitBehavior(Word.WdAutoFitBehavior.wdAutoFitWindow)
T.Borders.OutsideLineStyle = Word.WdLineStyle.wdLineStyleNone
T.Borders.InsideLineStyle = Word.WdLineStyle.wdLineStyleNone

T.Rows.Add()
T.Rows(2).Range.Bold = 1
T.Rows(2).Range.Font.Size = 12
T.Cell(1, 1).Range.InlineShapes.AddPicture(FileLogo)
T.Cell(1, 2).Range.Font = mioFont
T.Cell(1, 2).Range.Text = "TEST"

Anonimo ha detto...

Ciao Marco intanto grazie per la tua celere risposta, come sempre!
Ho provato la tua soluzione e funziona a metà! nel senso che adesso il testo del doc resta ma l'inserimento della tabella me lo fa alla fine e non all'inizio come mi servirebbe. E poi però word mi dice che ha smesso di funzionare e l'applicazione mi da un'eccezione sul "mioFont" se commento la riga

T.Cell(1, 2).Range.Font = mioFont

No da l'eccezione e funziona tranquillamente, inserendo però la tab come detto prema in append al doc caricato.
Ora sto cercando di capire come mai!

grazie
Angelo

Angelo Romeo ha detto...

Ciao Marco ma come mai con il secondo esempio che ti ho scritto inserisce il testo prima del doc word caricato e con questa tua soluzione non riesco? mette la tabella in fondo al documento! Per caso centra il fatto che li si usa la selection? trovo poca doc in giro pur troppo e per lo più esempi vecchi!

grazie
Angelo

MarcoGG ha detto...

Infatti, la documentazione sugli Interop per Office da .NET è sempre stata scarsa e lo sarà sempre. E soprattutto esempi concreti validi e funzionanti. C'è sempre bisogno di fare un "fine tuning" a seconda della versione di .NET e della versione di Office impiegata. In risposta al tuo primo quesito avevo fatto un rapido test con VB 2005 e Office Word 2007 e non ho avuto alcun problema, mentre tu riporti un errore nel personalizzare la Font nella cella della tabella. Per il discorso Tabella alla fine del doc o all'inizio, basta che modifichi il mio esempio precedente con :
'Nuovo Paragrafo
Dim P As Word.Paragraph = AppWord.Selection.Paragraphs.Add()
e la tabella verrà inserita all'inizio del Document.
Se mi invii un msg pvt in FB ti posso inviare un allegato con la mia soluzione nei 2 casi, in VB 2005. Vedrai che funziona correttamente.

Anonimo ha detto...

Ciao.
Se sviluppo su una macchina che ha office 2007, e quindi metto i suoi riferimenti, poi utilizzo l'eseguibile su una macchina che ha office 2010, non funziona.
Lo stesso al contrario.
E' possibile indicare i riferimenti a runtime ,ovvero in abse alla versione di Office ?

M De Gennaro ha detto...

Ciao, ottimo esempio. Ma per creare invece della tabella dei campi come faccio???

Posta un commento

 
Design by Free WordPress Themes Modificato da MarcoGG