Office转PDF,Aspose太贵,怎么办?

640?wx_fmt=jpeg

在程序开发中经常需要将Office文件转换成PDF,著名的Aspose的三大组件可以很容易完成这个功能,但是Aspose的每个组件都单独收费,而且每个都卖的不便宜。在老大的提示下,换了一种思路来解决这个问题。

环境

dotNetCore:2.1
CentOS:7.5
Docker:18.06.1-ce

步骤

1、Docker中安装libreofficedotNetCore
2、编写转换程序;
3、程序以服务的方式部署在Docker中。

配置Docker环境

因为需要部署dotNetCore的程序,开始的想法是依赖microsoft/dotnet:2.1-aspnetcore-runtime镜像创建容器,然后在容器中安装libreoffice,后来发现容器中没法执行yum命令(可能是没找到方法)。最后换了一种思路,依赖centos镜像创建容器,在容器中安装dotNetCore2.1libreoffice

安装`libreofiicie`

yum install libreoffice 

安装`dotnetCore2.1`

sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpmsudo yum updatesudo yum install aspnetcore-runtime-2.1
sudo yum update
sudo yum install aspnetcore-runtime-2.1

转换程序编写

C#中使用libreoffice转换officepdf,网上有很多的代码示例,在这里还需要引入消息队列,整个程序是一个消息队列的消费者。简单说就是,用户上传了一个office文件,上传成功后会发一个消息,该程序中接收到消息就进行转换。

消息监听

    class Program    {        static IPowerPointConverter converter = new PowerPointConverter();        static void Main(string[] args)        {            var mqManager = new MQManager(new MqConfig            {                AutomaticRecoveryEnabled = true,                HeartBeat = 60,                NetworkRecoveryInterval = new TimeSpan(60),                Host = ConfigurationManager.AppSettings["mqhostname"],                 UserName = ConfigurationManager.AppSettings["mqusername"],                Password = ConfigurationManager.AppSettings["mqpassword"],                Port = ConfigurationManager.AppSettings["mqport"]            });            if (mqManager != null && mqManager.Connected)            {                Console.WriteLine("RabbitMQ连接初始化成功。");                Console.WriteLine("RabbitMQ消息接收中...");                mqManager.Subscribe<PowerPointConvertMessage>(message =>                {                    if (message != null)                    {                        converter.OnWork(message);                        Console.WriteLine(message.FileInfo);                    }                });            }            else            {                Console.WriteLine("RabbitMQ连接初始化失败,请检查连接。");                Console.ReadLine();            }        }    }Program
    {
        static IPowerPointConverter converter = new PowerPointConverter();

        static void Main(string[] args)
        
{

            var mqManager = new MQManager(new MqConfig
            {
                AutomaticRecoveryEnabled = true,
                HeartBeat = 60,
                NetworkRecoveryInterval = new TimeSpan(60),

                Host = ConfigurationManager.AppSettings["mqhostname"], 
                UserName = ConfigurationManager.AppSettings["mqusername"],
                Password = ConfigurationManager.AppSettings["mqpassword"],
                Port = ConfigurationManager.AppSettings["mqport"]
            });


            if (mqManager != null && mqManager.Connected)
            {
                Console.WriteLine("RabbitMQ连接初始化成功。");
                Console.WriteLine("RabbitMQ消息接收中...");

                mqManager.Subscribe<PowerPointConvertMessage>(message =>
                {
                    if (message != null)
                    {
                        converter.OnWork(message);
                        Console.WriteLine(message.FileInfo);
                    }
                });
            }
            else
            {
                Console.WriteLine("RabbitMQ连接初始化失败,请检查连接。");
                Console.ReadLine();
            }
        }
    }

文件转换

        public bool OnWork(MQ.Messages Message)        {            PowerPointConvertMessage message = (PowerPointConvertMessage)Message;            string sourcePath = string.Empty;            string destPath = string.Empty;            try            {                if(message == null)                    return false;                Stream sourceStream = fileOperation.GetFile(message.FileInfo.FileId);                string filename = message.FileInfo.FileId;                string extension = System.IO.Path.GetExtension(message.FileInfo.FileName);                sourcePath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), filename + extension);                destPath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), string.Format("{0}.pdf", filename));                if (!SaveToFile(sourceStream, sourcePath))                    return false;                var psi = new ProcessStartInfo("libreoffice", string.Format("--invisible --convert-to pdf  {0}", filename + extension)) { RedirectStandardOutput = true };                // 启动                var proc = Process.Start(psi);                if (proc == null)                {                    Console.WriteLine("不能执行.");                    return false;                }                else                {                    Console.WriteLine("-------------开始执行--------------");                    //开始读取                    using (var sr = proc.StandardOutput)                    {                        while (!sr.EndOfStream)                        {                            Console.WriteLine(sr.ReadLine());                        }                        if (!proc.HasExited)                        {                            proc.Kill();                        }                    }                    Console.WriteLine("---------------执行完成------------------");                    Console.WriteLine($"退出代码 : {proc.ExitCode}");                }            }            catch (Exception ex)            {                Console.WriteLine(ex.Message);                return false;            }            finally            {                if (File.Exists(destPath))                {                    var destFileInfo = UploadFile(destPath, string.Format("{0}.pdf", Path.GetFileNameWithoutExtension(message.FileInfo.FileName)));                }                if (File.Exists(destPath))                {                    System.IO.File.Delete(destPath);                }            }            return true;        }
            PowerPointConvertMessage message = (PowerPointConvertMessage)Message;
            string sourcePath = string.Empty;
            string destPath = string.Empty;
            try
            {
                if(message == null)
                    return false;
                Stream sourceStream = fileOperation.GetFile(message.FileInfo.FileId);
                string filename = message.FileInfo.FileId;
                string extension = System.IO.Path.GetExtension(message.FileInfo.FileName);
                sourcePath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), filename + extension);
                destPath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), string.Format("{0}.pdf", filename));

                if (!SaveToFile(sourceStream, sourcePath))
                    return false;
                var psi = new ProcessStartInfo("libreoffice"string.Format("--invisible --convert-to pdf  {0}", filename + extension)) { RedirectStandardOutput = true };
                // 启动
                var proc = Process.Start(psi);
                if (proc == null)
                {
                    Console.WriteLine("不能执行.");
                    return false;
                }
                else
                {
                    Console.WriteLine("-------------开始执行--------------");
                    //开始读取
                    using (var sr = proc.StandardOutput)
                    {
                        while (!sr.EndOfStream)
                        {
                            Console.WriteLine(sr.ReadLine());
                        }
                        if (!proc.HasExited)
                        {
                            proc.Kill();
                        }
                    }
                    Console.WriteLine("---------------执行完成------------------");
                    Console.WriteLine($"退出代码 : {proc.ExitCode}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
            finally
            {
                if (File.Exists(destPath))
                {
                    var destFileInfo = UploadFile(destPath, string.Format("{0}.pdf", Path.GetFileNameWithoutExtension(message.FileInfo.FileName)));
                }
                if (File.Exists(destPath))
                {
                    System.IO.File.Delete(destPath);
                }
            }
            return true;
        }

上面只是一些代码片段,完整示例会上传到Github上,文章末尾会给出地址。

部署代码到Docker

此程序是dotNetCore编写的控制台程序,希望以服务的方式在后台运行,下面介绍怎样将控制台程序以服务的方式运行:

1、将发布后的代码放在容器的/root/officetopdf/publish目录中
2、在 /lib/systemd/system目录中创建文件officetopdf.service
3、文件内容如下:

[Unit]Description=office to pdf service[Service]ExecStart=/usr/bin/dotnet /root/officetopdf/publish/Office2PDF.dll[Install]WantedBy=default.target
Description=office to pdf service

[Service]

ExecStart=/usr/bin/dotnet /root/officetopdf/publish/Office2PDF.dll

[Install]

WantedBy=default.target

4、使用下面命令创建和启动服务;

systemctrl daemon-reloadsystemctrl start officetopdf
systemctrl start officetopdf

示例

https://github.com/oec2003/StudySamples/tree/master/Office2PDF


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

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

相关文章

收起.NET程序的dll来

作为上床后需要下床检查好几次门关了没有的资深强迫症患者&#xff0c;有一个及其搞我的问题&#xff0c;就是dll问题。曾几何时&#xff0c;在没有nuget的年代&#xff0c;当有依赖项需要引用的时候&#xff0c;只能通过文件引用来管理引用问题&#xff0c;版本问题&#xff0…

从壹开始 [ Ids4实战 ] 之三║ 详解授权持久化 用户数据迁移

哈喽大家周三好&#xff0c;今天终于又重新开启 IdentityServer4 的落地教程了&#xff0c;不多说&#xff0c;既然开始了&#xff0c;就要努力做好?。书接上文&#xff0c;在很久之前的上篇文章《二║ 基础知识集合 & 项目搭建一》中&#xff0c;我们简单的说了说 Identi…

微软XAML Studio - WPF, UWP, Xamarin等技术开发者的福音

最近在继续倒腾WPF的项目&#xff0c;继续使用Caliburn.Micro和Xceed来堆代码。每次调试xaml上的binding&#xff0c;都有种要疯的赶脚。今天路过 https://channel9.msdn.com/ 浏览 WPF相关的学习视频时&#xff0c;遇到微软推荐的相关视频 - XAML sutdio简介https://channel9.…

AddMvc 和 AddMvcCore 的区别

目录本文出自《从零开始学 ASP.NET CORE MVC》目录 视频课程效果更佳&#xff1a;从零开始学 Asp.Net Core MVC ASP.NET Core 为什么有 AddMvc 和 AddMvcCore 他们是什么关系&#xff1f;在本视频中&#xff0c;我们将讨论 AddMvc()和 AddMvcCore()方法之间的区别。要在 ASP.NE…

浅谈容量规划

俗话说&#xff0c;”人无远虑&#xff0c;必有近忧”&#xff0c;容量规划就是”远虑”。所谓容量规划&#xff0c;是一个产品满足用户目标需求而决定生产能力的过程。当产品发展到一个较为稳定成熟的阶段&#xff0c;产品的整体处理能力的把控自然是不可或缺&#xff0c;尽管…

CF1063C Dwarves, Hats and Extrasensory Abilities

CF1063C Dwarves, Hats and Extrasensory Abilities 题意&#xff1a; 首先题目会给出 n &#xff0c;表示要输入多少点。 然后你输出n 个点的坐标&#xff0c;每输出一个点会告诉你这个点的颜色是黑色或者白色。 最后你需要输出两个点的坐标代表一条直线&#xff0c;这条直线…

Blazor——Asp.net core的新前端框架

Blazor是微软在Asp.net core 3.0中推出的一个前端MVVM模型&#xff0c;它可以利用Razor页面引擎和C#作为脚本语言来构建WEB页面&#xff0c;如下代码简单演示了它的基本功能&#xff1a;和Angular JS和VUE的模型非常类似&#xff0c;Blazor 支持大多数应用所需的核心方案&#…

CF1149B Three Religions

CF1149B Three Religions 题意&#xff1a; 给定长度为 n 的母串和三个子串s1,s2,s3s_1,s_2,s_3s1​,s2​,s3​ 。初始时子串均为空。有 q 次询问。你需要支持两种操作&#xff1a;向某个子串末尾添加一个字母&#xff0c;或者删去某个子串末尾的字母。在每次操作后&#xff…

【译文】领域模型的五个特征

我在这篇博客文章中&#xff0c;我试图给领域模型下一个非常合适的定义&#xff0c;我发现我的这些定义都不太妥当&#xff0c;不过&#xff0c;我们还是可以先来看一下wiki百科对领域驱动模型下的定义&#xff1a;问题解决和软件工程中的领域模型可以被认为是感兴趣的领域&…

使用ASP.NET Core 实现Docker的HealthCheck指令

写在前面HealthCheck 不仅是对应用程序内运行情况、数据流通情况进行检查&#xff0c; 还包括应用程序对外部服务或依赖资源的健康检查。健康检查通常是以暴露应用程序的HTTP端点的形式 实施&#xff0c;可用于配置健康探测的的场景有 &#xff1a;容器或负载均衡器 探测应用状…

VS Code 中有哪些好用的 Azure 插件?

在之前的文章中&#xff0c;我们提到了 Amazon、Google、IBM、Red Hat、Salesforce、Pivotal 等大厂都在 VS Code 中有提供相应的开发工具&#xff1a;亚马逊上了 VS Code 的船&#xff0c;还有哪些大厂也上了船&#xff1f;微软必定更是把 VS Code 作为其最重要的开发者平台了…

邀请 | 关于微软容器服务,你需要知道的二三事

容器是近年来特别火的话题&#xff0c;那么&#xff0c;什么是容器&#xff1f;为什么我们需要容器服务&#xff1f;微软容器服务特点是什么&#xff1f;今天我们用一种特殊的方式为大家介绍这三大话题。什么是容器这个部分&#xff0c;我们用一个故事进行开场。很久以前&#…

UWP 推荐 | 限时免费的RSS阅读器《RSS 追踪》登录 Windows 10

前不久&#xff0c;本公号作者 Bravo Yeung 写了一篇不错的关于 RSS 的文章 .Net开发者必知的技术类RSS订阅指南。RSS 现在用的人很少了&#xff0c;而且就算是我&#xff0c;也不过是在一周前才开始正视 RSS 。只因为接触到了一个很好很强大的社区 RSS Hub &#xff0c;当时看…

常见跨域解决方案以及Ocelot 跨域配置

常见跨域解决方案以及Ocelot 跨域配置Intro我们在使用前后端分离的模式进行开发的时候&#xff0c;如果前端项目和api项目不是一个域名下往往会有跨域问题。今天来介绍一下我们在Ocelot网关配置的跨域。什么是跨域跨域:浏览器对于javascript的同源策略的限制,例如a.cn下面的js不…

解读大内老A的《.NET Core框架本质》

老A说的一句话让我很受启发&#xff0c;想要深入了解框架&#xff0c;你要把精力聚焦在架构设计的层面来思考问题。而透彻了解底层原理&#xff0c;最好的笨办法就是根据原理对框架核心进行重建或者说再造。看起来没有捷径&#xff0c;也是最快的捷径。相信很多读者已经看过老A…

Mono和.NET Core 从比翼双飞到合体

.NET 开源之路就是 Mono和.NET Core 从比翼双飞到合体&#xff1a;2001年12月-2002年2月。一个新的平台诞生了。与惠普、英特尔和其他公司一起, 创建了 ECMA-335 标准, 该标准定义了支持多种编程语言的公共语言基础结构&#xff0c;C# 和 Visual Basic. Net。 F # 于2007年晚些…

Skywalking部署常见问题以及注意事项

Skywalking部署常见问题以及注意事项IntroSkyWalking 创建与2015年&#xff0c;提供分布式追踪功能。从5.x开始&#xff0c;项目进化为一个完成功能的Application Performance Management系统。他被用于追踪、监控和诊断分布式系统&#xff0c;特别是使用微服务架构&#xff0c…

GitHub推出包管理服务,npm与Nuget全支持

GitHub 今天推出了一项名为 GitHub Package Registry 的新产品&#xff0c;它提供了软件包管理服务&#xff0c;开发者通过它可发布公共或私有软件包。官方介绍&#xff0c;GitHub Package Registry 完全集成在 GitHub 中&#xff0c;因此和 repo 一样&#xff0c;用户可以使用…

发布dotNetCore程序到Kubernetes

上一篇《Mac中搭建Kubernetes》介绍了怎样在Mac中搭建单节点的Kubernetes&#xff0c;本文将编写一个dotNetCore的示例程序&#xff0c;并发布到Kubernetes中。环境基本步骤创建dotnetCore示例项目&#xff1b;本地搭建私有registry&#xff0c;或者使用DockerHub&#xff0c;本…

[Cake] 2. dotnet 全局工具 cake

在上篇博客[Cake] 1. CI中的Cake中介绍了如何在CI中利用Cake来保持与CI/CD环境的解耦。当时dotnet 2.1还未正式发布&#xff0c;dotnet 还没有工具的支持&#xff0c;使得安装cake非常麻烦。不过随着 dotnet tool 的加入&#xff0c;这一问题得到了很好的解决。目前安装cake&am…