如何以编程方式将 Word 文件转换为 PDF?[关闭]

How do I convert Word files to PDF programmatically? [closed]

提问人:Shaul Behr 提问时间:3/4/2009 更新时间:1/8/2020 访问量:396736

问:


我们不允许提出有关书籍、工具、软件库等建议的问题。您可以编辑问题,以便用事实和引文来回答。

4年前关闭。

去年,社群审查了是否要重新讨论这个问题,并关闭了这个问题:

原始关闭原因未解决

我找到了几个开源/免费软件程序,允许您将 .doc 文件转换为 .pdf 文件,但它们都是应用程序/打印机驱动程序的品种,没有附加 SDK。

我发现有几个程序确实具有SDK,允许您将.doc文件转换为.pdf文件,但它们都是专有类型,许可证2,000美元左右。

有谁知道使用 C# 或 VB.NET 解决我的问题的任何干净、廉价(最好是免费)的编程解决方案?

谢谢!

C# vb.net PDF MS-Word

评论

2赞 Colonel Panic 9/30/2016
检查 Pandoc 是否具有您喜欢的语言的绑定。命令行界面也非常简单pandoc manual.docx -o manual.pdf
0赞 hertzogth 2/11/2020
另外,请检查 GemBox.Document SDK。它有一个免费版本和一个便宜的版本。它既不使用打印机驱动程序也不使用ms office将Word文件转换为PDF。
0赞 Al Johri 2/18/2020
您可以使用 docx2pdf 进行以下转换: github.com/AlJohri/docx2pdf
0赞 nicojs 2/13/2023
对于寻求解决方案的人来说,使用 LibreOffice 要容易得多。如果您安装了 docker,则只需一个简单的命令:docker "run" "--rm" "--entrypoint" "soffice" "-v" "$(pwd):/usr/src/project" "linuxserver/libreoffice:latest" "--headless" "--convert-to" "pdf" "--outdir" "/usr/src/project" "/usr/src/project/foo.docx"

答:

2赞 MikeW 3/4/2009 #1

这里似乎有一些相关信息:

在 ASP.NET 中将 MS Word 文档转换为 PDF

此外,由于 Office 2007 具有发布到 PDF 功能,我想您可以使用办公自动化在 Word 2007 中打开 *.DOC 文件并另存为 PDF。我不太热衷于办公自动化,因为它很慢而且容易挂起,但只是把它扔在那里......

评论

2赞 Shaul Behr 3/4/2009
Aspose 可能有效,但它非常昂贵。
13赞 Mark Brackett 3/4/2009 #2

PDFCreator 具有一个 COM 组件,可从 .NET 或 VBScript 调用(下载中包含示例)。

但是,在我看来,打印机正是您所需要的 - 只需将其与 Word 的自动化功能混合在一起,您就可以开始了。

评论

0赞 Shaul Behr 3/4/2009
此 COM 组件在哪里?“mik”是什么意思?那是“混合”吗?
0赞 Mark Brackett 3/4/2009
COM 组件与示例一起包含在下载中。是的,这应该是“混合”。
5赞 Phil Gorley 5/29/2015
仅供参考 - 如果您走这条路,PDFCreator 会在安装程序中捆绑恶意软件。自 2009 年以来,这一直是 PDFCreator 的一个持续问题。
2赞 Lzh 8/5/2015
@PhilGorley恶意软件?这个答案是+8...
0赞 Mark Brackett 8/6/2015
@Mzn - FWIW,注意并取消选中插件安装总是对我有用。我不认为它与 Java 安装程序中的 Oracle 捆绑废话有什么不同;这很烦人,但对我来说不值得避免使用该软件(是的,好吧,PdfCreator 的广告软件可能比 Oracle 这些天推出的任何东西都更没用且更具侵入性......我仍然不想要其中任何一个)。
215赞 Eric Ness 3/4/2009 #3

使用 foreach 循环而不是 for 循环 - 它解决了我的问题。

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

这是对适用于我的程序的修改。它使用安装了“另存为 PDF”加载项的 Word 2007。它在目录中搜索 .doc 文件,在 Word 中打开它们,然后将它们另存为 PDF。请注意,您需要将对 Microsoft.Office.Interop.Word 的引用添加到解决方案中。

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赞 Shaul Behr 3/4/2009
谢谢!无论如何,我可能会使用 Aspose,如果它比 Word 自动化更快。但是,如果我能忍受一点点慢,我会使用你的解决方案。再次感谢!
4赞 Eric Ness 3/4/2009
是的,它不是最快的,但很难打败价格。:-)很高兴我能帮上忙。
11赞 RichardOD 9/30/2009
使用 Office 2007 SP2,您不再需要另存为 PDF 下载。我还成功地将这种技术用于 Excel 和 Powerpoint。
6赞 Prabu 12/22/2009
您是否在具有 Web 应用程序的服务器上使用此方法?我遇到了很多问题,没有提到 MS 不推荐它。 support.microsoft.com/default.aspx?scid=kb;EN-US;q257757#kb2 我听说 ASPose 很棒,但它非常珍贵。
6赞 BrainSlugs83 10/25/2011
呃......如果没有安装 word,我认为打包互操作程序集将是您最不担心的事情。此代码需要安装 word。
1赞 Saber 3/24/2012 #4

适用于 word 的 Microsoft PDF 加载项似乎是目前最好的解决方案,但您应该考虑到它无法将所有 word 文档正确转换为 pdf,在某些情况下,您会看到 word 和输出 pdf 之间存在巨大差异。不幸的是,我找不到任何可以正确转换所有 word 文档的 api。 我发现确保转换 100% 正确的唯一解决方案是通过打印机驱动程序转换文档。缺点是文档被逐个排队和转换,但您可以确定生成的 pdf 与 word 文档布局完全相同。 我个人更喜欢使用 UDC(通用文档转换器)并在服务器上安装了 Foxit Reader(免费版),然后通过启动“进程”并将其 Verb 属性设置为“print”来打印文档。您还可以使用 FileSystemWatcher 在转换完成时设置信号。

39赞 Elger Mensonides 9/21/2012 #5

总结一下 vb.net 用户,免费选项(必须安装 office):

Microsoft 办公组件下载:

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赞 Adam Anderson 4/10/2015
2015 年仍然有效。使用 Office 2013,无需单独下载 PIA。
4赞 Stefan Steiger 3/1/2016
如果 BOOM 打开一个消息框并询问某些内容 - 例如在 Web 应用程序中......或者同时做 2 个文件......
0赞 JasonPlutext 1/25/2019
npmjs.com/package/@nativedocuments/docx-wasm 免费增值选项(通过 nodejs 和 edge.js 或 Javascript.NET)(无需 Word)
6赞 Ggalla1779 2/26/2016 #6

当有人用 10000 个 word 文件转给我以转换为 PDF 时,我经历了 Word 到 PDF 的痛苦。现在我用 C# 做了它并使用了 Word 互操作,但如果我尝试使用 PC,它会很慢并且崩溃。非常令人沮丧。

这让我发现我可以抛弃互操作及其缓慢......对于我使用的 Excel(EPPLUS),然后我发现您可以获得一个名为 Spire 的免费工具,该工具允许转换为 PDF......有局限性!

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

评论

0赞 mbdavis 2/15/2018
谢谢你 - 不使用 Interop 的绝佳解决方案。为什么很难找到免费的 docx 到 PDF 转换器?
0赞 grinder22 2/27/2019
我对此寄予厚望,但免费版本仅限于 3 页的 PDF 输出。如果您需要无限制的部署,完整版非常昂贵。
0赞 hertzogth 2/11/2020
grinder22 GemBox.Document 也有有大小限制的免费版本和付费版本。但是,它包括免版税部署,因此您可以免费构建和发布无限数量的项目。
15赞 zeta 11/5/2016 #7

只是想补充一点,我使用了 Microsoft.Interop 库,特别是 ExportAsFixedFormat 函数,我没有看到在此线程中使用。

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

评论

9赞 Sam Rueby 2/23/2018
对于那些不知道需要在计算机上安装 Office 才能使用 Microsoft Interop 库的用户,请注意。
2赞 Dan Korn 5/6/2020
好!我建议在 finally 块中设置并添加调用。app.Visible = false;app.Quit();
5赞 daniele3004 3/25/2019 #8

使用 Microsoft.Office.Interop.Word 将 WORD 转换为 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);

}

添加以下过程以释放内存:

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

评论

0赞 Preza8 1/30/2020
是否有必要调用 GC。收集?难道没有一种不同的方法可以只标记与此相关的内存部分,以便在下一个自动 GC 上释放吗?