Chi non ha mai avuto bisogno di convertire uno o più file DOC e/o DOCX da Word in PDF almeno una volta nella vita? Niente di più facile, direte voi: è sufficiente selezionare il formato .PDF nell'apposita casella a discesa che appare subito dopo aver fatto click sul pulsante "Salva Come...". A dire la verità, non era così facile in passato: questo metodo è infatti disponibile solo a partire da Office 2010; prima di allora, l'unico modo per ottenere questo risultato era utilizzare software appositi - solitamente basati su Ghostscript - o installare driver di stampa PDF come Bullzip, CutePDF e altri.
Office 2010 ha risolto il problema per l'utente medio, ma soltanto a condizione che abbia una valida licenza MS Office e il software installato sulla propria macchina. Chiunque non sia provvisto di queste cose non può far altro che ricorrere alle alternative di cui sopra, o procedere all'acquisto di un software - non necessariamente MS Office - che lo metta in condizione di fare altrettanto.
Il discorso si fa leggermente diverso - e certamente più complicato - per gli sviluppatori che vogliono ottenere lo stesso risultato a livello di codice: esiste un modo semplice e gratuito per convertire file DOC o DOCX in formato PDF all'interno di una applicazione ASP.NET o .NET Core sviluppata in linguaggio C#, possibilmente senza consentire agli utenti il download del file DOC/DOCX originario? E soprattutto, nel caso in cui si tratti di una applicazione web, senza dover acquistare una licenza di MS Office sul server di pubblicazione?
La risposta, anch'essa targata Microsoft, arriva sotto froma di libreria: il suo nome è Microsoft Office primary interop assemblies (PIAs), nota anche come Microsoft.Office.Interop.Word.dll. Se utilizzate Visual Studio potete recuperarla agevolmente tramite NuGet e aggiungerla come reference della vostra applicazione con il Package Explorer: in alternativa, potete scaricarla e installarla sul vostro sistema tramite il suo pacchetto di distribuzione ufficiale.
Una volta fatto questo, sarete in grado di aprire e modificare qualsiasi documento MS Word leggendolo direttamente da FileSystem (o anche da Byte Array, seguendo le istruzioni contenute in questo articolo). Ecco un rapido esempio che mostra cosa è possibile fare:
1 2 3 4 5 6 7 8 9 10 11 |
// NS alias to avoid writing the required namespace all the time using word = Microsoft.Office.Interop.Word; // [...] Application app = new word.Application(); Document doc = app.Documents.Open(filePath); doc.SaveAs2("path-to-pdf-file.pdf", word.WdSaveFormat.wdFormatPDF); doc.Close(); app.Quit(); |
In alternativa al metodo SaveAs2() è possibile utilizzare anche il metodo ExportAsFixedFormat() e ottenere un risultato del tutto analogo:
1 |
doc.ExportAsFixedFormat(tmpFile, WdExportFormat.wdExportFormatPDF); |
E' fondamentale sottolineare come tutto quello che si può ottenere con i formati MS Word può essere realizzato anche con gli altri formati di file MS Office, come ad esempio MS Excel, MS Powerpoint e altri: ovviamente, sarà necessario importare all'inizio del file i vari riferimenti alle librerie relativi.
IMPORTANTE: Fate particolare attenzione all'utilizzo del metodo app.Quit() ! Se evitate di chiamarlo, una istanza del worker di MS Word resterà aperta sul vostro server (cfr. questo thread su StackOverflow per maggiori informazioni su questa problematica), con un dispendio di risorse notevole. Per essere assolutamente certi che l'istanza MS Word venga chiusa correttamente al termine del processo di conversione, consigliamo di aggiungere una strategia basata su un blocco try/catch in linea con il codice mostrato di seguito:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Application app = null; Document doc = null; try { app = new word.Application(); doc = Document doc = app.Documents.Open(filePath); // .. do your stuff here ... doc.Close(); app.Quit(); } catch (Exception e) { if (doc != null) doc.Close(); if (app != null) app.Quit(); } |
E' un vero peccato che questi oggetti non implementino la classe IDisposable , altrimenti avremmo potuto gestire la cosa mediante un blocco using e avere un codice ancora più leggibile e pulito.
Per il momento è tutto: felice conversione!