当前位置: 首页 > 科技观察

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

时间:2023-03-13 01:50:40 科技观察

前几年做云盘产品的时候,一个很核心的功能就是Office文件预览。当时没有使用.NETCore,程序部署在WindowsServer上,文件预览程序使用微软的OWA。目前零代码产品中的表单附件控件也面临Office文件预览的问题。既然技术栈采用了.NETCore,使用容器化部署,那么OWA方案自然也就放弃了。本文简要介绍了OWA的替代方案。思路是在表单的附件控件中上传Office文件,存储在MongoDB中,发送消息给文件转换程序。文件转换器程序从MongoDB获取Office文件,并通过Libreoffice将它们转换为PDF文件。将PDF文件存储在MongoDB中,将PDF文件在MongoDB中的FileID存储到平台与原文件进行关联。使用关联的PDF文件ID从MongoDB中获取PDF文件,以便在单击表单中的文件预览时显示。准备工作1.创建一个用于文件转换的.NETCore控制台程序。2、下载Libreoffice安装包、Libreoffice中文语言包、jdk1.8安装包、中文字体包。3.搭建centos虚拟机,准备docker环境。Version.NETCore:3.1CentOS:7.6Docker:Liberoffice:7.3.5RabbitMQ:3.8.2MongoDB:5.0开始写一个文件转换的控制台程序1.创建一个名为OfficeToPdf的.NETCore控制台程序,在Main方法中消息队列为监控。staticvoidMain(string[]args){try{varmqManager=newMQManager(newMQConfig{AutomaticRecoveryEnabled=true,HeartBeat=60,NetworkRecoveryInterval=newTimeSpan(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(转换);mqManager.Subscribe(转换);mqManager.Subscribe(转换);}else{_logger.Warn("RabbitMQ连接初始化失败,请检查连接。");Console.ReadLine();}}catch(Exceptionex){_logger.Error(ex.Message);}}2.Convert方法中处理消息,首先根据消息:流sourceStream=fileOperation.GetFile(officeMessage.FileInfo.FileId);if(sourceStream==null){logger.Log(LogLevel.Error,$"文件ID:{officeMessage.FileInfo.FileId},不存在");}stringfilename=officeMessage.FileInfo.FileId;stringextension=System.IO.Path.GetExtension(officeMessage.FileInfo.FileName);sourcePath=System.IO.Path.Combine(Directory.GetCurrentDirectory(),文件名+扩展名);destPath=System.IO.Path.Combine(Directory.GetCurrentDirectory(),string.Format("{0}.pdf",filename));logger.Log(LogLevel.Info,$"文件原路径:{sourcePath}");logger.Log(LogLevel.Info,$"Filedestinationpath:{destPath}");if(extension!=null&&(extension.Equals(".xlsx",StringComparison.OrdinalIgnoreCase)||扩展。等于(“.xls”,StringComparison.OrdinalIgnoreCase))){如果(!SetExcelScale(sourceStream,sourcePath))返回false;}else{byte[]sourceBuffer=newByte[sourceStream.Length];sourceStream.Read(sourceBuffer,0,sourceBuffer.Length);源流。寻求(0,SeekOrigin.Begin);如果(!SaveToFile(sourceBuffer,sourcePath))返回false;}3。启用LibreOffice进行文件转换:varpsi=newProcessStartInfo("libreoffice7.3",string.Format("--invisible--convert-topdf{0}",filename+extension)){RedirectStandardOutput=true};//开始varproc=Process.Start(psi);if(proc==null){logger.Error("请检查LibreOffice是否安装成功。");返回假;}logger.Log(LogLevel.Info,"文件转换开始...");使用(varsr=proc.StandardOutput){while(!sr.EndOfStream){Console.WriteLine(sr.ReadLine());}if(!proc.HasExited){proc.Kill();}}logger.Log(LogLevel.Info,"文件转换完成");4.文件转换成功最后将转换后的PDF文件存入MongoDB中,再与原文件进行关联。以下代码调用零代码平台中的接口进行处理。这里可以根据业务需要修改:stringhost=EnvironmentHelper.GetEnvValue("ApiHost");stringapi=EnvironmentHelper.GetEnvValue("AssociationApi");if(string.IsNullOrEmpty(api)){logger.Warn("请检查AssociationApi环境变量的配置");返回假;}if(string.IsNullOrEmpty(host)){logger.Warn("请检查ApiHost环境变量的配置");返回假;}stringresult=APIHelper.RunApiGet(host,$"{api}/{fileId}/{destFileId}");搭建Libreoffice基础镜像1、在centos服务器/data目录下创建目录liberoffice-docker-build,将上述Libreoffice安装包、Libreoffice中文语言包、jdk1.8安装包、中文字体包复制到这个目录2.在这个目录下创建一个Dockerfile,内容如下:RUNyumupdate-y&&\yumreinstall-yglibc-common&&\yuminstall-ytelnetnet-tools&&\yumcleanall&&\rm-rf/tmp/*rm-rf/var/cache/yum/*&&\localedef-c-fUTF-8-izh_CNzh_CN.UTF-8&&\ln-sf/usr/share/zoneinfo/Asia/Shanghai/etc/localtime#添加windows字体包ADDchinese.tar.gz/usr/share/fonts/ADDLibreOffice_7.3.5_Linux_x86-64_rpm.tar.gz/home/ADDLibreOffice_7.3.5_Linux_x86-64_rpm_langpack_zh-CN.tar.gz/usr/#execute安装RUNcd/home/LibreOffice_7.3.5.2_Linux_x86-64_rpm/RPMS/\&ÿocalinstall*.rpm-y\&&cd/usr/LibreOffice_7.3.5.2_Linux_x86-64_rpm_langpack_zh-CN/RPMS/\&ÿocalinstall*.rpm-y\#安装依赖&&yuminstallibus-y\#添加中文字体支持并授予权限&&cd/usr/share/fonts/\&&chmod-R755/usr/share/fonts\&&yuminstallmkfontscale-y\&&mkfontscale\&&yuminstallfontconfig-y\&&mkfontdir\&&fc-cache-fv\&&mkdir/usr/local/java/\#清理缓存,减小图像大小&&yumcleanall#Installjava环境ADDjdk-8u341-linux-x64.tar.gz/usr/local/java/RUNln-s/usr/local/java/jdk1.8.0_314/usr/local/java/jdk#配置环境变量ENVJAVA_HOME/usr/local/java/jdkENVJRE_HOME${JAVA_HOME}/jreENVCLASSPATH.:${JAVA_HOME}/lib:${JRE_HOME}/libENVPATH${JAVA_HOME}/bin:$PATH#安装dotnetcore3.1运行环境RUNrpm-Uvhhttps://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm\&&yuminstall-yaspnetcore-runtime-3.1\&&yumcleanallWORKDIR/usrEXPOSE80CMD/bin/bash3,执行命令dockerbuild-tlibreofficebase:v1.0。构建基础镜像,构建的基础镜像用于构建文件预览镜像时的文件预览镜像构建1.在centosserver-build的/data目录下创建目录doc-preview-docker。2.编译发布转换程序OfficeToPdf,将发布的文件复制到doc-preview-docker-build目录下。3.在该目录下创建一个Dockerfile,内容如下:FROMlibreofficebase:v1#这里的镜像是上面COPY构建的Libreoffice的基础镜像。/appWORKDIR/appEXPOSE80/tcpENTRYPOINT["dotnet","OfficeToPdf.dll"]4,执行命令dockerbuild-toffice-preview:v1.0构建预览图。运行预览容器执行以下命令创建容器:dockerrun-d--nameoffice-previewoffice-preview最后,Officepreview的选择肯定有很多,以上只是目前找到的一种可行的方法。