Word 转成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 streamsprocess.OutputDataReceived += (sender, args) => Console.WriteLine("OUT: " + args.Data);process.ErrorDataReceived += (sender, args) => Console.WriteLine("ERR: " + args.Data);process.Start();// Start reading the output asynchronouslyprocess.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 ConstructorsWordPrint(){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 managerservice = (XMultiServiceFactory)context.getServiceManager();/// Create a new Desktop instance using our service managercomponent = (XComponentLoader)service.createInstance("com.sun.star.frame.Desktop");// Getting filtersXNameContainer 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 methodsprivate 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; }}#endregionprivate 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);}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/505784.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Springboot+Vue的仓库管理系统

开发一个基于Spring Boot和Vue的仓库管理系统涉及到前端和后端的开发。本文呢&#xff0c;给出一个简单的开发步骤指南&#xff0c;用于指导初入的新手小白如何开始构建这样一个系统&#xff0c;如果**你想直接学习全部内容&#xff0c;可以直接拉到文末哦。** 开始之前呢给小…

快速导入请求到postman

1.确定请求&#xff0c;右键复制为cURL(bash) 2.postman菜单栏Import-Raw text&#xff0c;粘贴复制的内容保存&#xff0c;请求添加成功

预训练语言模型——BERT

1.预训练思想 有了预训练就相当于模型在培养大学生做任务&#xff0c;不然模型初始化再做任务就像培养小学生 当前数据层面的瓶颈是能用于预训练的语料快被用完了 现在有一个重要方向是让机器自己来生成数据并做微调 1.1 预训练&#xff08;Pre - training&#xff09;vs. 传…

数字孪生电网有什么作用?实时云渲染技术又如何赋能智慧电网?

电网系统的结构比较复杂&#xff0c;传统运维模式主要是依赖传感器和人工巡检&#xff0c;难以全面监测管理。而数字孪生技术的应用将推动电网智能化、绿色化的高效转型。 智慧电网利用物理模型、现场测量数据和历史数据&#xff0c;结合云计算、物联网、大数据等技术&#xf…

MiniMind - 从0训练语言模型

文章目录 一、关于 MiniMind &#x1f4cc;项目包含 二、&#x1f4cc; Environment三、&#x1f4cc; Quick Start Test四、&#x1f4cc; Quick Start Train0、克隆项目代码1、环境安装2、如果你需要自己训练3、测试模型推理效果 五、&#x1f4cc; Data sources1、分词器&am…

EasyCVR视频汇聚平台如何配置webrtc播放地址?

EasyCVR安防监控视频系统采用先进的网络传输技术&#xff0c;支持高清视频的接入和传输&#xff0c;能够满足大规模、高并发的远程监控需求。平台支持多协议接入&#xff0c;能将接入到视频流转码为多格式进行分发&#xff0c;包括RTMP、RTSP、HTTP-FLV、WebSocket-FLV、HLS、W…

【GlobalMapper精品教程】093:将tif影像色彩映射表(调色板)转为RGB全彩模式

参考阅读:【ArcGIS微课1000例】0137:色彩映射表转为RGB全彩模式 文章目录 一、Globalmapper中显示模式二、ArcGIS中显示模式三、调色板转为RGB全彩模式四、注意事项一、Globalmapper中显示模式 Globalmapper中,将谷歌等多种来源在线影像下载到本地后,可能会遇到以下数据格…

Postman接口测试05|实战项目笔记

目录 一、项目接口概况 二、单接口测试-登录接口&#xff1a;POST 1、正例 2、反例 ①姓名未注册 ②密码错误 ③姓名为空 ④多参 ⑤少参 ⑥无参 三、批量运行测试用例 四、生成测试报告 1、Postman界面生成 2、Newman命令行生成 五、token鉴权&#xff08;“…

【css】浏览器强制设置元素状态(hover|focus……)

直接上步骤&#xff1a; 打开浏览器控制台 → 找到样式选项 → 找到:hov选项 → 点击:hov选项&#xff0c;会展开【设置元素状态】。 只要选中就会展示出自己写在css里面的该种状态下的样式了。

Springboot——钉钉(站内)实现登录第三方应用

文章目录 前言准备1、创建钉钉应用&#xff0c;并开放网页应用2、配置网页应用各项参数发布版本 前端改造后端逻辑1、获取应用免登录 Access_token2、通过免登录 Access_token 和 Auth_Code 获取对应登录人信息 注意事项 前言 PC端的钉钉中工作台&#xff0c;增加第三方应用&a…

完美解决VMware 17.0 Pro安装ubuntu、Deepin等虚拟机后卡顿、卡死问题

这两天在 VM 17 Pro 中安装了ubuntu 24.1 和Deepin 23.9 等Linux操作系统&#xff0c;在使用过程中出现过数次卡顿、卡死问题&#xff0c;现记录整理解决方法如下&#xff1a; 一、问题描述 安装虚拟机时、以及安装完成后正常使用时出现鼠标点击卡顿、系统反应慢、卡死等问题…

计算机的错误计算(二百零七)

摘要 利用两个数学大模型计算 arccot(0.125664e2)的值&#xff0c;结果保留16位有效数字。 实验表明&#xff0c;它们的输出中分别仅含有3位和1位正确数字。 例1. 计算 arccot(0.125664e2)的值&#xff0c;结果保留16位有效数字。 下面是与一个数学解题器的对话。 以上为与…

Linux内核TTY子系统有什么(6)

接前一篇文章&#xff1a;Linux内核TTY子系统有什么&#xff08;5&#xff09; 本文内容参考&#xff1a; Linux TTY子系统框架-CSDN博客 一文彻底讲清Linux tty子系统架构及编程实例-CSDN博客 linux TTY子系统(3) - tty driver_sys tty device driver-CSDN博客 Linux TTY …

03_Redis基本操作

1.Redis查询命令 1.1 官网命查询命令 为了便于学习Redis,官方将其用于操作不同数据类型的命令进行了分类整理。你可以通过访问Redis官方网站上的命令参考页面https://redis.io/commands来查阅这些分组的命令,这有助于更系统地理解和使用Redis的各项功能。 1.2 HELP查询命令…

@LocalBuilder装饰器: 维持组件父子关系

一、前言 当开发者使用Builder做引用数据传递时&#xff0c;会考虑组件的父子关系&#xff0c;使用了bind(this)之后&#xff0c;组件的父子关系和状态管理的父子关系并不一致。为了解决组件的父子关系和状态管理的父子关系保持一致的问题&#xff0c;引入LocalBuilder装饰器。…

kubernetes第七天

1.影响pod调度的因素 nodeName 节点名 resources 资源限制 hostNetwork 宿主机网络 污点 污点容忍 Pod亲和性 Pod反亲和性 节点亲和性 2.污点 通常是作用于worker节点上&#xff0c;其可以影响pod的调度 语法&#xff1a;key[value]:effect effect:[ɪˈfek…

FFmpeg Muxer HLS

使用FFmpeg命令来研究它对HLS协议的支持程度是最好的方法&#xff1a; ffmpeg -h muxerhls Muxer HLS Muxer hls [Apple HTTP Live Streaming]:Common extensions: m3u8.Default video codec: h264.Default audio codec: aac.Default subtitle codec: webvtt. 这里面告诉我…

maven高级(day15)

Maven 是一款构建和管理 Java 项目的工具 分模块设计与开发 所谓分模块设计&#xff0c;顾名思义指的就是我们在设计一个 Java 项目的时候&#xff0c;将一个 Java 项目拆分成多 个模块进行开发。 分模块设计我们在进行项目设计阶段&#xff0c;就可以将一个大的项目拆分成若干…

【json】

JSON JSON是一种轻量级的,按照指定的格式去组织和封装数据的数据交互格式。 本质上是一个带有特定格式的字符串(py打印json时认定为str类型) 在各个编程语言中流通的数据格式&#xff0c;负责不同编程语言中的数据传递和交互,类似于计算机普通话 python与json关系及相互转换…

计算机网络 笔记 数据链路层 2

1,信道划分&#xff1a; (1)时分复用TDM 将时间等分为“TDM帧”&#xff0c;每个TDM帧内部等分为m个时隙&#xff0c;m个用户对应m个时隙 缺点&#xff1a;每个节点只分到了总带宽的1/m,如果有部分的1节点不发出数据&#xff0c;那么就会在这个时间信道被闲置&#xff0c;利用…