Jak konwertować pliki Word na programowo PDF? [Zamknięte]


221

Znalazłem kilka programów typu open source / freeware, które pozwalają konwertować pliki doc na pliki pdf, ale wszystkie są aplikacjami / sterownikami drukarki, bez dołączonego SDK.

Znalazłem kilka programów, które mają zestaw SDK umożliwiający konwersję plików doc na pliki pdf, ale wszystkie są prawnie zastrzeżone, 2000 USD za licencję lub inne.

Czy ktoś wie o czystym, niedrogim (najlepiej darmowym) programowym rozwiązaniu mojego problemu za pomocą C # lub VB.NET?

Dzięki!


1
Sprawdź, czy Pandoc ma powiązania dla twojego ulubionego języka . Interfejs wiersza poleceń jest również bardzo łatwypandoc manual.docx -o manual.pdf
pułkownik Panic

Sprawdź także GemBox.Document SDK. Ma darmową wersję i niedrogą wersję. Nie używa ani sterownika drukarki, ani pakietu MS Office do konwersji plików Word na PDF.
hertzogth

Możesz użyć docx2pdf, aby dokonać tej konwersji: github.com/AlJohri/docx2pdf
Al Johri

Odpowiedzi:


204

Użyj pętli foreach zamiast pętli for - to rozwiązało mój problem.

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++;
}

Oto modyfikacja programu, który działał dla mnie. Używa programu Word 2007 z zainstalowanym dodatkiem Zapisz jako PDF . Przeszukuje katalog w poszukiwaniu plików .doc, otwiera je w programie Word, a następnie zapisuje jako plik PDF. Pamiętaj, że musisz dodać odwołanie do Microsoft.Office.Interop.Word do rozwiązania.

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
Dziękuję Ci! Mimo to mogę po prostu użyć Aspose, jeśli jest to szybsze niż automatyzacja programu Word. Ale jeśli mogę tolerować odrobinę spowolnienia, będę korzystać z twojego rozwiązania. Dzięki jeszcze raz!
Shaul Behr

4
Tak, nie jest najszybszy, ale ciężko jest przebić cenę. :-) Cieszę się, że mogłem pomóc.
Eric Ness,

10
W pakiecie Office 2007 SP2 nie trzeba już zapisywać jako pliku PDF do pobrania. Z powodzeniem zastosowałem tę technikę w programach Excel i Powerpoint.
RichardOD

5
Czy używałeś tej metody na serwerze z aplikacją internetową? Dostaję dużo problemów nie wspominając, że to nie jest zalecane przez stwardnienie rozsiane. support.microsoft.com/default.aspx?scid=kb;EN-US;q257757#kb2 Słyszałem, że ASPose jest świetny, ale bardzo drogi.
Prabu,

6
Um ... jeśli słowo nie zostanie zainstalowane, myślę, że pakowanie zestawu interop będzie najmniejszym zmartwieniem. Ten kod WYMAGA słowa do zainstalowania.
BrainSlugs83

35

Podsumowując dla użytkowników vb.net, darmowa opcja (musi mieć zainstalowany pakiet Office):

Pobieranie zestawów Microsoft Office:

  • pia na biuro 2010
  • pia na biuro 2007

  • Dodaj odwołanie do Microsoft.Office.Interop.Word.Application

  • Dodaj instrukcję using lub import (vb.net) do Microsoft.Office.Interop.Word.Application

Przykład 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
Nadal działa w 2015 roku. W pakiecie Office 2013 nie trzeba pobierać PIA osobno.
Adam Anderson,

3
I BOOM, jeśli otworzy okno wiadomości i zapyta o coś - na przykład w aplikacji internetowej ... lub zrobi 2 dokumenty w tym samym czasie ...
Stefan Steiger

Opcją freemium (przez nodejs i edge.js lub Javascript.NET) jest npmjs.com/package/@nativedocuments/docx-wasm (bez potrzeby korzystania z programu Word)
JasonPlutext

14

PDFCreator ma składnik COM, który można wywołać z .NET lub VBScript (próbki zawarte w pliku do pobrania).

Ale wydaje mi się, że drukarka jest właśnie tym, czego potrzebujesz - po prostu połącz ją z automatyzacją Worda i powinieneś już iść.


gdzie jest ten składnik COM? A co znaczy „mik”? Czy to miało być „miksowanie”?
Shaul Behr

Składnik COM znajduje się w pliku do pobrania wraz z próbkami. I tak, to miał być „miks”.
Mark Brackett,

4
Do Twojej wiadomości - jeśli wybierzesz tę drogę, PDFCreator dołącza złośliwe oprogramowanie do instalatora. Jest to ciągły problem z PDFCreator od 2009 roku.
Phil Gorley

2
@PhilGorley Malware? i ta odpowiedź to +8 ...
Mzn

@Mzn - FWIW, zwracanie uwagi i odznaczanie instalacji dodatków zawsze działa dla mnie. Nie widzę w tym nic innego niż bzdury pakietowania Oracle w instalatorze Java; jest denerwujące, ale nie warto unikać oprogramowania dla mnie (tak, OK, oprogramowanie reklamowe PdfCreator jest prawdopodobnie nieskończenie mniej przydatne i bardziej natrętne niż cokolwiek, co Oracle naciska obecnie ... Nadal nie chcę żadnego z nich).
Mark Brackett,

12

Chciałem tylko dodać, że korzystałem z bibliotek Microsoft.Interop, w szczególności funkcji ExportAsFixedFormat, której nie widziałem w tym wątku.

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
Tylko uwaga dla tych, którzy nie wiedzą, że na komputerze musi być zainstalowany pakiet Office, aby móc korzystać z bibliotek Microsoft Interop.
Sam Rueby

Miły! Sugeruję ustawienie app.Visible = false;i dodanie wywołania app.Quit();w ostatnim bloku.
Dan Korn


5

Przeszedłem przez program Word do formatu PDF, gdy ktoś rzucił mi 10000 plików słownych do konwersji na format PDF. Teraz zrobiłem to w C # i użyłem Word Interop, ale działało to powoli i zawieszało się, jeśli w ogóle próbowałem używać komputera ... bardzo frustrujące.

To doprowadziło mnie do odkrycia, że ​​mogę zrzucić interopsy i ich powolność ..... w programie Excel, którego używam (EPPLUS), a potem odkryłem, że możesz uzyskać bezpłatne narzędzie o nazwie Spire, które pozwala na konwersję do formatu PDF ... z ograniczeniami!

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


Dzięki za to - świetne rozwiązanie bez użycia Interop. Dlaczego tak trudno jest znaleźć darmowy konwerter docx na PDF?
mbdavis

Miałem na to duże nadzieje, ale darmowa wersja jest ograniczona do 3 stron pliku PDF. Pełna wersja jest bardzo droga, jeśli potrzebujesz nieograniczonej liczby wdrożeń.
grinder22

grinder22 GemBox.Document ma również darmową wersję z ograniczeniem wielkości i wersję płatną. Obejmuje to jednak wdrożenie bezpłatne, więc możesz tworzyć i publikować nieograniczoną liczbę projektów bez dodatkowych kosztów.
hertzogth

3

Łatwy kod i rozwiązanie Microsoft.Office.Interop.Worddo konwersji WORD w 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);

}

Dodaj tę procedurę, aby zwolnić pamięć:

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

Czy konieczne jest połączenie z GC.Collect? Czy nie ma innego sposobu na oznaczenie tylko części pamięci, która jest z tym związana, aby zwolnić na następnej automatycznej GC?
Preza8

2

Wydaje się, że są to niektóre istotne informacje:

Konwertowanie dokumentów MS Word do formatu PDF w ASP.NET

Ponadto, ponieważ Office 2007 ma funkcję publikowania w formacie PDF, myślę, że można użyć automatyzacji biura, aby otworzyć plik * .DOC w programie Word 2007 i zapisać jako PDF. Nie przepadam za automatyką biurową, ponieważ jest powolna i podatna na powieszenie, ale po prostu ją tam rzucam ...


Aspose może działać, ale jest rażąco kosztowne.
Shaul Behr

1

Wydaje się, że dodatek Microsoft PDF dla programu Word jest najlepszym rozwiązaniem na razie, ale należy wziąć pod uwagę, że nie konwertuje on poprawnie wszystkich dokumentów Word na format pdf, aw niektórych przypadkach widać ogromną różnicę między słowem a formatem wyjściowym pdf. Niestety nie mogłem znaleźć interfejsu API, który poprawnie przekonwertowałby wszystkie dokumenty tekstowe. Jedynym rozwiązaniem, które zapewniłem, że konwersja była w 100% poprawna, było przekonwertowanie dokumentów za pomocą sterownika drukarki. Minusem jest to, że dokumenty są kolejkowane i konwertowane jeden po drugim, ale możesz być pewien, że wynikowy pdf jest dokładnie taki sam jak układ dokumentu Word. Osobiście wolałem używać UDC (Universal Document Converter) i zainstalowałem Foxit Reader (darmowa wersja) na serwerze, a następnie wydrukowałem dokumenty, uruchamiając „Proces” i ustawiając jego właściwość Czasownik na „drukuj”.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.