.NET Core 使用 LibreOffice 实现 Office 预览(Docker 部署)

f4d3da559b6c48ca8b2a021153eabb64.jpeg

前些年做云盘产品的时候,一个很核心的功能就是 Office 文件预览,当时还没有使用 .NET Core ,程序部署在 Windows Server 服务器上,文件预览的方案采用了微软的 OWA 。

目前在做的零代码产品中的表单附件控件,同样面临着 Office 文件预览的问题,现在技术栈采用了 .NET Core ,并使用容器化部署,自然就抛弃了 OWA 的方案。

本文简单介绍下 OWA 的替代方案。

思路

1、在表单的附件控件上传 Office 文件后,存储到 MongoDB 中,并发消息给文件转换程序;

2、文件转换程序从 MongoDB 获取 Office 文件,通过 Libreoffice 转换为 PDF 文件;

3、将 PDF 文件存储到 MongoDB 中,并将 PDF 文件在 MongoDB 中的 FileID 存储到平台和原始文件进行关联;

4、在表单中点击文件预览时使用关联的 PDF 的文件 ID 从 MongoDB 中获取 PDF 文件进行展示。

准备

1、创建一个 .NET Core 的控制台程序用来做文件的转换;

2、下载 Libreoffice 安装包、Libreoffice 中文语言包、jdk1.8 安装包 、中文字体包,这些文件我放在云盘了,可以访问这个链接下载:https://pan.baidu.com/s/131lLewbCvGDGLlZzYdSYNA 提取码: 5aas

4f1e088bc382850eb14727df87f1e473.png

3、搭建一台 centos 虚拟机,并准备好 docker 环境;

版本

  • .NET Core:3.1

  • CentOS:7.6

  • Docker:

  • Liberoffice:7.3.5

  • RabbitMQ:3.8.2

  • MongoDB:5.0

开始

编写控制台程序进行文件转换

1、创建一个名为 OfficeToPdf 的 .NET Core 控制台程序,在 Main 方法中对消息队列进行监听;

static void Main(string[] args)  
{  try  {  var mqManager = new MQManager(new MQConfig  {  AutomaticRecoveryEnabled = true,  HeartBeat = 60,  NetworkRecoveryInterval = new TimeSpan(60),  Host = EnvironmentHelper.GetEnvValue("MQHostName"),  UserName = EnvironmentHelper.GetEnvValue("MQUserName"),  Password = EnvironmentHelper.GetEnvValue("MQPassword"),  Port = EnvironmentHelper.GetEnvValue("MQPort")  });        if (mqManager.Connected)  {            _logger.Log(LogLevel.Info, "RabbitMQ连接成功。");  _logger.Log(LogLevel.Info, "RabbitMQ消息接收中...");  mqManager.Subscribe<PowerPointConvertMessage>(Convert);  mqManager.Subscribe<WordConvertMessage>(Convert);  mqManager.Subscribe<ExcelConvertMessage>(Convert);  }        else  {  _logger.Warn("RabbitMQ连接初始化失败,请检查连接。");  Console.ReadLine();  }    }catch(Exception ex)  {        _logger.Error(ex.Message);  }
}

2、在 Convert 方法中对消息进行处理,首先根据消息的中的文件 ID 获取文件:

Stream sourceStream = fileOperation.GetFile(officeMessage.FileInfo.FileId);  
if(sourceStream == null)  
{  logger.Log(LogLevel.Error, $"文件ID:{officeMessage.FileInfo.FileId},不存在");  
}  string filename = officeMessage.FileInfo.FileId;  
string extension = System.IO.Path.GetExtension(officeMessage.FileInfo.FileName);  sourcePath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), filename + extension);  
destPath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), string.Format("{0}.pdf", filename));  logger.Log(LogLevel.Info, $"文件原路径:{sourcePath}");  
logger.Log(LogLevel.Info, $"文件目标路径:{destPath}");  
if (extension != null && (extension.Equals(".xlsx",StringComparison.OrdinalIgnoreCase) ||   extension.Equals(".xls", StringComparison.OrdinalIgnoreCase)))  
{  if (!SetExcelScale(sourceStream, sourcePath))  return false;  
}  
else  
{  byte[] sourceBuffer = new Byte[sourceStream.Length];  sourceStream.Read(sourceBuffer, 0, sourceBuffer.Length);  sourceStream.Seek(0, SeekOrigin.Begin);  if (!SaveToFile(sourceBuffer, sourcePath))  return false;  
}

3、启用 LibreOffice 进行文件转换:

var psi = new ProcessStartInfo(  "libreoffice7.3",  string.Format("--invisible --convert-to pdf  {0}", filename + extension))  {RedirectStandardOutput = true};  // 启动  
var proc = Process.Start(psi);  
if (proc == null)  
{  logger.Error("请检查 LibreOffice 是否成功安装.");  return false;  
}  logger.Log(LogLevel.Info, "文件转换开始......");  
using (var sr = proc.StandardOutput)  
{  while (!sr.EndOfStream)  {        Console.WriteLine(sr.ReadLine());  }    if (!proc.HasExited)  {        proc.Kill();  }}  logger.Log(LogLevel.Info, "文件转成完成");

4、文件转换成功后,存储转换后的 PDF 文件到 MongoDB,然后和原始文件进行关联,下面代码是调用了零代码平台中的接口进行处理,这里可以根据自己的业务需求自行修改 :

string host = EnvironmentHelper.GetEnvValue("ApiHost");  
string api = EnvironmentHelper.GetEnvValue("AssociationApi");  
if (string.IsNullOrEmpty(api))  
{  logger.Warn("请检查 AssociationApi 环境变量的配置");  return false;  
}  
if (string.IsNullOrEmpty(host))  
{  logger.Warn("请检查 ApiHost 环境变量的配置");  return false;  
}  
string result = APIHelper.RunApiGet(host, $"{api}/{fileId}/{destFileId}");

构建 Libreoffice 基础镜像

1、在 centos 服务器上 /data 目录中创建目录 liberoffice-docker-build ,将上面提到的 Libreoffice 安装包、Libreoffice 中文语言包、jdk1.8 安装包 、中文字体包拷贝到该目录中;

2、在该目录中创建 Dockerfile 文件,内容如下:

RUN yum update -y && \yum reinstall -y glibc-common && \yum install -y telnet net-tools && \yum clean all && \rm -rf /tmp/* rm -rf /var/cache/yum/* && \localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8 && \ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime#加入windows字体包
ADD chinese.tar.gz /usr/share/fonts/ADD LibreOffice_7.3.5_Linux_x86-64_rpm.tar.gz /home/
ADD LibreOffice_7.3.5_Linux_x86-64_rpm_langpack_zh-CN.tar.gz /usr/#执行安装
RUN cd /home/LibreOffice_7.3.5.2_Linux_x86-64_rpm/RPMS/ \&& yum localinstall *.rpm -y \&& cd /usr/LibreOffice_7.3.5.2_Linux_x86-64_rpm_langpack_zh-CN/RPMS/   \&& yum localinstall *.rpm -y \#安装依赖&& yum install ibus -y \#加入中文字体支持并赋权限&& cd /usr/share/fonts/ \&& chmod -R 755 /usr/share/fonts \&& yum install mkfontscale -y \&& mkfontscale \&& yum install fontconfig -y \&& mkfontdir \&& fc-cache -fv \&& mkdir /usr/local/java/ \#清理缓存,减少镜像大小&& yum clean all#安装java环境
ADD jdk-8u341-linux-x64.tar.gz /usr/local/java/
RUN ln -s /usr/local/java/jdk1.8.0_314 /usr/local/java/jdk#配置环境变量
ENV JAVA_HOME /usr/local/java/jdk
ENV JRE_HOME ${JAVA_HOME}/jre
ENV CLASSPATH .:${JAVA_HOME}/lib:${JRE_HOME}/lib
ENV PATH ${JAVA_HOME}/bin:$PATH#安装 dotnet core 3.1 运行环境
RUN rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm \&& yum install -y  aspnetcore-runtime-3.1 \&& yum clean allWORKDIR /usr
EXPOSE 80
CMD /bin/bash

3、执行命令 docker build -t libreofficebase:v1.0 . 进行基础镜像的构建,构建好的基础镜像供文件预览镜像构建时使用。

构建文件预览镜像

1、在 centos 服务器的 /data 目录中创建目录 doc-preview-docker-build ;

2、将转换程序 OfficeToPdf 进行编译发布,将发布后的文件拷贝到目录 doc-preview-docker-build 中;

3、在该目录中创建 Dockerfile 文件,内容如下:

FROM libreofficebase:v1 #此处的镜像就是上面构建的 Libreoffice 基础镜像
COPY . /app
WORKDIR /app
EXPOSE 80/tcp
ENTRYPOINT ["dotnet", "OfficeToPdf.dll"]

4、执行命令 docker build -t office-preview:v1.0 . 进行预览镜像的构建。

运行预览容器

执行下面命令进行容器的创建:

docker run -d --name office-preview office-preview

最后

Office 预览肯定有很多种方案,上面只是目前找到的一种可行的方法,如果你有更好的 Office 文件预览方案,欢迎私信告诉我。

点击阅读原文,可以查看示例转换程序。

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

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

相关文章

[开源精品] C#.NET im 聊天通讯架构设计 -- FreeIM 支持集群、职责分明、高性能

&#x1f4bb; FreeIM 是什么&#xff1f;FreeIM 使用 websocket 协议实现简易、高性能&#xff08;单机支持5万连接&#xff09;、集群即时通讯组件&#xff0c;支持点对点通讯、群聊通讯、上线下线事件消息等众多实用性功能。 ImCore 已正式改名为 FreeIM。使用场景&#xff…

用websploit获取管理员后台地址

1, use web/dir_scanner 2, set TARGET http://www.****.com 3, run SOURCE: https://sourceforge.net/projects/websploit/ WebSploit Advanced MITM Framework[]Autopwn – Used From Metasploit For Scan and Exploit Target Service[]wmap – Scan,Crawler Target Used Fro…

《ASP.NET Core 6框架揭秘》实例演示[16]:内存缓存与分布式缓存的使用

.NET提供了两个独立的缓存框架&#xff0c;一个是针对本地内存的缓存&#xff0c;另一个是针对分布式存储的缓存。前者可以在不经过序列化的情况下直接将对象存储在应用程序进程的内存中&#xff0c;后者则需要将对象序列化成字节数组并存储到一个独立的“中心数据库”。对于分…

人工智能教程007:创建一个卷积神经网络(2)

2019独角兽企业重金招聘Python工程师标准>>> 我们如何对图像应用卷积 当我们在图像上应用卷积时&#xff0c;我们在两个维度上执行卷积——水平和竖直方向。我们混合两桶信息&#xff1a;第一桶是输入的图像&#xff0c;由三个矩阵构成——RGB三通道&#xff0c;其中…

【系统知识点】linux入门基础命令

大概总结了一下一些基础命令&#xff0c;仅仅是帮助基础使用linux文件系统&#xff0c;如果还有相关基础命令&#xff0c;希望大家留言一起补充汇总一下&#xff01;命令的基本格式&#xff1a;格式&#xff1a;command [-options] parameter1 parameter2 …ps&#xff1a;第一…

Blazor University (48)依赖注入 —— Scoped 依赖

原文链接&#xff1a;https://blazor-university.com/dependency-injection/dependency-lifetimes-and-scopes/scoped-dependencies/Scoped 依赖Scoped 依赖项类似于 Singleton 依赖项&#xff0c;因为 Blazor 会将相同的实例注入到依赖它的每个对象中&#xff0c;但不同之处在…

c 连接mysql怎么增删改_C++ API方式连接mysql数据库实现增删改查

这里复制的http://www.bitscn.com/pdb/mysql/201407/226252.html一、环境配置1&#xff0c;装好mysql&#xff0c;新建一个C控制台工程(从最简单的弄起&#xff0c;这个会了&#xff0c;可以往任何c工程移植)&#xff0c;在vs2010中设置&#xff0c;工程--属性--VC目录--包含目…

阿里云如何实现海量短视频的极速分发?答案在这里!

摘要&#xff1a;短视频行业目前比较火热&#xff0c;但是如何快速的实现海量短视频的极速分发&#xff0c;对于短视频业务提供方来讲是一个比较棘手的问题。阿里云技术专家将带领大家从视频的上传、采集、存储和CDN分发等方面为我们介绍阿里云的整体方案&#xff0c;并且重点讲…

GitHub项目管理维护实用教程

GitHub项目维护教程 1&#xff09;注册GitHub账户并登陆&#xff1b; 2&#xff09;在Windows cmd&#xff08;或Ubuntu中的terminal&#xff09;中cd到自己的工作目录&#xff0c;将仓库clone下来&#xff1a; 命令&#xff1a; 1 git clone https://github.com/... #项目地址…

图文详解cacti的安装和使用

简介&#xff1a; 1.cacti介绍2.安装服务端3.安装客户端4.添加监控的设备cacti的介绍Cacti是一套基于PHP,MySQL,SNMP及RRDTool开发的网络流量监测图形分析工具Cacti是通过 snmpget来获取数据&#xff0c;使用 RRDtool绘画图形&#xff0c;而且你完全可以不需要了解RRDtool复杂…

记一次 .NET 某金融企业 WPF 程序卡死分析

一&#xff1a;背景 1. 讲故事前段时间遇到了一个难度比较高的 dump&#xff0c;经过几个小时的探索&#xff0c;终于给找出来了&#xff0c;在这里做一下整理&#xff0c;希望对大家有所帮助&#xff0c;对自己也是一个总结&#xff0c;好了&#xff0c;老规矩&#xff0c;上 …

如何将图片放到mysql_怎么将图片添加到mysql中

将图片添加到mysql中的方法&#xff1a;首先将数据库存储图片的字段类型设置为blob二进制大对象类型&#xff1b;然后将图片流转化为二进制&#xff1b;最后将图片插入数据库即可。正常的图片储存要么放进本地磁盘&#xff0c;要么就存进数据库。存入本地很简单&#xff0c;现在…

Java线程与Linux内核线程的映射关系

http://blog.sina.com.cn/s/blog_605f5b4f010198b5.html Linux从内核2.6開始使用NPTL &#xff08;Native POSIX Thread Library&#xff09;支持&#xff0c;但这时线程本质上还轻量级进程。Java里的线程是由JVM来管理的。它怎样相应到操作系统的线程是由JVM的实现来确定的。L…

YoursLC 有源 低代码 项目介绍

YoursLC 是我们独立研发的一款低代码产品&#xff0c;YoursLC-yours你们的、LC是低代码low-code的缩写&#xff0c;中文名称&#xff1a;有源低代码&#xff0c; 是一套双输出的低代码产品&#xff1a;既能完整输出功能又能100%输出源码。满足用户高效率、低成本和个性化的需求…

stm32电机控制定时器1_STM32通过PWM控制电机速度

做STM32智能小车的实验中会用到定时器PWM输出&#xff0c;来改变直流电机的转速。分享本文了解如何通过PWM实现对电机速度的控制。PWM控制电机速度的基本原理PWM(Pulse Width Modulation)&#xff0c;也就是脉冲宽度调制。PWM中有一个比较重要的概念&#xff0c;占空比&#xf…

走向无后端的系统开发实践:CRUD自动化与强约定的REST接口

2019独角兽企业重金招聘Python工程师标准>>> ttp://mp.weixin.qq.com/s?__bizMzAwMDU1MTE1OQ&idx1&mid2653548079&sn2377b625db58b2ea93c3ef2d87e4c395 转载于:https://my.oschina.net/yunjie/blog/806130

mysql char varchar 性能_Mysql小细节:varchar与char在性能上的特点

varchar与char的一个主要区别是存储方式的不同varchar 是变长存储占用的存储空间 存储内容实际大小 长度记录位char 是定长存储占用的存储空间 字段声明的宽度存储方式对性能是有影响的例如分别使用 varchar(10) 与 varchar(255) 定义一个字段&#xff0c;实际存储的字符串为…

Dubbo源码解析之Zookeeper连接

2019独角兽企业重金招聘Python工程师标准>>> 注&#xff1a;Dubbo的版本是2.5.7。 图1 RegistryProtocol的export时序图 注册中心有Zookeeper、Redis、Dubbo&#xff0c;分别对应ZookeeperRegistry、RedisRegistry、MulticastRegistry。 连接Dubbo的客户端有俩种&am…

SHELL 脚本小技巧

脚本很简单&#xff0c;直接上功能介绍及脚本&#xff0c;可以做模板使用&#xff1a; 记录日志,记录脚本开始执行时间、结束时间usage 函数&#xff0c;脚本需接参数执行&#xff0c;避免误执行&#xff0c;告诉用户&#xff0c;这个脚本的使用方法加锁&#xff0c;创建锁文件…

WinForm(十)项目框架结构

看到下面的项目结构&#xff0c;是否曾经相识&#xff1f;不要笑&#xff0c;这也是一种项目结构&#xff0c;极简主义。项目结构没有对错&#xff0c;合适就好&#xff0c;但也要有几个要求&#xff0c;至少要做到结构明确&#xff0c;清晰&#xff0c;当然上图的结构清晰&…