Come posso convertire i file Word in PDF a livello di codice? [chiuso]


221

Ho trovato diversi programmi open source / freeware che ti consentono di convertire i file .doc in file .pdf, ma sono tutti della varietà di driver di applicazioni / stampanti, senza SDK allegato.

Ho trovato diversi programmi che hanno un SDK che ti consente di convertire i file .doc in file .pdf, ma sono tutti di tipo proprietario, $ 2000 una licenza o giù di lì.

Qualcuno sa di qualsiasi soluzione programmatica pulita, economica (preferibilmente gratuita) al mio problema, usando C # o VB.NET?

Grazie!


1
Controlla se Pandoc ha attacchi per la tua lingua preferita . Anche l'interfaccia della riga di comando è semplicissimapandoc manual.docx -o manual.pdf
colonnello Panic il

Inoltre, controlla GemBox.Document SDK. Ha una versione gratuita e una versione economica. Non utilizza né un driver della stampante né ms office per convertire i file Word in PDF.
hertzogth,

Puoi usare docx2pdf per fare questa conversione: github.com/AlJohri/docx2pdf
Al Johri

Risposte:


204

Usa un ciclo foreach invece di un ciclo for - ha risolto il mio problema.

int j = 0;
foreach (Microsoft.Office.Interop.Word.Page p in pane.Pages)
{
    var bits = p.EnhMetaFileBits;
    var target = path1 +j.ToString()+  "_image.doc";
    try
    {
        using (var ms = new MemoryStream((byte[])(bits)))
        {
            var image = System.Drawing.Image.FromStream(ms);
            var pngTarget = Path.ChangeExtension(target, "png");
            image.Save(pngTarget, System.Drawing.Imaging.ImageFormat.Png);
        }
    }
    catch (System.Exception ex)
    {
        MessageBox.Show(ex.Message);  
    }
    j++;
}

Ecco una modifica di un programma che ha funzionato per me. Utilizza Word 2007 con il componente aggiuntivo Salva come PDF installato. Cerca una directory per i file .doc, li apre in Word e li salva in formato PDF. Nota che dovrai aggiungere un riferimento a Microsoft.Office.Interop.Word alla soluzione.

using Microsoft.Office.Interop.Word;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

...

// Create a new Microsoft Word application object
Microsoft.Office.Interop.Word.Application word = new Microsoft.Office.Interop.Word.Application();

// C# doesn't have optional arguments so we'll need a dummy value
object oMissing = System.Reflection.Missing.Value;

// Get list of Word files in specified directory
DirectoryInfo dirInfo = new DirectoryInfo(@"\\server\folder");
FileInfo[] wordFiles = dirInfo.GetFiles("*.doc");

word.Visible = false;
word.ScreenUpdating = false;

foreach (FileInfo wordFile in wordFiles)
{
    // Cast as Object for word Open method
    Object filename = (Object)wordFile.FullName;

    // Use the dummy value as a placeholder for optional arguments
    Document doc = word.Documents.Open(ref filename, ref oMissing,
        ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
        ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
        ref oMissing, ref oMissing, ref oMissing, ref oMissing);
    doc.Activate();

    object outputFileName = wordFile.FullName.Replace(".doc", ".pdf");
    object fileFormat = WdSaveFormat.wdFormatPDF;

    // Save document into PDF Format
    doc.SaveAs(ref outputFileName,
        ref fileFormat, ref oMissing, ref oMissing,
        ref oMissing, ref oMissing, ref oMissing, ref oMissing,
        ref oMissing, ref oMissing, ref oMissing, ref oMissing,
        ref oMissing, ref oMissing, ref oMissing, ref oMissing);

    // Close the Word document, but leave the Word application open.
    // doc has to be cast to type _Document so that it will find the
    // correct Close method.                
    object saveChanges = WdSaveOptions.wdDoNotSaveChanges;
    ((_Document)doc).Close(ref saveChanges, ref oMissing, ref oMissing);
    doc = null;
}

// word has to be cast to type _Application so that it will find
// the correct Quit method.
((_Application)word).Quit(ref oMissing, ref oMissing, ref oMissing);
word = null;

3
Grazie! Potrei comunque utilizzare Aspose, se è più veloce dell'automazione di Word. Ma se riesco a tollerare un po 'di lentezza, userò prontamente la tua soluzione. Grazie ancora!
Shaul Behr,

4
Sì, non è il più veloce ma è difficile battere il prezzo. :-) Lieto di poterti aiutare.
Eric Ness,

10
Con Office 2007 SP2 non è più necessario il salvataggio come download PDF. Ho anche usato questa tecnica con successo per Excel e Powerpoint.
RichardOD,

5
Hai usato questo metodo su un server con un'applicazione web? Ricevo molti problemi, per non parlare del fatto che non è raccomandato dalla SM. support.microsoft.com/default.aspx?scid=kb;EN-US;q257757#kb2 Ho sentito che ASPose è fantastico ma è abbastanza caro.
Prabu,

6
Ehm ... se la parola non è installata, penso che impacchettare il gruppo di interoperabilità sarà l'ultima delle tue preoccupazioni. Questo codice RICHIEDE la parola da installare.
BrainSlugs83,

35

Per riassumere per gli utenti di vb.net, l'opzione gratuita (deve avere Office installato):

Download degli assemblaggi di Microsoft Office:

Esempio VB.NET:

        Dim word As Application = New Application()
        Dim doc As Document = word.Documents.Open("c:\document.docx")
        doc.Activate()
        doc.SaveAs2("c:\document.pdf", WdSaveFormat.wdFormatPDF)
        doc.Close()

3
Funziona ancora nel 2015. Con Office 2013 non è necessario scaricare il PIA separatamente.
Adam Anderson,

3
E BOOM se apre una finestra di messaggio e chiede qualcosa, ad esempio in un'applicazione Web ... o fa 2 documenti contemporaneamente ...
Stefan Steiger

Un'opzione freemium (tramite nodejs e edge.js o Javascript.NET) è npmjs.com/package/@nativedocuments/docx-wasm (No need for Word)
JasonPlutext

14

PDFCreator ha un componente COM, richiamabile da .NET o VBScript (esempi inclusi nel download).

Ma mi sembra che una stampante sia proprio ciò di cui hai bisogno: basta mescolarla con l'automazione di Word e dovresti essere pronto.


dov'è questo componente COM? E cosa significa "mik"? Doveva essere "mix"?
Shaul Behr,

Il componente COM è incluso nel download, insieme agli esempi. E sì, doveva essere "mix".
Mark Brackett,

4
Cordiali saluti - se segui questa strada, PDFCreator raggruppa malware nell'installer. Questo è un problema in corso con PDFCreator dal 2009.
Phil Gorley,

2
@PhilGorley Malware? e questa risposta è +8 ...
Mzn

@Mzn - FWIW, prestando attenzione e deselezionando le installazioni dei componenti aggiuntivi funziona sempre per me. Non lo vedo diverso da quello di Oracle bundle merda nel programma di installazione di Java; è fastidioso, ma non vale la pena evitare il software per me (sì, ok, l'adware di PdfCreator è probabilmente infinitamente meno utile e più invadente di qualunque cosa Oracle stia spingendo in questi giorni ... Continuo a non volere nessuno dei due).
Mark Brackett,

12

Volevo solo aggiungere che ho usato le librerie Microsoft.Interop, in particolare la funzione ExportAsFixedFormat che non vedevo usata in questo thread.

using Microsoft.Office.Interop.Word;
using System.Runtime.InteropServices;
using System.IO;
using Microsoft.Office.Core;

Application app;

public string CreatePDF(string path, string exportDir)
{
    Application app = new Application();
    app.DisplayAlerts = WdAlertLevel.wdAlertsNone;
    app.Visible = true;

    var objPresSet = app.Documents;
    var objPres = objPresSet.Open(path, MsoTriState.msoTrue, MsoTriState.msoTrue, MsoTriState.msoFalse);

    var pdfFileName = Path.ChangeExtension(path, ".pdf");
    var pdfPath = Path.Combine(exportDir, pdfFileName);

    try
    {
        objPres.ExportAsFixedFormat(
            pdfPath,
            WdExportFormat.wdExportFormatPDF,
            false,
            WdExportOptimizeFor.wdExportOptimizeForPrint,
            WdExportRange.wdExportAllDocument
        );
    }
    catch
    {
        pdfPath = null;
    }
    finally
    {
        objPres.Close();
    }
    return pdfPath;
}

7
Solo una nota per coloro che non sanno che è necessario che Office sia installato sul computer per utilizzare le librerie di Microsoft Interop.
Sam Rueby,

Bello! Suggerisco di impostare app.Visible = false;e aggiungere una chiamata app.Quit();nel blocco finally.
Dan Korn,


5

Ho attraversato il dolore da Word a PDF quando qualcuno mi ha scaricato con file da 10000 parole da convertire in PDF. Ora l'ho fatto in C # e ho usato l'interoperabilità di Word, ma è stato lento e si è arrestato in modo anomalo se ho provato a usare il PC ... molto frustrante.

Questo mi ha portato a scoprire che potevo scaricare interoper e la loro lentezza ..... per Excel che uso (EPPLUS) e poi ho scoperto che puoi ottenere uno strumento gratuito chiamato Spire che consente la conversione in PDF ... con limitazioni!

http://www.e-iceblue.com/Introduce/free-doc-component.html#.VtAg4PmLRhE


Grazie per questo - ottima soluzione senza usare Interop. Perché è così difficile trovare un convertitore gratuito da docx a PDF?
mbdavis,

Avevo grandi speranze in questo, ma la versione gratuita è limitata a 3 pagine di output PDF. La versione completa è molto costosa se hai bisogno di distribuzioni illimitate.
grinder22,

grinder22 GemBox.Document ha anche una versione gratuita con limitazione delle dimensioni e una versione a pagamento. Tuttavia, include una distribuzione senza diritti d'autore in modo da poter creare e pubblicare un numero illimitato di progetti senza costi aggiuntivi.
hertzogth,

3

Codice e soluzione semplici che utilizzano Microsoft.Office.Interop.Wordper convertire WORD in PDF

using Word = Microsoft.Office.Interop.Word;

private void convertDOCtoPDF()
{

  object misValue = System.Reflection.Missing.Value;
  String  PATH_APP_PDF = @"c:\..\MY_WORD_DOCUMENT.pdf"

  var WORD = new Word.Application();

  Word.Document doc   = WORD.Documents.Open(@"c:\..\MY_WORD_DOCUMENT.docx");
  doc.Activate();

  doc.SaveAs2(@PATH_APP_PDF, Word.WdSaveFormat.wdFormatPDF, misValue, misValue, misValue, 
  misValue, misValue, misValue, misValue, misValue, misValue, misValue);

  doc.Close();
  WORD.Quit();


  releaseObject(doc);
  releaseObject(WORD);

}

Aggiungi questa procedura per liberare memoria:

private void releaseObject(object obj)
{
  try
  {
      System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
      obj = null;
  }
  catch (Exception ex)
  {
      //TODO
  }
  finally
  {
     GC.Collect();
  }
}

È necessario chiamare GC.Collect? Non esiste un modo diverso di contrassegnare solo la parte di memoria correlata a questa per la liberazione sul prossimo GC automatico?
Preza8

2

Sembra essere alcune informazioni rilevanti qui:

Conversione di documenti MS Word in PDF in ASP.NET

Inoltre, con Office 2007 con funzionalità di pubblicazione in PDF, suppongo che potresti usare l'automazione di Office per aprire il file * .DOC in Word 2007 e Salva come PDF. Non sono troppo appassionato di automazione dell'ufficio in quanto è lento e soggetto a impiccagioni, ma lo sto solo lanciando ...


Aspose può funzionare, ma è decisamente costoso.
Shaul Behr,

1

Il componente aggiuntivo Microsoft PDF per Word sembra essere la soluzione migliore per ora, ma dovresti considerare che non converte tutti i documenti Word correttamente in pdf e in alcuni casi vedrai un'enorme differenza tra la parola e l'output pdf. Sfortunatamente non sono riuscito a trovare alcuna API in grado di convertire correttamente tutti i documenti di Word. L'unica soluzione che ho trovato per garantire che la conversione fosse corretta al 100% era convertendo i documenti tramite un driver della stampante. Il rovescio della medaglia è che i documenti vengono messi in coda e convertiti uno per uno, ma puoi essere sicuro che il pdf risultante sia esattamente lo stesso del layout del documento di Word. Personalmente ho preferito usare UDC (Universal Document Converter) e installare Foxit Reader (versione gratuita) anche sul server, quindi ho stampato i documenti avviando un "Processo" e impostando la proprietà Verb su "stampa".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.