以编程方式将 Word (docx) 转换为 PDF

Posted

技术标签:

【中文标题】以编程方式将 Word (docx) 转换为 PDF【英文标题】:Programmatically convert Word (docx) to PDF 【发布时间】:2011-12-02 21:27:59 【问题描述】:

好的,在您认为“不是这样的另一个问题”之前,请先阅读此内容。

我有一个应用程序(ASP.NET MVC 3 中的 Web 应用程序)使用 DocX library 在 DocX 中生成 Word 文件。

应用程序获取一个模板并用数据库中的所有数据填充它。 现在我想为创建的 docx 文件创建一个 PDF 版本。

我知道apose.word 是一个选项,但不适合我,因为我的预算很少。我必须花钱购买的其他库也不可能。

我没有共享点服务器,所以Word Automation Services 也不是一个选项。

所以我有 2 个选项(我知道),它们都使用 iTextSharp。不知道哪个更好。

    我可以使用从 docx 文件生成的 XML 并将其转换为 iTextSharp 可用的版本。 我可以像使用模板创建 docx 一样创建 PDF。

任何人都知道它有多少工作,这两个中哪一个具有更好的性能以及是否有可能做到。

我知道第二个选项的缺点是,当我更改模板时,我必须为两个版本都更改它。

如果您有更好的解决方案(即免费),欢迎分享。

【问题讨论】:

【参考方案1】:

另一种选择,即使它需要一些工作:在服务器上安装 OpenOffice,并使用 UNO 库(包括它们作为应用程序中的程序集),您可以打开 docx 文档并将其直接保存为 PDF。 几分钟后我会发布一个示例...

部分示例: 这是我很久以前创建的一个类,用于将文件转换为pdf

using unoidl.com.sun.star.lang;
using unoidl.com.sun.star.uno;
using unoidl.com.sun.star.container;
using unoidl.com.sun.star.frame;
using unoidl.com.sun.star.beans;
using unoidl.com.sun.star.view;
using System.Collections.Generic;
using System.IO;

namespace QOpenOffice

    public enum AppType
    
        Writer,
        Calc,
        Impress,
        Draw,
        Math
    

    public enum ExportFilter
        Word97,
        WriterPDF,
        CalcPDF,
        DrawPDF,
        ImpressPDF,
        MathPDF
    

    class OpenOffice
    
        private XComponentContext context;
        private XMultiServiceFactory service;
        private XComponentLoader component;
        private XComponent doc;

        private List<string> filters = new List<string>();

        #region Constructors
        public OpenOffice()
        
            /// This will start a new instance of OpenOffice.org if it is not running, 
            /// or it will obtain an existing instance if it is already open.
            context = uno.util.Bootstrap.bootstrap();

            /// The next step is to create a new OpenOffice.org service manager
            service = (XMultiServiceFactory)context.getServiceManager();

            /// Create a new Desktop instance using our service manager
            component = (XComponentLoader)service.createInstance("com.sun.star.frame.Desktop");

            // Getting filters
            XNameContainer filters = (XNameContainer)service.createInstance("com.sun.star.document.FilterFactory");
            foreach (string filter in filters.getElementNames())
                this.filters.Add(filter);
        

        ~OpenOffice()
        
            if (doc != null)
                doc.dispose();
            doc = null;
        
        #endregion

        #region Private methods
        private string FilterToString(ExportFilter filter)
        
            switch (filter)
            
                case ExportFilter.Word97: return "MS Word 97";
                case ExportFilter.WriterPDF: return "writer_pdf_Export";
                case ExportFilter.CalcPDF: return "calc_pdf_Export";
                case ExportFilter.DrawPDF: return "draw_pdf_Export";
                case ExportFilter.ImpressPDF: return "impress_pdf_Export";
                case ExportFilter.MathPDF: return "math_pdf_Export";
            
            return "";
        
        #endregion

        #region Public methods
        public bool Load(string filename, bool hidden)
        
            return Load(filename, hidden, "", "");
        
        public bool Load(string filename, bool hidden, int filter_index, string filter_options)
        
            return Load(filename, hidden, filters[filter_index], filter_options);
        
        public bool Load(string filename, bool hidden, string filter_name, string filter_options)
        
            List<PropertyValue> pv = new List<PropertyValue>();
            pv.Add(new PropertyValue("Hidden", 0, new uno.Any(hidden), PropertyState.DIRECT_VALUE));
            if (filter_name != "")
            
                pv.Add(new PropertyValue("FilterName", 0, new uno.Any(filter_name), PropertyState.DIRECT_VALUE));
                pv.Add(new PropertyValue("FilterOptions", 0, new uno.Any(filter_options), PropertyState.DIRECT_VALUE));
            

            try
            
                doc = component.loadComponentFromURL(
                    "file:///" + filename.Replace('\\', '/'), "_blank",
                    0, pv.ToArray());
                return true;
            
            catch
            
                doc = null;
                return false;
            
        
        public bool Print()
        
            return Print(1, "");
        
        public bool Print(int copies, string pages)
        
            List<PropertyValue> pv = new List<PropertyValue>();
            pv.Add(new PropertyValue("CopyCount", 0, new uno.Any(copies), PropertyState.DIRECT_VALUE));
            if (pages != "")
                pv.Add(new PropertyValue("Pages", 0, new uno.Any(pages), PropertyState.DIRECT_VALUE));
            //if (doc is XPrintable)
            try
            
                ((XPrintable)doc).print(pv.ToArray());
                return true;
            
            catch  return false; 
        
        public bool Save(string filename, ExportFilter filter)
        
            return Save(filename, FilterToString(filter));
        
        public bool Save(string filename, string filter)
        
            List<PropertyValue> pv = new List<PropertyValue>();
            pv.Add(new PropertyValue("FilterName", 0, new uno.Any(filter), PropertyState.DIRECT_VALUE));
            pv.Add(new PropertyValue("Overwrite", 0, new uno.Any(true), PropertyState.DIRECT_VALUE));
            try
            
                filename = filename.Replace("\\", "/");
                ((XStorable)doc).storeToURL("file:///" + filename, pv.ToArray());
                return true;
            
            catch  return false; 
        
        public bool ExportToPdf(string filename)
        
            filename = Path.ChangeExtension(filename, ".pdf");
            bool ret = Save(filename, "writer_pdf_Export");
            if (!ret) ret = Save(filename, "impress_pdf_Export");
            if (!ret) ret = Save(filename, "calc_pdf_Export");
            if (!ret) ret = Save(filename, "draw_pdf_Export");
            if (!ret) ret = Save(filename, "impress_pdf_Export");
            if (!ret) ret = Save(filename, "math_pdf_Export");
            return ret;
        
        public void Close()
        
            doc.dispose();
            doc = null;
        

        public bool New(AppType app, bool hidden)
        
            try
            
                string sapp = "private:factory/";
                switch (app)
                
                    case AppType.Writer:
                        sapp += "swriter";
                        break;
                    case AppType.Calc:
                        sapp += "scalc";
                        break;
                    case AppType.Impress:
                        sapp += "simpress";
                        break;
                    case AppType.Draw:
                        sapp += "sdraw";
                        break;
                    case AppType.Math:
                        sapp += "smath";
                        break;
                
                PropertyValue pv = new PropertyValue("Hidden", 0, new uno.Any(hidden), PropertyState.DIRECT_VALUE);
                doc = component.loadComponentFromURL(sapp, "_blank", 0, new PropertyValue[1]  pv );
                return true;
            
            catch
            
                doc = null;
                return false;
            
        
        #endregion


        #region Properties
        public List<string> Filters
        
            get  return filters; 
        
        #endregion
    

【讨论】:

@Frederiek:看看我编辑过的帖子。让我知道它是否适合你 这是一个有趣的解决方案。我对宇诺不熟悉。有人可以告诉我 service.createInstance 是在进程内还是进程外加载程序集? 在这种情况下,我们需要购买并安装MS Office。 @JitendraPancholi:也许你误读了我的帖子,但我写道你可以使用 OpenOffice,而不是 MS Office!不,在这种情况下您不需要 MS Office,因为 OpenOffice 不使用 MS 库。 好的,我试试这个

以上是关于以编程方式将 Word (docx) 转换为 PDF的主要内容,如果未能解决你的问题,请参考以下文章

在 Java 中以编程方式将 Word doc 转换为 HTML

怎么把doc文件转换成docx

使用apache的POI API 生成word文档(docx)时,怎么将一段文字设置成为大纲标题,如设置成标题1

使用 OpenOffice.org 基本宏以编程方式将 *.odt 文件转换为 MS Word *.doc 文件

将 Word/PowerPoint XML 转换为 docx/pptx

在 AWS Lambda 上使用 Python 将 MS Word(.doc 和 .docx)文件转换为 HTML