首页 > 其他分享 >Word 转成pdf及打印的开源方案支持xp

Word 转成pdf及打印的开源方案支持xp

时间:2025-01-10 18:05:04浏览次数:3  
标签:Word string return filename filter file new pdf xp

Word转成pdf、打印的方案几乎没有免费开源的方案,现在提供一个通过LibreOffice实现的方案

操作依赖LibreOffice需要安装,点此下载老版本

5.4.7.2是最后一个支持xp的 版本如需xp要请安装此版本

LibreOffice官方介绍

LibreOffice 是一款开放源代码的自由免费全能办公软件,可运行于 Microsoft Windows, GNU/Linux 以及 macOS 等操作系统上。它包含了 Writer, Calc, Impress, Draw, Math 以及 Base 等组件,可分别用于文本文档、电子表格、幻灯片演示文稿、绘图文档、数学公式编辑、数据库管理等工作。

LibreOffice 采用对企业和个人用户均免费的 MPL 2.0 授权协议。您可以自由分发该软件,无需支付授权费用(但您仍然可以付费获得经认证的专业支持)。它的源代码完全公开,任何人都可以参与软件的开发和维护。

一、通过进程的方式

1.Word打印

  public void PrintWordFile(string file, string printerName)
        {
            if (string.IsNullOrEmpty(file)) throw new Exception("Invalid parameters passed to convert word function.");

            if (!File.Exists(file)) throw new FileNotFoundException($"The file passed to the convert word process ({file}) could not be found.");

            var fileInfo = new FileInfo(file);

            if (fileInfo.Extension.ToLower() != ".doc" && fileInfo.Extension.ToLower() != ".docx")
                throw new ArgumentOutOfRangeException($"The file type passed to the convert word process is an invalid type ({fileInfo.Extension}).");

            var libreOfficePath = Path.Combine(LibreOfficePath, "swriter.exe");

            if (!File.Exists(libreOfficePath)) throw new FileNotFoundException("It seems that LibreOffice is not where it should be, please ensure the path exists.");

            var procStartInfo = new ProcessStartInfo(libreOfficePath, $@"--headless --pt ""{printerName}"" ""{file}""")
            {
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                UseShellExecute = false,
                CreateNoWindow = true,
                WorkingDirectory = Environment.CurrentDirectory
            };

            Process process = new Process() { StartInfo = procStartInfo };

            // Attach event handlers to capture output and error streams
            process.OutputDataReceived += (sender, args) => Console.WriteLine("OUT: " + args.Data);
            process.ErrorDataReceived += (sender, args) => Console.WriteLine("ERR: " + args.Data);

            process.Start();

            // Start reading the output asynchronously
            process.BeginOutputReadLine();
            process.BeginErrorReadLine();

            process.WaitForExit();

            if (process.ExitCode != 0)
            {
                throw new LibreOfficeFailedException(process.ExitCode);
            }
        }

2.Word转成PDF

  public string ConvertWordFile(string file, string outputDirectory)
        {
            if (string.IsNullOrEmpty(file) || string.IsNullOrEmpty(outputDirectory)) throw new Exception("Invalid parameters passed to convert word function.");

            if (!File.Exists(file)) throw new FileNotFoundException($"The file passed to the convert word process ({file}) could not be found.");

            if (!Directory.Exists(outputDirectory)) throw new DirectoryNotFoundException($"The output folder passed to the convert word process ({outputDirectory}) does not exist.");

            if (outputDirectory.EndsWith(@"\")) outputDirectory = outputDirectory.TrimEnd('\\');

            var fileInfo = new FileInfo(file);

            if (fileInfo.Extension.ToLower() == ".doc" && fileInfo.Extension.ToLower() == ".docx") throw new ArgumentOutOfRangeException($"The file type passed to the convert word process is an invalid type ({fileInfo.Extension}).");

            var outputFile = outputDirectory + @"\" + Path.GetFileNameWithoutExtension(fileInfo.Name) + ".pdf";

            if (File.Exists(outputFile)) File.Delete(outputFile);

            var libreOfficePath = Path.Combine(LibreOfficePath, "swriter.exe");

            if (!File.Exists(libreOfficePath)) throw new FileNotFoundException("It seems that LibreOffice is not where it should be, please ensure the path exists.");
            var procStartInfo = new ProcessStartInfo(libreOfficePath, $@"--headless --convert-to pdf:writer_pdf_Export ""{file}"" --outdir ""{outputDirectory}""")
            {
                RedirectStandardOutput = true,
                UseShellExecute = false,
                CreateNoWindow = true,
                WorkingDirectory = Environment.CurrentDirectory
            };

            Process process = new Process() { StartInfo = procStartInfo };

            process.Start();

            process.WaitForExit();

            if (process.ExitCode != 0)
                throw new LibreOfficeFailedException(process.ExitCode);

            if (!File.Exists(outputFile)) throw new FileNotFoundException("The convert to word process has failed to convert the file!");

            return outputFile;
        }

 public class LibreOfficeFailedException : Exception
    {
        public LibreOfficeFailedException(int exitCode) : base($"LibreOffice has failed with {exitCode}") { }
    }

二、通过cli库调用,下附代码

CLI下载

   public class WordPrint
    {
        private XComponentContext context;
        private XMultiServiceFactory service;
        private XComponentLoader component;
        private XComponent doc;
        private static WordPrint wordPrint;
        private List<string> filters = new List<string>();
        #region Constructors
        
        WordPrint()
        {
            NativeMethods.InitializationLibrary();
            /// 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);
        }

        ~MiniWordPrint()
        {
            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
        /// <summary>
        /// load docx
        /// </summary>
        /// <param name="filename">file path</param>
        /// <param name="hidden">load document invisible Defines if the loaded component is made visible. If this property is not specified, the component is made visible by default.</param>
        /// <returns></returns>
        public bool Load(string filename, bool hidden)
        {
            return Load(filename, hidden, "", "");
        }

        /// <summary>
        /// load docx
        /// </summary>
        /// <param name="filename">file path</param>
        /// <param name="hidden">load document invisible Defines if the loaded component is made visible. If this property is not specified, the component is made visible by default. </param>
        /// <param name="filter_index">internal filter name <see cref="Filters"/> Filters index
        /// Name of a filter that should be used for loading or storing the component.Names must match the names of the TypeDetection configuration, invalid names are ignored.If a name is specified on loading, it still will be verified by a filter detection, but in case of doubt it will be preferred.</param>
        /// <param name="filter_options">additional properties for filter
        /// Some filters need additional parameters; use only together with property MediaDescriptor::FilterName.Details must be documented by the filter. This is an old format for some filters. If a string is not enough, filters can use the property MediaDescriptor::FilterData.</param>
        /// <returns></returns>
        public bool Load(string filename, bool hidden, int filter_index, string filter_options)
        {
            return Load(filename, hidden, filters[filter_index], filter_options);
        }

        /// <summary>
        /// load docx
        /// </summary>
        /// <param name="filename">file path</param>
        /// <param name="hidden">load document invisible Defines if the loaded component is made visible. If this property is not specified, the component is made visible by default.</param>
        /// <param name="filter_name">internal filter name <see cref="Filters"/>
        /// Name of a filter that should be used for loading or storing the component.Names must match the names of the TypeDetection configuration, invalid names are ignored.If a name is specified on loading, it still will be verified by a filter detection, but in case of doubt it will be preferred.</param>
        /// <param name="filter_options"> additional properties for filter
        /// Some filters need additional parameters; use only together with property MediaDescriptor::FilterName.Details must be documented by the filter. This is an old format for some filters. If a string is not enough, filters can use the property MediaDescriptor::FilterData.</param>
        /// <returns></returns>
        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;
            }
        }
        /// <summary>
        ///  a given document xDoc to print to the standard printer without any settings
        /// </summary>
        /// <returns></returns>
        public bool Print()
        {
            return Print("", 1, "");
        }
        /// <summary>
        /// a given document xDoc to print 
        /// </summary>
        /// <param name="printName">string - Specifies the name of the printer queue to be used.</param>
        /// <param name="copies">short - Specifies the number of copies to print.</param>
        /// <param name="pages">string - Specifies the pages to print in the same format as in the print dialog of the GUI (e.g. "1, 3, 4-7, 9-")</param>
        /// <param name="orientation">com.sun.star.view.PaperOrientation. Specifies the orientation of the paper.</param>
        /// <param name="paperFormat">com.sun.star.view.PaperFormat. Specifies a predefined paper size or if the paper size is a user-defined size.</param>
        /// <returns></returns>
        public bool Print(string printName, int copies, string pages, MiniOrientation orientation = MiniOrientation.PORTRAIT, MiniFormat paperFormat = MiniFormat.A4)
        {
            var printerDesc = new List<PropertyValue>();
            if (!string.IsNullOrEmpty(printName))
                printerDesc.Add(new PropertyValue("Name", 0, new uno.Any(typeof(string), printName), PropertyState.DIRECT_VALUE));
            printerDesc.Add(new PropertyValue("PaperOrientation", 0, new uno.Any(typeof(PaperOrientation), orientation), PropertyState.DIRECT_VALUE));
            printerDesc.Add(new PropertyValue("PaperFormat", 0, new uno.Any(typeof(PaperFormat), paperFormat), PropertyState.DIRECT_VALUE));

            var printOpts = new List<PropertyValue>();
            printOpts.Add(new PropertyValue("CopyCount", 0, new uno.Any(copies), PropertyState.DIRECT_VALUE));
            if (!string.IsNullOrEmpty(pages))
                printOpts.Add(new PropertyValue("Pages", 0, new uno.Any(pages), PropertyState.DIRECT_VALUE));
            printOpts.Add(new PropertyValue("Wait", 0, new uno.Any(true), PropertyState.DIRECT_VALUE));
            //if (doc is XPrintable)
            try
            {
                ((XPrintable)doc).setPrinter(printerDesc.ToArray());
                ((XPrintable)doc).print(printOpts.ToArray());
                return true;
            }
            catch { return false; }
        }
        /// <summary>
        /// a given document xDoc to print with custom
        /// </summary>
        /// <param name="printerDesc">
        ///----------- Properties of com.sun.star.view.PrinterDescriptor--------
        ///*** Name string - Specifies the name of the printer queue to be used.
        ///*** PaperOrientation com.sun.star.view.PaperOrientation.Specifies the orientation of the paper.
        ///*** PaperFormat com.sun.star.view.PaperFormat.Specifies a predefined paper size or if the paper size is a user-defined size.
        ///*** PaperSize com.sun.star.awt.Size.Specifies the size of the paper in 1/100 mm.
        ///*** IsBusy boolean - Indicates if the printer is busy.
        ///*** CanSetPaperOrientation boolean - Indicates if the printer allows changes to.PaperOrientation
        ///*** CanSetPaperFormat boolean - Indicates if the printer allows changes to.PaperFormat
        ///*** CanSetPaperSize boolean - Indicates if the printer allows changes to.PaperSize
        /// </param>
        /// <param name="printerDesc">
        ///------------- Properties of com.sun.star.view.PrintOptions--------
        ///CopyCount short - Specifies the number of copies to print.
        ///FileName string - Specifies the name of a file to print to, if set.
        ///Collate boolean - Advises the printer to collate the pages of the copies.If true, a whole document is printed prior to the next copy, otherwise the page copies are completed together.
        ///Pages string - Specifies the pages to print in the same format as in the print dialog of the GUI (e.g. "1, 3, 4-7, 9-")
        ///Wait boolean - Advises that the print job should be performed synchronously, i.e.wait until printing is complete before returning from printing.Otherwise return is immediate and following actions(e.g.closing the corresponding model) may fail until printing is complete.Default is false.
        /// </param>
        /// <param name="pagePrintSettings">
        /// ------------- Properties of com.sun.star.text.PagePrintSettings--------
        /// PageRows short - Number of rows in which document pages should appear on the output page.
        /// PageColumns short - Number of columns in which document pages should appear on the output page.
        /// LeftMargin long - Left margin on the output page.
        /// RightMargin long - Right margin on the output page.
        /// TopMargin long - Top margin on the output page.
        /// BottomMargin long - Bottom margin on the output page.
        /// HoriMargin long - Margin between the columns on the output page.
        /// VertMargin long - Margin between the rows on the output page.
        /// IsLandscape boolean - Determines if the output page is in landscape format.
        /// </param>
        /// <returns></returns>
        public bool Print(List<MiniPropertyValue> printerDesc, List<MiniPropertyValue> printOpts, List<MiniPropertyValue> pagePrintSettings)
        {
            try
            {
                var printSettings = pagePrintSettings.ConvertAll(v => ToPropertyValue(v));
                var desc = printerDesc.ConvertAll(v => ToPropertyValue(v));
                var opts = printOpts.ConvertAll(v => ToPropertyValue(v));
                ((XPagePrintable)doc).setPagePrintSettings(printSettings.ToArray());
                ((XPrintable)doc).setPrinter(desc.ToArray());
                ((XPrintable)doc).print(opts.ToArray());
                return true;
            }
            catch { return false; }
        }
        /// <summary>
        /// save pdf
        /// </summary>
        /// <param name="filename">file path</param>
        /// <param name="filter"><see cref="ExportFilter"/></param>
        /// <returns></returns>
        public bool Save(string filename, ExportFilter filter)
        {
            return Save(filename, FilterToString(filter));
        }
        /// <summary>
        /// save pdf
        /// </summary>
        /// <param name="filename">file path</param>
        /// <param name="filter">
        /// internal filter name <see cref="Filters"/>
        /// Name of a filter that should be used for loading or storing the component.Names must match the names of the TypeDetection configuration, invalid names are ignored.If a name is specified on loading, it still will be verified by a filter detection, but in case of doubt it will be preferred.
        /// </param>
        /// <returns></returns>
        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; }
        }
        /// <summary>
        /// export pdf
        /// </summary>
        /// <param name="filename">file path</param>
        /// <returns></returns>
        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;
        }
        /// <summary>
        /// close XComponent 
        /// doc stream must be not use,otherwise dispose() has no return
        /// </summary>
        public void Close()
        {
            doc.dispose();
            doc = null;
        }
        /// <summary>
        ///  new docx
        /// </summary>
        /// <param name="app"><see cref="AppType"/></param>
        /// <param name="hidden">load document invisible Defines if the loaded component is made visible. If this property is not specified, the component is made visible by default.</param>
        /// <returns></returns>
        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
        /// <summary>
        /// internal filter name
        /// Name of a filter that should be used for loading or storing the component.Names must match the names of the TypeDetection configuration, invalid names are ignored.If a name is specified on loading, it still will be verified by a filter detection, but in case of doubt it will be preferred.
        /// </summary>
        public List<string> Filters
        {
            get { return filters; }
        }
        #endregion

        private PropertyValue ToPropertyValue(MiniPropertyValue miniProperty)
        {
            return new PropertyValue(
                Name: miniProperty.Name,
                Handle: miniProperty.Handle,
                Value: new uno.Any(
                    type: miniProperty.Value.Type,
                    value: miniProperty.Value.Value),
                State: (PropertyState)miniProperty.State);
        }
    }

标签:Word,string,return,filename,filter,file,new,pdf,xp
From: https://blog.csdn.net/u011234288/article/details/145062677

相关文章

  • ai中如何截取PDF文件的一部分
     001、AI打开PDF文件  002、左侧选择矩形工具 003、选择想要剪切的区域 004、回到一般选择图标 005、ctrl+a选中两个图层 006、右键选择简历剪切蒙版 007、剪切完成。 。 ......
  • Java生成Word文档之 XDocReport 和 Poi-tl
    近期参与的多个项目中,均涉及根据预定义模板生成Word文档以供前端下载的需求。以往,我们通常采用将Word文档转换为XML格式,并通过代码赋值变量的方式来实现这一功能。尽管此方法在技术层面可行,但当面对篇幅较长且包含大量变量的文档时,其弊端便显露无遗:代码冗长繁杂,模板维护困难,不利......
  • Download the Vue Devtools extension for a better development experience/浏览器扩
    文章目录一、引言二、下载相关插件三、浏览器加载插件四、运行代码一、引言在做Vue项目的开发时,我们经常需要在页面上调试,若没有安装vue-devtools插件则肯能有以下报错。DownloadtheVueDevtoolsextensionforabetterdevelopmentexperience:https://githu......
  • 网络是怎样连接的PDF免费下载
    适读人群:1.菜鸟程序员入门进阶2.中级程序员查漏补缺3.高手程序员向家人(女友、老妈等)普及计算机知识计算机网络概论图解趣味版,计算机网络基础,程序是怎样跑起来的,计算机是怎样跑起来的姊妹篇,Wireshark网络分析就这么简单作者林沛满作序推荐日文版重印32次。电子版仅供预览,下......
  • ThreeJS入门(217):THREE.DRACOExporter 知识详解,示例代码
    作者:还是大剑师兰特,曾为美国某知名大学计算机专业研究生,现为国内GIS领域高级前端工程师,CSDN知名博主,深耕openlayers、leaflet、mapbox、cesium,webgl,ThreeJS,canvas,echarts等技术开发,欢迎加微信(gis-dajianshi),一起交流。查看本专栏目录-本文是第217篇入门文章......
  • 【YashanDB知识库】kettle做增量同步,出现报错:Unrecognized VM option 'MaxPermSize-25
    本文内容来自YashanDB官网,原文内容请见https://www.yashandb.com/newsinfo/7863039.html?templateId=1718516问题现象kettle在增量同步过程,出现报错:UnrecognizedVMoption'MaxPermSize=256m'问题的风险及影响无法使用kettle做增量同步,导致迁移进度会有所影响问题影响的版......
  • Eval-Expression.NET:动态执行C#脚本,类似Javascript的Eval函数功能
    我们都知道在JavaScript中,我们可以通过Eval来执行JavaScript字符串代码。下面推荐一个.Net版本的Eval的开源项目。01项目简介Eval-Expression.NET是一个非常强大工具,使得开发人员可以动态编译和执行C#代码和表达式。通过C#反射,还能轻松访问公共和私有方法、字段、属性值,并创建......
  • 【专题】2024年直播、短视频:抖音、小红书、快手行业报告汇总PDF合集分享(附原数据表)
    原文链接: https://tecdat.cn/?p=38697在当今数字化飞速发展的时代,直播、短视频行业已然成为了大众生活与商业运作中不容忽视的重要力量,正不断重塑着信息传播与消费的格局。2024年,这一领域更是呈现出多元且复杂的发展态势。从内容创作者生态来看,抖音、小红书、快手等平台各有热......
  • 跟我一起学 Python 数据处理(二十六):PDF 数据提取技巧与问题解决策略
    跟我一起学Python数据处理(二十六):PDF数据提取技巧与问题解决策略在Python数据处理的学习之旅中,我们已经走过了不少路程,今天继续深入探索PDF文件处理的核心技巧与方法,旨在帮助大家进一步提升数据处理能力,解决实际工作中遇到的难题。一、slate库处理PDF文件的深入......
  • 跟我一起学 Python 数据处理(二十五):PDF 文件处理入门与工具抉择
    跟我一起学Python数据处理(二十五):PDF文件处理入门与工具抉择在数据处理的征程中,我们时常会遇到各种格式的数据,而PDF作为一种常见但处理难度较大的格式,掌握其处理方法至关重要。本文旨在与大家共同探索Python处理PDF文件的奥秘,帮助大家提升数据处理技能。一、PDF......